Implement AES-GCM proposal (IETF draft) #430

Merged
merged 30 commits into from Mar 25, 2016

Conversation

Projects
None yet
4 participants
@tanx
Member

tanx commented Mar 22, 2016

This implements the IETF draft for authenticated encryption. It does not implement the full proposal, only the following parts:

Advantages of AES-GCM

  • Performance: in contrast to CFB mode, GCM is implemented natively in WebCrypto for all major browsers. This should make bulk encryption really fast, since there is no more JS code for symmetric encryption or hashing. Integrity protection is already done by GCM. Chrome and other browsers also use hardware acceleration on supported CPUs, which should speed things up even more.
  • Mitigate side channel attacks: using a native-only approach for our crypto primitives mitigates timing attack vectors. So no more flame wars about JS crypto ;)

Open Questions regarding the specification

We should give feedback to the author about the following...

  • I have added a single octet version number as the first byte in the packet, just like in the sym_encrypted_integrity_protected packet. This is not specified in the current IETF draft, but seems to make sense to allow for an upgrade path for future authenticated encryption schemes.
  • The specification calls for an "additional data" field to be appended after the variable length encrypted payload. But the specification also states that this is probably not required in the context of OpenPGP and recommends to leave it empty (0 bytes).
  • AES-GCM has an optional tag length parameter than defaults to 128. Does this need to be specified/stored in the data packet? I have left it out for now.
  • AES-GCM initialization vectors are recommended to be 12 bytes long and I did not find any example online that uses an IV of a different length. The length is currently hardcoded in the gcm module, but it may make sense to specify/store it in the data packet.

tanx added some commits Mar 23, 2016

Use only standard window.crypto.subtle in gcm.js
There is currently no support for AES-GCM in IE11 and Safari/iOSqq
@tanx

This comment has been minimized.

Show comment
Hide comment
@tanx

tanx Mar 23, 2016

Member

Alright. I've gotten this to work on node and all browsers. I've also fixed all the unit tests. IE11 and Safari/WebKit don't support GCM as they don't implement the current crypto.subtle interface. So those browsers currently fall back to asm.js. On Chrome, Firefox, Edge and node it's native all the way down though :)

Ready for review and feel free the merge!

Member

tanx commented Mar 23, 2016

Alright. I've gotten this to work on node and all browsers. I've also fixed all the unit tests. IE11 and Safari/WebKit don't support GCM as they don't implement the current crypto.subtle interface. So those browsers currently fall back to asm.js. On Chrome, Firefox, Edge and node it's native all the way down though :)

Ready for review and feel free the merge!

@tanx

This comment has been minimized.

Show comment
Hide comment
@tanx

tanx Mar 23, 2016

Member

Here are some benchmark results for an encrypt/decrypt roundtrip of 30 MB of data ... 353 ms for aes256 aren't bad at all :) @bartbutler @evilaliv3 @toberndo this should allow you to handle larger files alot better.

bildschirmfoto 2016-03-24 um 01 58 32

N.B. Chrome uses Intel's AES-NI hardware acceleration on supporting chipsets. I ran the benchmarks on my 2011 MacBook Air 1.7 GHz Core i5, which has support.

Member

tanx commented Mar 23, 2016

Here are some benchmark results for an encrypt/decrypt roundtrip of 30 MB of data ... 353 ms for aes256 aren't bad at all :) @bartbutler @evilaliv3 @toberndo this should allow you to handle larger files alot better.

bildschirmfoto 2016-03-24 um 01 58 32

N.B. Chrome uses Intel's AES-NI hardware acceleration on supporting chipsets. I ran the benchmarks on my 2011 MacBook Air 1.7 GHz Core i5, which has support.

@evilaliv3

This comment has been minimized.

Show comment
Hide comment
@evilaliv3

evilaliv3 Mar 23, 2016

Contributor

great! well done @tanx

i will take a look at the pull tonight :)

Contributor

evilaliv3 commented Mar 23, 2016

great! well done @tanx

i will take a look at the pull tonight :)

@fpietrosanti

This comment has been minimized.

Show comment
Hide comment
@fpietrosanti

fpietrosanti Mar 23, 2016

Question: Are we also so lucky that AES-GCM symmetric cipher is also already compatible with GnuPG (when used in companion with NIST P-* Curves)?

Question: Are we also so lucky that AES-GCM symmetric cipher is also already compatible with GnuPG (when used in companion with NIST P-* Curves)?

@tanx

This comment has been minimized.

Show comment
Hide comment
@tanx

tanx Mar 24, 2016

Member

Question: Are we also so lucky that AES-GCM symmetric cipher is also already compatible with GnuPG (when used in companion with NIST P-* Curves)?

No, not yet. GnuPG v2.1 supports the NIST curves, but not GCM. I'm currently emailing with Werner of GnuPG as to which AEAD mode makes sense to use for OpenPGP. He favors OCB (which is encumbered by patents [1][2]) while I favor GCM (which is patent free [3][4]).

Matthew Green on GCM:

GCM. Galois Counter Mode has quietly become the most popular AE(AD) mode in the field today, despite the fact that everyone hates it. The popularity is due in part to the fact that GCM is extremely fast, but mostly it's because the mode is patent-free. GCM is 'on-line' and can be parallelized, and (best): recent versions of OpenSSL and Crypto++ provide good implementations, mostly because it's now supported as a TLS ciphersuite. As a side benefit, GCM will occasionally visit your house and fix broken appliances.

Matthew Green on OCB:

OCB. In performance terms Offset Codebook Mode blows the pants off of all the other modes I mention in this post. It's 'on-line' and doesn't require any real understanding of Galois fields to implement** -- you can implement the whole thing with a block cipher, some bit manipulation and XOR. If OCB was your kid, he'd play three sports and be on his way to Harvard. You'd brag about him to all your friends.

Unfortunately OCB is not your kid. It belongs to Philip Rogaway, who also happens to hold a patent on it. This is no problem if you're developing GPL software (it's free for you), but if you want to use it in a commercial product -- or even license under Apache -- you'll probably have to pay up. As a consequence OCB is used in approximately no industry standards, though you might find it in some commercial products."

[1] https://en.wikipedia.org/wiki/OCB_mode#Patents
[2] http://crypto.stackexchange.com/questions/5639/why-is-ocb-aes-mode-not-becoming-a-standard-for-authenticated-encryption
[3] https://en.wikipedia.org/wiki/Galois/Counter_Mode#Patents
[4] http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html

Member

tanx commented Mar 24, 2016

Question: Are we also so lucky that AES-GCM symmetric cipher is also already compatible with GnuPG (when used in companion with NIST P-* Curves)?

No, not yet. GnuPG v2.1 supports the NIST curves, but not GCM. I'm currently emailing with Werner of GnuPG as to which AEAD mode makes sense to use for OpenPGP. He favors OCB (which is encumbered by patents [1][2]) while I favor GCM (which is patent free [3][4]).

Matthew Green on GCM:

GCM. Galois Counter Mode has quietly become the most popular AE(AD) mode in the field today, despite the fact that everyone hates it. The popularity is due in part to the fact that GCM is extremely fast, but mostly it's because the mode is patent-free. GCM is 'on-line' and can be parallelized, and (best): recent versions of OpenSSL and Crypto++ provide good implementations, mostly because it's now supported as a TLS ciphersuite. As a side benefit, GCM will occasionally visit your house and fix broken appliances.

Matthew Green on OCB:

OCB. In performance terms Offset Codebook Mode blows the pants off of all the other modes I mention in this post. It's 'on-line' and doesn't require any real understanding of Galois fields to implement** -- you can implement the whole thing with a block cipher, some bit manipulation and XOR. If OCB was your kid, he'd play three sports and be on his way to Harvard. You'd brag about him to all your friends.

Unfortunately OCB is not your kid. It belongs to Philip Rogaway, who also happens to hold a patent on it. This is no problem if you're developing GPL software (it's free for you), but if you want to use it in a commercial product -- or even license under Apache -- you'll probably have to pay up. As a consequence OCB is used in approximately no industry standards, though you might find it in some commercial products."

[1] https://en.wikipedia.org/wiki/OCB_mode#Patents
[2] http://crypto.stackexchange.com/questions/5639/why-is-ocb-aes-mode-not-becoming-a-standard-for-authenticated-encryption
[3] https://en.wikipedia.org/wiki/Galois/Counter_Mode#Patents
[4] http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html

@evilaliv3

This comment has been minimized.

Show comment
Hide comment
@evilaliv3

evilaliv3 Mar 24, 2016

Contributor

i've not digged into the crypto details but simply took a review of the code not finding annything to comment; tests works for me.

i see that there are various failing on travis but it seems to me that it's saucelabs that is instable.

Contributor

evilaliv3 commented Mar 24, 2016

i've not digged into the crypto details but simply took a review of the code not finding annything to comment; tests works for me.

i see that there are various failing on travis but it seems to me that it's saucelabs that is instable.

@tanx

This comment has been minimized.

Show comment
Hide comment
@tanx

tanx Mar 24, 2016

Member

i've not digged into the crypto details but simply took a review of the code not finding annything to comment; tests works for me.

@evilaliv3 thanks!

Note that I have added a minor change in 8b46a11 which prefers aes128 over aes192. This is due to lack of support for 192 keys in blink.

Member

tanx commented Mar 24, 2016

i've not digged into the crypto details but simply took a review of the code not finding annything to comment; tests works for me.

@evilaliv3 thanks!

Note that I have added a minor change in 8b46a11 which prefers aes128 over aes192. This is due to lack of support for 192 keys in blink.

@tanx

This comment has been minimized.

Show comment
Hide comment
@tanx

tanx Mar 24, 2016

Member

Alright. If there are no objections I would merge?

N.B. you can deactivate this feature by setting openpgp.config.aead_protect = false for compatibility with GPG. But since the performance impact is so high, I would keep the feature on by default.

Member

tanx commented Mar 24, 2016

Alright. If there are no objections I would merge?

N.B. you can deactivate this feature by setting openpgp.config.aead_protect = false for compatibility with GPG. But since the performance impact is so high, I would keep the feature on by default.

tanx added some commits Mar 24, 2016

@toberndo

This comment has been minimized.

Show comment
Hide comment
@toberndo

toberndo Mar 24, 2016

Member

N.B. you can deactivate this feature by setting openpgp.config.aead_protect = false for compatibility
with GPG. But since the performance impact is so high, I would keep the feature on by default.

I would see the main use case for OpenPGP.js to provide an implementation that is compatible with the OpenPGP standard and other implementations. Setting AES-GCM as the default would break that use case. When using OpenPGP.js in a closed environment then it makes totally sense to use AEAD, but I see this as a special use case which justifies to tweak the default config.

Besides this, great work. The performance gap between the native AES-GCM and AES-GCM asm.js implemenation (>20x) is larger than one would expect according to what asm.js promises. Looks like there is either room for improvement in the asmcrypto lib, or it might be worth to consider WebAssembly.

Member

toberndo commented Mar 24, 2016

N.B. you can deactivate this feature by setting openpgp.config.aead_protect = false for compatibility
with GPG. But since the performance impact is so high, I would keep the feature on by default.

I would see the main use case for OpenPGP.js to provide an implementation that is compatible with the OpenPGP standard and other implementations. Setting AES-GCM as the default would break that use case. When using OpenPGP.js in a closed environment then it makes totally sense to use AEAD, but I see this as a special use case which justifies to tweak the default config.

Besides this, great work. The performance gap between the native AES-GCM and AES-GCM asm.js implemenation (>20x) is larger than one would expect according to what asm.js promises. Looks like there is either room for improvement in the asmcrypto lib, or it might be worth to consider WebAssembly.

@evilaliv3

This comment has been minimized.

Show comment
Hide comment
@evilaliv3

evilaliv3 Mar 24, 2016

Contributor

i agree with @toberndo for what relates the openpgp.config.aead_protect = false by default

Contributor

evilaliv3 commented Mar 24, 2016

i agree with @toberndo for what relates the openpgp.config.aead_protect = false by default

@tanx

This comment has been minimized.

Show comment
Hide comment
@tanx

tanx Mar 24, 2016

Member

Ok. I'll deactivate it by default and document it in the README, so developers that do not have to worry about interoperability in their app can find it easily.

Member

tanx commented Mar 24, 2016

Ok. I'll deactivate it by default and document it in the README, so developers that do not have to worry about interoperability in their app can find it easily.

@tanx

This comment has been minimized.

Show comment
Hide comment
@tanx

tanx Mar 24, 2016

Member

Besides this, great work. The performance gap between the native AES-GCM and AES-GCM asm.js implemenation (>20x) is larger than one would expect according to what asm.js promises. Looks like there is either room for improvement in the asmcrypto lib, or it might be worth to consider WebAssembly.

Chrome uses Intel's AES-NI hardware acceleration on supporting chipsets. I ran the benchmarks on my 2011 MacBook Air 1.7 GHz Core i5, which has support. I doubt wasm will get anywhere near those results since it's up to 2x as slow as C code.

Member

tanx commented Mar 24, 2016

Besides this, great work. The performance gap between the native AES-GCM and AES-GCM asm.js implemenation (>20x) is larger than one would expect according to what asm.js promises. Looks like there is either room for improvement in the asmcrypto lib, or it might be worth to consider WebAssembly.

Chrome uses Intel's AES-NI hardware acceleration on supporting chipsets. I ran the benchmarks on my 2011 MacBook Air 1.7 GHz Core i5, which has support. I doubt wasm will get anywhere near those results since it's up to 2x as slow as C code.

tanx added some commits Mar 24, 2016

Use underscore instead of camelcase in config
zeroCopy —> zero_copy
useNative —> use_native
Remove unnecessary tests from build
@tanx

This comment has been minimized.

Show comment
Hide comment
@tanx

tanx Mar 24, 2016

Member

Ok. The feature is now disabled by default. It's ready to merge from my side.

Also, I will be joining the IETF working group session on April 6th to discuss the spec. If you have any thoughts, please let me know. I made the case for WebCrypto and GCM here.

Member

tanx commented Mar 24, 2016

Ok. The feature is now disabled by default. It's ready to merge from my side.

Also, I will be joining the IETF working group session on April 6th to discuss the spec. If you have any thoughts, please let me know. I made the case for WebCrypto and GCM here.

tanx added some commits Mar 25, 2016

@tanx tanx merged commit 10bf9ec into master Mar 25, 2016

0 of 2 checks passed

continuous-integration/travis-ci/pr The Travis CI build is in progress
Details
continuous-integration/travis-ci/push The Travis CI build is in progress
Details

@tanx tanx deleted the aes_gcm branch Mar 25, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment