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
authTagLength
property to theoptions
parameter ofcrypto.createCipheriv
andcrypto.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.setAAD
tocipher.setAAD(buffer, [length])
. The confusing part here is thatlength
is 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?