Coder Social home page Coder Social logo

miscreant / meta Goto Github PK

View Code? Open in Web Editor NEW
473.0 19.0 27.0 692 KB

Meta-repository for Miscreant: misuse-resistant symmetric encryption library with AES-SIV (RFC 5297) and AES-PMAC-SIV support

Home Page: https://miscreant.io

License: Other

aes siv cryptography security nonce-misuse-attacks aead key-wrapping streaming-encryption

meta's Introduction

miscreant.

MIT Licensed Gitter Chat

The best crypto you've never heard of, brought to you by Phil Rogaway

A misuse resistant symmetric encryption library designed to support authenticated encryption of individual messages, encryption keys, message streams, or large files using the AES-SIV (RFC 5297), AES-PMAC-SIV, and STREAM constructions.

Miscreant is available for several programming languages, including C#, Go, JavaScript, Python, Ruby, and Rust.

What is Miscreant?

Miscreant is a set of interoperable libraries implemented in several languages providing a high-level API for misuse-resistant symmetric encryption. Additionally, it provides support for "online" [authenticated encryption] use cases such as streaming or incrementally encryption/decryption of large files.

The following algorithms are provided by Miscreant:

  • AES-SIV: an authenticated mode of AES which provides nonce reuse misuse resistance. Described in RFC 5297, it combines the AES-CTR (NIST SP 800-38A) mode of encryption with the AES-CMAC(NIST SP 800-38B) function for integrity.

  • AES-PMAC-SIV: a fully parallelizable variant of AES-SIV which substitutes the AES-PMAC function for integrity, providing effectively identical security properties as the original construction, but much better performance on systems which provide parallel hardware implementations of AES, namely Intel/AMD CPUs.

  • STREAM: a construction which, when combined with AES-SIV or AES-PMAC-SIV, provides online/streaming authenticated encryption and defends against reordering and truncation attacks.

Cipher Comparison

Miscreant Ciphers

Name Authenticated Misuse Resistance x86 Speed IoT Speedโ€  Standardization
AES-SIV ๐Ÿ’š ๐Ÿ’š ๐Ÿ’› ๐Ÿ’š RFC 5297
AES-PMAC-SIV ๐Ÿ’š ๐Ÿ’š ๐Ÿ’š ๐Ÿ’š None

Other Constructions

Name Authenticated Misuse Resistance x86 Speed IoT Speedโ€  Standardization
AES-GCM-SIV ๐Ÿ’š ๐Ÿ’š ๐Ÿ’– ๐Ÿ’” Forthcomingโ€ก
AES-GCM ๐Ÿ’š ๐Ÿ’” ๐Ÿ’– ๐Ÿ’” NIST SP 800-38D
AES-CCM ๐Ÿ’š ๐Ÿ’” ๐Ÿ’› ๐Ÿ’š NIST SP 800-38C
AES-CBC ๐Ÿ’” ๐Ÿ’” ๐Ÿ’š ๐Ÿ’š NIST SP 800-38A
AES-CTR ๐Ÿ’” ๐Ÿ’” ๐Ÿ’š ๐Ÿ’š NIST SP 800-38A
ChaCha20+Poly1305 ๐Ÿ’š ๐Ÿ’” ๐Ÿ’š ๐Ÿ’› RFC 7539
XSalsa20+Poly1305 ๐Ÿ’š ๐Ÿ’” ๐Ÿ’š ๐Ÿ’› None

Legend

Heart Meaning
๐Ÿ’š Great
๐Ÿ’› Fine
๐Ÿ’” Bad

โ€  Assumes hardware acceleration for the AES block cipher function

โ€ก Work is underway in the IRTF CFRG to provide an informational RFC for AES-GCM-SIV. For more information, see draft-irtf-cfrg-gcmsiv. When standardization work around AES-GCM-SIV is complete, it will be considered for inclusion in this library.

Language Support

Miscreant libraries are available for the following languages:

Language Version
C# nuget
Go N/A
JavaScript npm
Python pypi
Ruby gem
Rust crate

Documentation

Please see the Miscreant Wiki for more detailed documentation and usage notes.

Related Projects

  • XSTREAM: public-key cryptography built on Miscreant and the X25519 elliptic curve Diffie-Hellman function.
  • minc (the MIscreaNt Cryptotool): a command-line encryption utility built on Miscreant and XSTREAM.

Help and Discussion

Have questions? Want to suggest a feature or change?

Code of Conduct

We abide by the Contributor Covenant and ask that you do as well.

For more information, please see CODE_OF_CONDUCT.md.

Key Rap

The paper describing AES-SIV, Deterministic Authenticated-Encryption: A Provable-Security Treatment of the Key-Wrap Problem contains this explanatory rap song at the end, which goes out to all the chronic IV misusing miscreants in the land:

Yo! Weโ€™z gonnaโ€™ take them keys anโ€™ whatever you pleaze
We gonnaโ€™ wrap โ€™em all up looks like some ranโ€™om gup
Make somethinโ€™ gnarly and funky wonโ€™t fool no half-wit junkie
So the gameโ€™s like AE but thereโ€™s one major hitch
No coins can be pitched thereโ€™s no state to enrich
the IVโ€™s in a ditch dead drunk on cheap wine
Now NIST and X9 and their friends at the fort
suggest that you stick it in a six-layer torte
S/MIME has a scheme thereโ€™s even one more
So many ways that itโ€™s hard to keep score
And maybe they work and maybe theyโ€™re fine
but I want some proofs for spendinโ€™ my time
After wrappinโ€™ them keys gonnaโ€™ help out some losers
chronic IV abusers donโ€™t read no directions
risk a deadly infection If a rusty IVโ€™s drippinโ€™ into yoโ€™ veins
and ya never do manage to get it exchanged
Then we got ya somethinโ€™ and it comes at low cost
When you screw up again not all โ€™ill be lost

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/miscreant/miscreant

Copyright

Copyright (c) 2017-2018 The Miscreant Developers. Distributed under the MIT license. See LICENSE.txt for further details.

Some language-specific subprojects include sources from other authors with more specific licensing requirements, though all projects are MIT licensed. Please see the respective LICENSE.txt files in each project for more information.

meta's People

Contributors

tarcieri avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

meta's Issues

SIVx / PMAC2x

See Revisiting Full-PRF-Secure PMAC and Using It for Beyond-Birthday Authenticated Encryption

This paper proposes an authenticated encryption scheme,
called SIVx, that preserves BBB security also without the requirement
for nonces. For this purpose, we propose a single-key BBB-secure message
authentication code with 2n-bit outputs, called PMAC2x, based on a
tweakable block cipher. PMAC2x is motivated by PMAC_TBC1k by
Naito; we revisit its security proof and point out an invalid assumption.
As a remedy, we provide an alternative proof for our construction, and
derive a corrected bound for PMAC_TBC1k.

Related issue: #76

js: node-webcrypto-ossl 1.0.26 incompatible with typescript 2.6.2

Hey,

When trying to install miscrants dev-dependencies today, the node-webcrypto-ossl install failed with an error in build:e5 tsc.

just running the following:

$ npm install

...SNIP...

> [email protected] postinstall /Users/aegarbutt/src/miscreant/js/node_modules/node-webcrypto-ossl
> npm run build


> [email protected] build /Users/aegarbutt/src/miscreant/js/node_modules/node-webcrypto-ossl
> npm run build:es5


> [email protected] build:es5 /Users/aegarbutt/src/miscreant/js/node_modules/node-webcrypto-ossl
> tsc

lib/crypto/aes.ts(94,13): error TS2322: Type 'Promise<{}>' is not assignable to type 'PromiseLike<ArrayBuffer>'.
  Types of property 'then' are incompatible.
    Type '<TResult1 = {}, TResult2 = never>(onfulfilled?: ((value: {}) => TResult1 | PromiseLike<TResult1>)...' is not assignable to type '<TResult1 = ArrayBuffer, TResult2 = never>(onfulfilled?: ((value: ArrayBuffer) => TResult1 | Prom...'.
      Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible.
        Types of parameters 'value' and 'value' are incompatible.
          Type '{}' is not assignable to type 'ArrayBuffer'.
            Property 'byteLength' is missing in type '{}'.
lib/crypto/aes.ts(102,13): error TS2322: Type 'Promise<{}>' is not assignable to type 'PromiseLike<ArrayBuffer>'.
lib/crypto/hmac.ts(26,29): error TS2345: Argument of type 'CryptoKey' is not assignable to parameter of type 'CryptoKeyPair | PromiseLike<CryptoKeyPair> | undefined'.
  Type 'CryptoKey' is not assignable to type 'PromiseLike<CryptoKeyPair>'.
    Property 'then' is missing in type 'CryptoKey'.
lib/crypto/pbkdf2.ts(44,9): error TS2322: Type 'Promise<CryptoKey>' is not assignable to type 'PromiseLike<CryptoKey>'.
  Types of property 'then' are incompatible.
    Type '<TResult1 = CryptoKey, TResult2 = never>(onfulfilled?: ((value: CryptoKey) => TResult1 | PromiseL...' is not assignable to type '<TResult1 = CryptoKey, TResult2 = never>(onfulfilled?: ((value: CryptoKey) => TResult1 | PromiseL...'. Two different types with this name exist, but they are unrelated.
      Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible.
        Types of parameters 'value' and 'value' are incompatible.
          Type 'CryptoKey' is not assignable to type 'CryptoKey'. Two different types with this name exist, but they are unrelated.
            Property 'native_' is missing in type 'CryptoKey'.

However, if I drop the typescript version to @2.3.4 (as found in this issue: PeculiarVentures/node-webcrypto-ossl#107)

$ npm install

...SNIP...

z
> [email protected] postinstall /Users/aegarbutt/src/miscreant/js/node_modules/node-webcrypto-ossl
> npm run build


> [email protected] build /Users/aegarbutt/src/miscreant/js/node_modules/node-webcrypto-ossl
> npm run build:es5


> [email protected] build:es5 /Users/aegarbutt/src/miscreant/js/node_modules/node-webcrypto-ossl
> tsc

added 487 packages in 53.381s

Thanks!

pip/python

Hi, I'm a fan of SIV and nonce-less modes. I was trying out your Python implementation and the usual pip install for some reason does not bring in the miscreant/aes directory. Github code looks right, but may be something different when loaded from pip. I'm teaching a teaching a Cryptography class and was looking for an easy to install SIV Python package.
I've got my own implementation of Python AES-SIV already, in case you're interested:
https://github.com/nymble/cryptopy/blob/master/cipher/aes_siv.py

Currently working on ChaCha-SIV ...

Paul

Using same nonce

Just seeking your advice.

In your documentation you say to use a unique nonce for every encrypted message when using AES-SIV.

Is this a requirement? If not, what would be the security issues? If yes, then can the nonce be appended to the first 16 bytes of the encrypted output?

The reason I ask is that I see some production projects that are using the same KEY + NONCE for every encryption.

See here: https://cryptomator.org/security/architecture/
Look for: Filename Encryption

[Python] Incorrect documentation example for AES SIV open

In the following wiki document:
https://github.com/miscreant/miscreant/wiki/Python-Documentation

The last piece of example code should be like this:

import os
from miscreant.aes.siv import SIV

key = SIV.generate_key()
siv = SIV(key)

message = "Hello, world!"
nonce = os.urandom(16)

ciphertext = siv.seal(message, [nonce])
plaintext = siv.open(ciphertext, [nonce])

(only the last line is different as we should open ciphertext and not message)

Formal verification

It would be nice to formally verify Miscreant's implementations of algorithms (e.g. CMAC, PMAC), and in particular verify the Rust version.

Galois Cryptol may be useful here:

https://cryptol.net/

My understanding is given a Cryptol description of an algorithm, Galois' Software Analysis Workbench tool could potentially formally prove equivalence to e.g. the Rust implementation:

https://saw.galois.com/

miscreant.net with Xamarin on Android drifferent result

Hi.

I get different results with the same DotNet-Code (miscreant.net) in Windows and Xamarin on Android.

I use this project "CryptomatorAccessDemo" (or more specific only the "CryptomatorHelper") that is using miscreant.net to (de)code Cryptomator Vaults.

To test I simply use and test vault with just some small files and folders in it.

My detailed problem description with example logs and code links where it is implemented is here:
lellis1936/CryptomatorAccessDemo#1

Currently as a workaround I use a "Binding Library" for the original Cryptomator "siv-mode" java jar file but of course it would be nice to have all in csharp.

I think it is somewhere when using "TransformFinalBlock", I found a DotNet Bug about verison below 4.6.2 for reuse, but even when I used higher versions for the windows example tool (CryptomatorAccessDemo), it was still working for me, I could not recreate the problem (the other/wrong hash) with windows.

Any idea what it could be or what I could try?

Many thanks!

[C#] AES CMAC implementation crashes with certain plain text len

Hello,
I think I found a bug. Please have a look at the following C# code:

var aead = Aead.CreateAesCmacSiv( masterKey );
aead.Seal( Encoding.UTF8.GetBytes( "123456789012345" ) ); // Works
aead.Seal( Encoding.UTF8.GetBytes( "1234567890123456" ) ); // Crashes
aead.Seal( Encoding.UTF8.GetBytes( "12345678901234567" ) ); // Works

Message: "Index out of range"
StackTrace: "Miscreant.Utils.Pad(Byte[] buffer, Int32 position)\r\n bei Miscreant.AesSiv.S2V(Byte[][] headers, Byte[] message)\r\n bei Miscreant.AesSiv.Seal(Byte[] plaintext, Byte[][] data)"

An aead.Open() will crash, too (e.g. when the seal with 16 chars is done with another implementation).
NuGet shows me a Miscreant version 0.3.1.

Support for placing the SIV tag at the end of the message?

AES-SIV as specified in RFC 5297 places the SIV tag, which plays a dual role as both an initialization vector and MAC, at the beginning of the message (as commonly seen with IVs) as opposed to the end (as commonly seen with MACs).

I hate to reopen what I am sure is an ancient bikeshedding debate, but I think it makes a lot more sense to place the SIV tag at the end of the message. For in-place APIs this means the plaintext aligns to the beginning of the buffer, instead of being 16 bytes into it to leave space for the tag. It also makes it difficult to incorporate these algorithms into libraries which are trying to offer an abstract in-place API which can be used in conjunction with more traditional AEAD algorithms that place the MAC tag at the end of the message.

It's also elicited a number of "WTF the MAC is at the beginning?"-style reactions from a number of people attempting to use or just taking a look at the library, to the point I am getting tired of hearing it.

This would break compatibility with RFC 5297, so if support for placing the tag at the end of the message were added, I would prefer for it to be optional, and for AES-SIV default to RFC 5297 compatibility. On the other hand, as a greenfield construction, perhaps AES-PMAC-SIV could default to placing it at the end.

Aside from having an option to specify where to place the tag, it has no impact on API design except for in-place APIs, but merely changes the message format. The Rust implementation is the only one which presently offers an in-place API. In regard to it, a buffer type (#151) could be used to abstract message slicing so code is capable of working with the tag at either the beginning or the end without other changes.

Table-based CTZ implementation (used to implement PMAC in JS, Python, and Ruby) does not support large messages

Using AES-PMAC-SIV with Python 3.6 as follows produces as an error:

from miscreant.aead import AEAD
from secrets import token_bytes

aead = AEAD('AES-PMAC-SIV', key=b'0'*64)

# this works:
aead.seal(token_bytes(1024*4), nonce=b'0' * 16)

# this fails:
aead.seal(token_bytes(1024*5), nonce=b'0' * 16)
Traceback (most recent call last):
  File "error.py", line 5, in <module>
    aead.seal(token_bytes(1024*5), nonce=b'0' * 16)
  File "/Users/denis/.virtualenvs/spare/lib/python3.6/site-packages/miscreant/aead.py", line 60, in seal
    return self.siv.seal(plaintext, [associated_data, nonce])
  File "/Users/denis/.virtualenvs/spare/lib/python3.6/site-packages/miscreant/aes/siv.py", line 47, in seal
    v = self.__s2v(associated_data, plaintext)
  File "/Users/denis/.virtualenvs/spare/lib/python3.6/site-packages/miscreant/aes/siv.py", line 114, in __s2v
    mac.update(plaintext[:difference])
  File "/Users/denis/.virtualenvs/spare/lib/python3.6/site-packages/miscreant/mac/pmac.py", line 118, in update
    self.__process_buffer()
  File "/Users/denis/.virtualenvs/spare/lib/python3.6/site-packages/miscreant/mac/pmac.py", line 145, in __process_buffer
    self.offset.xor_in_place(self.l[ctz.trailing_zeroes(self.counter + 1)])
  File "/Users/denis/.virtualenvs/spare/lib/python3.6/site-packages/miscreant/ctz.py", line 25, in trailing_zeroes
    return CTZ_TABLE[value]
IndexError: list index out of range

With AES-SIV this error does not occur.

[Rust] Optional clear_on_drop

I am trying to compile to wasm32-unknown-unknown and get the following error:

rust-lld: error: unknown file type: hide.o

I read that I can't compile clear_on_drop to wasm.

So it would be nice it could be excluded optionally.

js: Produce a miscreant.min.js

For use in web browsers, it'd be nice to have a minified single-file JavaScript implementation checked into the repo.

The gulpfile is presently set up to produce file-by-file translations from TypeScript and will need to be changed to support this version.

If we do things correctly, we should be able to release this same version via npm/yarn.

Automated performance testing

It looks like performance regressed rather severely in a commit reverted here:

#87

It would be nice to detect such regressions automatically and prevent them in the future

Support a faster construction than AES-SIV

The AES-SIV construction is built on AES-CMAC, which is not parallelizable due to its CBC chaining.

We should pick an additional cipher to support which does not have this restriction and provides better performance.

Potential candidates:

  • AES-GCM-SIV is a high-performance SIV mode currently in the final stages of standardization by the IRTF CFRG.
  • AES-PMAC-SIV is an alternatitive construction of AES-SIV which replaces AES-CMAC with AES-PMAC, a parallelizable MAC built on AES designed by Phil Rogaway.
  • AEZ is a newer, faster, parallelizable authenticated encryption cipher with improved security properties, co-designed by Phil Rogaway who also designed AES-SIV.
  • HS1-SIV is a authenticated encryption cipher several people thought was compelling but was unfortunately eliminated from the CAESAR competition.

Comparison

This is a rough breakdown of how the options compare. If you feel any of these are in error, please leave a comment and we can adjust them.

Name Performance Complexity Standardization IP Rights
AES-GCM-SIV ๐Ÿ’– โ€  ๐Ÿ’” ๐Ÿ’› ๐Ÿ’š
AES-PMAC-SIV ๐Ÿ’š ๐Ÿ’š ๐Ÿ’” ๐Ÿ’šโ€ก
AEZ ๐Ÿ’š ๐Ÿ’” ๐Ÿ’” ๐Ÿ’š
HS1-SIV ๐Ÿ’š ๐Ÿ’” ๐Ÿ’” ๐Ÿ’š

โ€ NOTE: AES-GCM-SIV only gets a ๐Ÿ’– performance rating on platforms that provide the hardware instructions necessary to accelerate the POLYVAL function, e.g. the CLMUL instructions on Intel/AMD CPUs. On platforms without this acceleration, AES-GCM-SIV's performance will be much worse.

โ€กNOTE: PMAC was previously patented by Phil Rogaway, however he has since abandoned his patents:

I abandoned all patent filings pertaining to PMAC many years ago. As far as I know, there is no IP relevant to using PMAC โ€” nothing owned by me or by anyone else.

See the PMAC FAQ for more information.

rust: Revisit Buffer type?

I tried to introduce a Buffer type (#116, reverted in #118) for the in-place API which takes care of slicing the message and MAC portions of the in-place buffer for you, in hopes of improving the ergonomics and abstracting over the odd way in which the plaintext portion of a message starts in the middle of the buffer instead of the beginning.

My original goal was to have Buffer wrap a &[u8] and use Into<Buffer> to bound the buffer type passed into the in-place APIs, allowing the caller's choice of either a byte slice or a Buffer to be passed.

Unfortunately, this doesn't work because we'd need to coerce a reference into an owned type. We could do that with an unsafe pointer cast, but I was hoping to avoid that, so I experimented with having Buffer<T> wrap an owned type with bounds AsRef<&[u8]> and AsMut<&[u8]>, allowing it to wrap either Vec or fixed-sized arrays, and then just passing &Buffer<T> to all the in-place APIs (i.e. mandating use of Buffer instead of allowing either a buffer or a slice).

All of that was slightly annoying but the owned type seemed to be working ok. That was until I realized AsRef and AsMut, in a pre-const generics world, are only implemented for fixed-sized arrays up to 32, which was a showstopper.

I think having a Buffer type is still worth investigating, as the present in-place ergonomics still leave quite a bit to be desired. I think it might be worth investigating the unsafe pointer cast option, although it would violate Miscreant's "all safe Rust" selling point.

KDF

It would be nice to support a KDF (or more than one) so long as it is parsimonious with the rest of the library, that is to say: based on the existing primitives supplied by the library, namely the AES block cipher and the PRFs CMAC and PMAC. Bonus points for a parallel construction.

Some options:

Key Wrap API

This is a tracking issue for adding a key wrapping API to Miscreant. Key wrapping was the original impetus for the creation of the AES-SIV construction, and also the impetus for creating Miscreant in the first place.

This API should generate a random encryption key of the desired length (with e.g. a 128-bit minimum), encrypt it under a given algorithm, and return both the randomly generated key and its encrypted form.

Since the key is guaranteed to be generated randomly and therefore never repeats, thanks to the SIV construction we can entirely omit a nonce/associated data, ensuring that ciphertext for wrapped keys are as small as possible.

Implementation Status

This is a tracking issue for adding key wrap support to the various language-specific implementations in this project:

Language Support
Go โ›”
Python โ›”
Ruby โ›”
Rust โ›”
TypeScript โ›”

1k-PMAC_Plus: "Beyond Birthday Bound" (BBC) secure PMAC_Plus variant

https://eprint.iacr.org/2017/848

In this paper, we propose 1k-PMAC_Plus, the first rate-11 single keyed block cipher based BBB (Beyond Birthday Bound) secure (in standard model) deterministic MAC construction without arbitrary field multiplications. Our construction is a simple one-key variant of PMAC_Plus. Moreover, we show higher security guarantee than what was proved originally for PMAC_Plus. Our proven bound shows that PMAC_Plus and 1k-PMAC_Plus always provide higher security guarantee than what was promised by PMAC against all types of adversaries.

AES-PMAC-SIV

This is a tracking issue for implementing AES-PMAC-SIV in the various languages within this project:

Language Support Notes
Go โœ… Done
Python โœ… Done
Ruby โœ… Done
Rust โœ… Done
TypeScript โœ… Done

[Nodejs] AES-SIV: ciphertext verification failure

I am using the following, but can't seem to get it working in Node 9. Any help would be appreciated.

Error: AES-SIV: ciphertext verification failure!

let generateDataKey = () => {
    return new Promise((resolve, reject) => {
        crypto.randomBytes(32, (err, buf) => {
            if (err) throw err;
            resolve(buf);
        });
    });
};

let generateNonce = () => {
    return new Promise((resolve, reject) => {
        crypto.randomBytes(16, (err, buf) => {
            if(err) throw err;
            resolve(buf);
        });
    });
};

async function encryptText(plainText) {
    // get new datakey
    const dataKey = await generateDataKey();
    //get nonce
    const nonce = await generateNonce();
    
    // get encryptor
    let encryptor = await miscreant.SIV.importKey(dataKey, "AES-SIV", new miscreant.PolyfillCryptoProvider());
    let stringBuffer = Buffer.from(plainText, 'utf8');
    let cipherText = await encryptor.seal(stringBuffer, dataKey, nonce);
    let decrypted = await encryptor.open(cipherText, nonce)
}

[Rust] Add examples

This is a great project. Thank you @tarcieri .

For those who don't know much about cryptography,
it would be very useful if there were some very common usage examples.

I suggest writing two usage examples:

  • encrypt/decrypt(&message)
  • encrypt/decrypt(&partial_message)
// Case 1
let message: Vec<u8> = vec![ ... ];
aes_siv.encrypt(&message);

// Case 2
let file = File::open("/bigfile.txt");
let mut filesize = file.size();
while filesize > 0 {
    aes_siv.encrypt(&file.read(1024));
    filesize -= 1024;
}

[Python] Add examples

It would be great to improve python documentation adding examples on how to use PMAC or STREAM. Something like JavaScript documentation would be perfect

PHP support

PHP is a widely-used programming language. It would be great if Miscreant supported it.

Is the STREAM construction misuse-resistant?

My understanding from the paper is that STREAM's security notion (nOAE) requires that nonces don't repeat. Instantiating STREAM on top of AES-SIV does make nonce reuse slightly less harmful, I think.* But an attacker can do something like chunk swapping between two messages that share the same nonce, which means that authenticity is immediately lost after a single reuse. Do I have that right? Is that something worth clarifying in the docs?

* It seems like some privacy might be retained after a few nonce reuses, but the "chosen prefix, secret suffix" attack described in the same paper would work if the attacker could make a lot of queries.

[Ruby] Correct Wiki

Hi, thanks for this project! There a few examples on the Ruby wiki page that could use updating.

message = "Hello, world!"
nonce = Miscreant::AEAD.generate_nonce
ciphertext = encryptor.seal(message, nonce: nonce)

And

message = "Hello, world!"
nonce = Miscreant::AEAD.generate_nonce
ciphertext = encryptor.seal(message, nonce: nonce)
plaintext = encryptor.open(ciphertext, nonce: nonce)

C (ABI) support

C is a widely-used programming language, particularly in the IoT/embedded space. It would be great if Miscreant supported it.

One approach would be to add a C ABI to the existing Rust implementation. This could leverage Rust's memory safety to deliver a safe implementation, and would avoid having to take on and support an additional language. The disadvantage is it involves pulling in a Rust toolchain to perform builds.

Another option would be to support a simple "from scratch" C implementation. If we were to do this, it would be nice to ensure its correctness somehow, e.g. formally proving equivalence with the Rust implementation, or potentially generating the C code from the Rust code.

STREAM support (Nonce-based OAE)

This is a tracking issue for adding support for the STREAM nonce-based OAE construction as described in the paper Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance (Section 7, p. 18):

STREAM Diagram

Design

The STREAM design used in Miscreant has the following properties:

  • KDF is not mandatory: raw Ek is used for encryption
  • Nonce encoding is nonce_prefix || ctr || last_block where:
    • nonce_prefix: 8-byte (64-bit) fixed prefix
    • ctr: 32-bit big endian counter value
    • last_block: 1-byte flag indicating if this is the last block (0x00 if false, 0x01 if true)
  • Associated data is per-message (as suggested in the IACR version of the paper)

Implementation Status

This is a tracking issue for adding STREAM support to the various language-specific implementations in this project:

Language Support Notes
Go โœ… Done (#132)
Python โœ… Done (#124)
Ruby โœ… Done (#122)
Rust โœ… Done (#112)
TypeScript โœ… Done (#131)

design input vec

Line: https://github.com/miscreant/miscreant/blob/master/rust/src/aead.rs#L78-L79

Currently, we put NONCE_DATA(or IV_DATA) bytes in front of the vec,
If we use open_in_place/seal_in_place method, like:

const NONCE_LEN: usize = 16;

let mut text = vec![1u8; 100];

let mut key = [0u8; 32];
let nonce = [0u8; NONCE_LEN];
let ad = [0u8; 0];
let mut aes = miscreant::aead::Aes128Siv::new(&key);

// if we put `NONCE_DATA`(or IV_DATA) bytes at the end of the vec,
// we just can write like this:
// text.resize(text.len() + NONCE_LEN, 0u8);
fpr _ in 0..NONCE_LEN {
    text.insert(0, 0u8);
}
aes.seal_in_place(&nonce, &ad, &mut text);

AES-GCM-SIV

Continuing from #31, this is a tracking ticket for potentially including AES-GCM-SIV as a supported construction in this library.

AES-GCM-SIV has an advantages that it is both very fast, and is on track to become an IETF standard with a soon-to-be-published RFC. For these reasons it is likely to get multiple, highly optimized implementations across various platforms in many languages.

The disadvantages are that it is a much more complicated construction than the ones presently implemented by Miscreant, that the security bounds are lower, and that for the construction to be performant it relies on hardware instructions which can be used to accelerate the POLYVAL function, which is not widely available on low-power platforms like IoT devices or low-end smartphones.

[Python] Index out of range on PMAC STREAM

Hi,

I may miss something on the usage of Encryptor with PMAC but I got a IndexError: list index out of range when I try to seal something big enough with it.

How to reproduce

import os
from miscreant.stream import Encryptor

nonce = os.urandom(8)
key = os.urandom(12)
encryptor = Encryptor('AES-PMAC-SIV', key, nonce)
with open('a_file', 'rb') as le_file:
    encryptor.seal(le_file.read())

I got no issue by replacing 'AES-PMAC-SIV' by 'AES-SIV'
It started to have an error with a file of 5Ko

Am I misusing PMAC algo ? Since I read it had better performance than AES-SIV, I would prefer using it as I use STREAM to encrypt large file.

Thank you

Java support

Java is a widely-used programming language. It would be great if Miscreant supported it.

Drop trait for secret-keys for memory management

libsodium provides a mem-zeroing functionality which gets called from the rust versions (e.g. rust_sodium) for at-least all the secret keys which are user-defined types with Drop. There is no such management in miscreant. Just wandering on what the opinions are on this:

  • It is important and we need it and miscreant is ready to provide it
  • It is important but the user is expected to do the wrapping but miscreant wouldn't see this as its goal
  • It's not needed (if so any reasons would be good to know)

Best practices for key reuse?

What's the best practice for reusing an encryption key? After how many messages/GiBs it's recommended to rotate the encryption key?

AES-SIV interop with no nonce, aad or plaintext

When trying to test interoperability with an implementation for another lib, I stumbled on the case where N=0 (according to https://tools.ietf.org/html/rfc5297#section-2.4 ). That's the case where the key is used to encrypt zero data, zero AD, with no nonce. That follows a separate path in the pseudo code:

      S2V(K, S1, ..., Sn) {
        if n = 0 then
          return V = AES-CMAC(K, <one>)
        fi

On your test vectors I see the following:

            "name:s":"Empty Authenticated Data And Plaintext Example",
            "key:d16":"fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
            "ad:A<d16>":[],
            "plaintext:d16":"",
"ciphertext:d16":"f2007a5beb2b8900c588a7adf599f172"

With my implementation

key: fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
nonce,aad,plaintext zero
ciphertext: 949f99cbcc3eb5da6d3c45d0f59aa9c7

While I'm not complete sure that this lib is wrong here, when in my code remove the special handling for the case of zero ad,plaintext and nonce, it brings the exact same ciphertext as you have in the test vector. Seeing the code, there seems to be no special handling of this case.

[Go] Failure with in-place Seal/Open

According to Seal/Open documentations (and the cipher.AEAD interface), they should work when dst and plaintext (resp. ciphertext) overlap entirely.

However, that doesn't work. This test fails:

func TestAESCMACSIVInPlace(t *testing.T) {
	v := loadAESSIVExamples("aes_siv.tjson")[0]

	c, err := NewAESCMACSIV(v.key)
	if err != nil {
		t.Fatalf("NewAESCMACSIV: %s", err)
	}
	pt := make([]byte, len(v.plaintext), len(v.plaintext)+c.Overhead())
	copy(pt, v.plaintext)
	ct, err := c.Seal(pt[:0], pt, v.ad...)
	if err != nil {
		t.Errorf("Seal: %s", err)
	}
	if !bytes.Equal(v.ciphertext, ct) {
		t.Errorf("Seal: expected: %x\ngot: %x", v.ciphertext, ct)
	}

	copy(ct, v.ciphertext)
	pt, err = c.Open(ct[:0], ct, v.ad...)
	if err != nil {
		t.Errorf("Open: %s", err)
	}
	if !bytes.Equal(v.plaintext, pt) {
		t.Errorf("Open: expected: %x\ngot: %x", v.plaintext, pt)
	}
}

I can write a MR fixing this, however, since the tag comes before the ciphertext it seems that will require making a whole copy of the input in this case (since XORKeyStream alse requires its input to overlap entirely or not at all), entirely defeating the purpose of the in-place optimization. However, I don't see a way out without breaking the cipher.AEAD contract, or moving the tag after the ciphertext (#152)

What do you think?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.