@@ -241,17 +241,22 @@ Once the `cipher.final()` method has been called, the `Cipher` object can no
241241longer be used to encrypt data. Attempts to call ` cipher.final() ` more than
242242once will result in an error being thrown.
243243
244- ### cipher.setAAD(buffer)
244+ ### cipher.setAAD(buffer[ , options ] )
245245<!-- YAML
246246added: v1.0.0
247247-->
248248- ` buffer ` {Buffer}
249+ - ` options ` {object}
249250- Returns the {Cipher} for method chaining.
250251
251- When using an authenticated encryption mode (only ` GCM ` is currently
252+ When using an authenticated encryption mode (only ` GCM ` and ` CCM ` are currently
252253supported), the ` cipher.setAAD() ` method sets the value used for the
253254_ additional authenticated data_ (AAD) input parameter.
254255
256+ The ` options ` argument is optional for ` GCM ` . When using ` CCM ` , the
257+ ` plaintextLength ` option must be specified and its value must match the length
258+ of the plaintext in bytes. See [ CCM mode] [ ] .
259+
255260The ` cipher.setAAD() ` method must be called before [ ` cipher.update() ` ] [ ] .
256261
257262### cipher.getAuthTag()
@@ -1312,7 +1317,12 @@ deprecated: REPLACEME
13121317- ` options ` {Object} [ ` stream.transform ` options] [ ]
13131318
13141319Creates and returns a ` Cipher ` object that uses the given ` algorithm ` and
1315- ` password ` . Optional ` options ` argument controls stream behavior.
1320+ ` password ` .
1321+
1322+ The ` options ` argument controls stream behavior and is optional except when a
1323+ cipher in CCM mode is used (e.g. ` 'aes-128-ccm' ` ). In that case, the
1324+ ` authTagLength ` option is required and specifies the length of the
1325+ authentication tag in bytes, see [ CCM mode] [ ] .
13161326
13171327The ` algorithm ` is dependent on OpenSSL, examples are ` 'aes192' ` , etc. On
13181328recent OpenSSL releases, ` openssl list-cipher-algorithms ` will display the
@@ -1353,8 +1363,10 @@ changes:
13531363- ` options ` {Object} [ ` stream.transform ` options] [ ]
13541364
13551365Creates and returns a ` Cipher ` object, with the given ` algorithm ` , ` key ` and
1356- initialization vector (` iv ` ). Optional ` options ` argument controls stream
1357- behavior.
1366+ The ` options ` argument controls stream behavior and is optional except when a
1367+ cipher in CCM mode is used (e.g. ` 'aes-128-ccm' ` ). In that case, the
1368+ ` authTagLength ` option is required and specifies the length of the
1369+ authentication tag in bytes, see [ CCM mode] [ ] .
13581370
13591371The ` algorithm ` is dependent on OpenSSL, examples are ` 'aes192' ` , etc. On
13601372recent OpenSSL releases, ` openssl list-cipher-algorithms ` will display the
@@ -1396,7 +1408,12 @@ deprecated: REPLACEME
13961408- ` options ` {Object} [ ` stream.transform ` options] [ ]
13971409
13981410Creates and returns a ` Decipher ` object that uses the given ` algorithm ` and
1399- ` password ` (key). Optional ` options ` argument controls stream behavior.
1411+ ` password ` (key).
1412+
1413+ The ` options ` argument controls stream behavior and is optional except when a
1414+ cipher in CCM mode is used (e.g. ` 'aes-128-ccm' ` ). In that case, the
1415+ ` authTagLength ` option is required and specifies the length of the
1416+ authentication tag in bytes, see [ CCM mode] [ ] .
14001417
14011418The implementation of ` crypto.createDecipher() ` derives keys using the OpenSSL
14021419function [ ` EVP_BytesToKey ` ] [ ] with the digest algorithm set to MD5, one
@@ -1425,8 +1442,12 @@ changes:
14251442- ` options ` {Object} [ ` stream.transform ` options] [ ]
14261443
14271444Creates and returns a ` Decipher ` object that uses the given ` algorithm ` , ` key `
1428- and initialization vector (` iv ` ). Optional ` options ` argument controls stream
1429- behavior.
1445+ and initialization vector (` iv ` ).
1446+
1447+ The ` options ` argument controls stream behavior and is optional except when a
1448+ cipher in CCM mode is used (e.g. ` 'aes-128-ccm' ` ). In that case, the
1449+ ` authTagLength ` option is required and specifies the length of the
1450+ authentication tag in bytes, see [ CCM mode] [ ] .
14301451
14311452The ` algorithm ` is dependent on OpenSSL, examples are ` 'aes192' ` , etc. On
14321453recent OpenSSL releases, ` openssl list-cipher-algorithms ` will display the
@@ -2167,6 +2188,71 @@ Based on the recommendations of [NIST SP 800-131A][]:
21672188
21682189See the reference for other recommendations and details.
21692190
2191+ ### CCM mode
2192+
2193+ CCM is one of the two supported [ AEAD algorithms] [ ] . Applications which use this
2194+ mode must adhere to certain restrictions when using the cipher API:
2195+
2196+ - The authentication tag length must be specified during cipher creation by
2197+ setting the ` authTagLength ` option and must be one of 4, 6, 8, 10, 12, 14 or
2198+ 16 bytes.
2199+ - The length of the initialization vector (nonce) ` N ` must be between 7 and 13
2200+ bytes (` 7 ≤ N ≤ 13 ` ).
2201+ - The length of the plaintext is limited to ` 2 ** (8 * (15 - N)) ` bytes.
2202+ - When decrypting, the authentication tag must be set via ` setAuthTag() ` before
2203+ specifying additional authenticated data and / or calling ` update() ` .
2204+ Otherwise, decryption will fail and ` final() ` will throw an error in
2205+ compliance with section 2.6 of [ RFC 3610] [ ] .
2206+ - Using stream methods such as ` write(data) ` , ` end(data) ` or ` pipe() ` in CCM
2207+ mode might fail as CCM cannot handle more than one chunk of data per instance.
2208+ - When passing additional authenticated data (AAD), the length of the actual
2209+ message in bytes must be passed to ` setAAD() ` via the ` plaintextLength `
2210+ option. This is not necessary if no AAD is used.
2211+ - As CCM processes the whole message at once, ` update() ` can only be called
2212+ once.
2213+ - Even though calling ` update() ` is sufficient to encrypt / decrypt the message,
2214+ applications * must* call ` final() ` to compute and / or verify the
2215+ authentication tag.
2216+
2217+ ``` js
2218+ const crypto = require (' crypto' );
2219+
2220+ const key = ' keykeykeykeykeykeykeykey' ;
2221+ const nonce = crypto .randomBytes (12 );
2222+
2223+ const aad = Buffer .from (' 0123456789' , ' hex' );
2224+
2225+ const cipher = crypto .createCipheriv (' aes-192-ccm' , key, nonce, {
2226+ authTagLength: 16
2227+ });
2228+ const plaintext = ' Hello world' ;
2229+ cipher .setAAD (aad, {
2230+ plaintextLength: Buffer .byteLength (plaintext)
2231+ });
2232+ const ciphertext = cipher .update (plaintext, ' utf8' );
2233+ cipher .final ();
2234+ const tag = cipher .getAuthTag ();
2235+
2236+ // Now transmit { ciphertext, tag }.
2237+
2238+ const decipher = crypto .createDecipheriv (' aes-192-ccm' , key, nonce, {
2239+ authTagLength: 16
2240+ });
2241+ decipher .setAuthTag (tag);
2242+ decipher .setAAD (aad, {
2243+ plaintextLength: ciphertext .length
2244+ });
2245+ const receivedPlaintext = decipher .update (ciphertext, null , ' utf8' );
2246+
2247+ try {
2248+ decipher .final ();
2249+ } catch (err) {
2250+ console .error (' Authentication failed!' );
2251+ }
2252+
2253+ console .log (receivedPlaintext);
2254+ ```
2255+
21702256## Crypto Constants
21712257
21722258The following constants exported by ` crypto.constants ` apply to various uses of
@@ -2525,7 +2611,9 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL.
25252611[ `tls.createSecureContext()` ] : tls.html#tls_tls_createsecurecontext_options
25262612[ `verify.update()` ] : #crypto_verify_update_data_inputencoding
25272613[ `verify.verify()` ] : #crypto_verify_verify_object_signature_signatureformat
2614+ [ AEAD algorithms ] : https://en.wikipedia.org/wiki/Authenticated_encryption
25282615[ Caveats ] : #crypto_support_for_weak_or_compromised_algorithms
2616+ [ CCM mode ] : #crypto_ccm_mode
25292617[ Crypto Constants ] : #crypto_crypto_constants_1
25302618[ HTML 5.2 ] : https://www.w3.org/TR/html52/changes.html#features-removed
25312619[ HTML5's `keygen` element ] : https://developer.mozilla.org/en-US/docs/Web/HTML/Element/keygen
@@ -2536,6 +2624,7 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL.
25362624[ OpenSSL's SPKAC implementation ] : https://www.openssl.org/docs/man1.0.2/apps/spkac.html
25372625[ RFC 2412 ] : https://www.rfc-editor.org/rfc/rfc2412.txt
25382626[ RFC 3526 ] : https://www.rfc-editor.org/rfc/rfc3526.txt
2627+ [ RFC 3610 ] : https://www.rfc-editor.org/rfc/rfc3610.txt
25392628[ RFC 4055 ] : https://www.rfc-editor.org/rfc/rfc4055.txt
25402629[ initialization vector ] : https://en.wikipedia.org/wiki/Initialization_vector
25412630[ stream-writable-write ] : stream.html#stream_writable_write_chunk_encoding_callback
0 commit comments