-
-
Notifications
You must be signed in to change notification settings - Fork 34.1k
Description
Overview
I've started work on adding AES CCM support to node. This is part of a larger goal of getting full DTLS support into node. Specifically I need AES_128_CCM_8 support. Until then, I'm working on a native module for the crypto support and helping @Rantanen improve his DTLS protocol module.
OpenSSL already supports this cipher, so I thought it was a matter of adding the necessary calls. I've since run into a complication with the order of calls required by OpenSSL and how the CipherBase class is structured.
I'm looking for some discussion and/or guidance on how to proceed with implementation.
CCM Requirements
CCM requires specifying 2 or 3 additional lengths for proper operation.
- Length of the IV. This is already available as an argument and does not present any issues.
- Length of the authentication tag
- Length of the plaintext / ciphertext (only required if also specifying AAD)
Authentication Tag Length
The authentication tag length must be specified before calling EVP_CipherInit_ex with the key and iv parameters (source). If specified afterwards, OpenSSL returns a buffer full of zeroes.
Plaintext / Ciphertext length
The total plaintext or ciphertext length must be specified before setting the AAD (via EVP_CipherUpdate in cipher.setAAD) and before adding any plaintext (via EVP_CipherUpdate in cipher.update). If not specified before, cipher.setAAD will fail.
Proposed API Changes
In order to provide the 1 or 2 lengths required, some API changes will be needed. This is where some input would be greatly appreciated.
The requirement for the authentication tag length is needed before the final OpenSSL call of CipherBase::initiv. This means crypto.createCipheriv and crypto.createDecipheriv need additional optional parameters.
- Add an optional
authTagLengthproperty to theoptionsparameter ofcrypto.createCipherivandcrypto.createDecipheriv
The requirement for the plaintext / ciphertext length depends on using AAD, thus perhaps it makes sense to add an optional parameter to cipher.setAAD?
- Change the signature of
cipher.setAADtocipher.setAAD(buffer, [length]). The confusing part here is thatlengthis not the length of the AAD, but the plaintext / ciphertext length.
I'm open to any and all suggestions regarding API signature changes, or even new methods.
What does everyone think?