Uh oh!
There was an error while loading. Please reload this page.
crypto: add support for AES-CCM - #18138
Conversation
991a94c to
6d0a3e0Comparetniessen
commented
Jan 17, 2018
Rebased due to a conflict with #18017. @nodejs/crypto and @nodejs/tsc, is there anything I can do to aid in discussing and reviewing this change? |
Uh oh!
There was an error while loading. Please reload this page.
tniessen
commented
Jan 17, 2018
@jasnell Thanks! Yes, documentation is still pending, I just want to discuss the general API before documenting its details :) |
jasnell
commented
Jan 22, 2018
ping @nodejs/tsc |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
be707a9 to
78d0441Comparetniessen
commented
Jan 24, 2018
@bnoordhuis Thank you for your thorough review! I tried to address all suggestions (except #18138 (comment)), PTAL if you can. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
e2f87d4 to
4c4dad0Compare✔️ Light CI: https://ci.nodejs.org/job/node-test-commit-light/179/ |
Seems like I found the cause of the FIPS failure thanks to gdb. openssl/openssl@9cca7be introduced a slight change to the CCM API back in 2015, and this change never made it into the FIPS release. Without this commit, the authentication tag must be specified along with its length when decrypting, and I believe this makes it incompatible with our current design. The only option I can think of right now is to make CCM unsupported when in FIPS mode and to throw an error in This is the conflicting line: (gdb) f
#0 aes_ccm_ctrl (c=0x3d1b490, type=17, arg=8, ptr=0x0) at e_aes.c:12841284 if ((c->encrypt && ptr) || (!c->encrypt && !ptr))
(gdb) next
1285 return 0;There is one other thing I came across, OpenSSL 1.1.0 seems to have fixed the problem with |
bnoordhuis
commented
Jan 29, 2018
I'm okay with that. |
jasnell
commented
Jan 29, 2018
I'm good with not supporting CCM in FIPS also. |
tniessen
commented
Jan 30, 2018
For now, I only disabled CCM decryption in FIPS mode, PTAL. |
bluetiger30
commented
Jan 31, 2018
great work guys , I was waiting for this |
tniessen
commented
Jan 31, 2018
@bluetiger30 This change will most likely be included in all releases beginning with node 10.0.0, but not in previous releases. |
@addaleax I suggested to make it semver-minor in #18138 (comment) without response, I am okay with that. The only reason I marked this semver-major is that it can break code which incorrectly used CCM before, because we did not account for that in previous releases, e.g., if you pass invalid CCM options to |
rvagg
commented
Apr 5, 2018
Yes, I'm fine with this addition and the API and being conservative on semver-major is probably a good idea although I wouldn't say it's essential. However#19794 is more important than getting this landed for Node 10 and that PR is going to heavily impact this one. AES-CCM is going to have fairly minimal use due to the necessarily awkward API so this is pretty low priority (sorry @tniessen but I suspect you already understand this). Getting #19794 safely landed without holding it up even further is critical so I'd rather see this PR have to change to fit that PR rather than the other way around. @tniessen could you do a quick investigation to see what changes might be required to sit on top of the 1.1.0 support @shigeki is adding? I wouldn't discard the exact code in this PR btw, we could possibly relax the semver-major and land this on 8.x as it is now so it's not entirely useless as it is now. I think I'd prefer to wait until after 10.x goes live to make a call on 8.x support for CCM. |
tniessen
commented
Apr 5, 2018
Side note: On a par with OpenSSL.
It indeed seems to be, the lack of TSC attention was noticeable long before 1.1.0h was even released. There haven't been any changes to this PR in weeks.
It lands cleanly and lite CI passes: https://ci.nodejs.org/job/node-test-commit-lite/589/ |
Trott
commented
Apr 5, 2018
R=@danbev perhaps? |
rvagg
commented
Apr 5, 2018
beautiful, if this lands cleanly with 1.1.0 then I see no other holdup, lgtm |
Trott
commented
Apr 5, 2018
Only CI that didn't finish last time was Linux, so here's a re-run of just that: https://ci.nodejs.org/job/node-test-commit-linux/17674/ |
Commit 8fb4ea9 ("test: add deprecation code to expectWarning") did not take into account that the same warning could be expected multiple times. This bug was discovered in nodejs#18138 and this commit adds a fix for this issue. Refs: nodejs#18138
tniessen
commented
Apr 6, 2018
I created tniessen@a191f6b by "landing" #19766, #18138 (this PR) and #19794 (in this order) on top of the current master. Again, there were no conflicts. Additional CI for that commit: https://ci.nodejs.org/job/node-test-commit/17477/ Unless someone objects, I intend to land this along with #19766 today. |
Commit 8fb4ea9 ("test: add deprecation code to expectWarning") did not take into account that the same warning could be expected multiple times. This bug was discovered in #18138 and this commit adds a fix for this issue. PR-URL: #19766 Refs: #18138 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: James M Snell <jasnell@gmail.com>
rvagg
commented
Apr 6, 2018
CI is a mess, but not because of these changes. lgtm, let's get it merged, thanks for the hard work on this @tniessen. |
This commit adds support for another AEAD algorithm and introduces required API changes and extensions. Due to the design of CCM itself and the way OpenSSL implements it, there are some restrictions when using this mode as outlined in the updated documentation. PR-URL: #18138Fixes: #2383 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Shigeki Ohtsu <ohtsu@ohtsu.org> Reviewed-By: Rod Vagg <rod@vagg.org> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
tniessen
commented
Apr 6, 2018
tniessen
commented
Apr 6, 2018
@Trott I marked this PR as semver-major again given that multiple TSC members approved after nodejs/TSC#516 and that it landed in time for node 10. At the very least, this is semver-minor. |
This change replaces some constants with better alternatives which were unavailable in OpenSSL 1.0.2. Refs: nodejs#19794 Refs: nodejs#18138
This change replaces some constants with better alternatives which were unavailable in OpenSSL 1.0.2. PR-URL: #20339 Refs: #19794 Refs: #18138 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This change replaces some constants with better alternatives which were unavailable in OpenSSL 1.0.2. PR-URL: #20339 Refs: #19794 Refs: #18138 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
tniessen
commented
May 15, 2019
openssl/openssl@67c81ec just landed and slightly relaxes one of the difficulties in using CCM, thus reducing the API differences between CCM and other modes slightly. I am not sure if it is worth cherry-picking since I assume we usually only cherry-pick security stuff. |
CCM ("Counter with Cipher Block Chaining-Message Authentication Code")
OpenSSL currently supports two AEAD algorithms, GCM and CCM. While node has supported GCM for years, CCM is a bit more difficult to implement and use.
Currently, this PR implements an API similar to what was proposed by @brycekahle in #2383:
createCipher,createDecipher,createCipherivandcreateDecipherivaccept an optionauthTagLength. While the tag length is not relevant for GCM, it is for CCM. (And yes, using CCM withcreateCipher/createDecipheris inherently insecure.)setAADaccepts additionaloptionsas an optional second argument. The only currently recognized option isplaintextLength, which specifies the length of the plaintext / ciphertext in bytes.There are some critical aspects:
authTagLengthoption when using CCM. Not providing this option causes an error to be thrown bycreate(De|C)ipher(iv)?.plaintextLengthoption when using CCM if and only if AAD is provided. The explanation is simple, the length of the plaintext is encoded into the first block of the cipher, and thus must be available before performing an update (and before encoding the AAD).update()can only be called once. Again, the reason is very simple, CCM operates in what is sometimes called a "packet" or "offline mode", meaning that all data is processed at once.Some of these points can be relaxed:
authTagLengthoption, we could simplify the migration to this "new" AEAD. We could stick with the default value used within OpenSSL (12 bytes) or upgrade to 16 bytes (as e.g. pycryptodome does).setAADuntilupdateis called, we take away the need to specify theplaintextLength. All data still needs to be passed toupdatein a single call.We should discuss both, but it should be possible to add these features later on if they turn out to be good ideas (as long as they don't break anything). Aside from that, I am always happy about feedback and suggestions!
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passesAffected core subsystem(s)
crypto