Skip to content

crypto: API changes needed for AES Counter with CBC-MAC (CCM) support #2383

Closed
@brycekahle

Description

@brycekahle

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 the options parameter of crypto.createCipheriv and crypto.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 to cipher.setAAD(buffer, [length]). The confusing part here is that length 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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    cryptoIssues and PRs related to the crypto subsystem.feature requestIssues that request new features to be added to Node.js.semver-minorPRs that contain new features and should be released in the next minor version.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions