@@ -241,17 +241,22 @@ Once the `cipher.final()` method has been called, the `Cipher` object can no
241
241
longer be used to encrypt data. Attempts to call ` cipher.final() ` more than
242
242
once will result in an error being thrown.
243
243
244
- ### cipher.setAAD(buffer)
244
+ ### cipher.setAAD(buffer[ , options ] )
245
245
<!-- YAML
246
246
added: v1.0.0
247
247
-->
248
248
- ` buffer ` {Buffer}
249
+ - ` options ` {object}
249
250
- Returns the {Cipher} for method chaining.
250
251
251
- When using an authenticated encryption mode (only ` GCM ` is currently
252
+ When using an authenticated encryption mode (only ` GCM ` and ` CCM ` are currently
252
253
supported), the ` cipher.setAAD() ` method sets the value used for the
253
254
_ additional authenticated data_ (AAD) input parameter.
254
255
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
+
255
260
The ` cipher.setAAD() ` method must be called before [ ` cipher.update() ` ] [ ] .
256
261
257
262
### cipher.getAuthTag()
@@ -1312,7 +1317,12 @@ deprecated: REPLACEME
1312
1317
- ` options ` {Object} [ ` stream.transform ` options] [ ]
1313
1318
1314
1319
Creates 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] [ ] .
1316
1326
1317
1327
The ` algorithm ` is dependent on OpenSSL, examples are ` 'aes192' ` , etc. On
1318
1328
recent OpenSSL releases, ` openssl list-cipher-algorithms ` will display the
@@ -1353,8 +1363,10 @@ changes:
1353
1363
- ` options ` {Object} [ ` stream.transform ` options] [ ]
1354
1364
1355
1365
Creates 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] [ ] .
1358
1370
1359
1371
The ` algorithm ` is dependent on OpenSSL, examples are ` 'aes192' ` , etc. On
1360
1372
recent OpenSSL releases, ` openssl list-cipher-algorithms ` will display the
@@ -1396,7 +1408,12 @@ deprecated: REPLACEME
1396
1408
- ` options ` {Object} [ ` stream.transform ` options] [ ]
1397
1409
1398
1410
Creates 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] [ ] .
1400
1417
1401
1418
The implementation of ` crypto.createDecipher() ` derives keys using the OpenSSL
1402
1419
function [ ` EVP_BytesToKey ` ] [ ] with the digest algorithm set to MD5, one
@@ -1425,8 +1442,12 @@ changes:
1425
1442
- ` options ` {Object} [ ` stream.transform ` options] [ ]
1426
1443
1427
1444
Creates 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] [ ] .
1430
1451
1431
1452
The ` algorithm ` is dependent on OpenSSL, examples are ` 'aes192' ` , etc. On
1432
1453
recent OpenSSL releases, ` openssl list-cipher-algorithms ` will display the
@@ -2167,6 +2188,71 @@ Based on the recommendations of [NIST SP 800-131A][]:
2167
2188
2168
2189
See the reference for other recommendations and details.
2169
2190
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
+
2170
2256
## Crypto Constants
2171
2257
2172
2258
The 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.
2525
2611
[ `tls.createSecureContext()` ] : tls.html#tls_tls_createsecurecontext_options
2526
2612
[ `verify.update()` ] : #crypto_verify_update_data_inputencoding
2527
2613
[ `verify.verify()` ] : #crypto_verify_verify_object_signature_signatureformat
2614
+ [ AEAD algorithms ] : https://en.wikipedia.org/wiki/Authenticated_encryption
2528
2615
[ Caveats ] : #crypto_support_for_weak_or_compromised_algorithms
2616
+ [ CCM mode ] : #crypto_ccm_mode
2529
2617
[ Crypto Constants ] : #crypto_crypto_constants_1
2530
2618
[ HTML 5.2 ] : https://www.w3.org/TR/html52/changes.html#features-removed
2531
2619
[ 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.
2536
2624
[ OpenSSL's SPKAC implementation ] : https://www.openssl.org/docs/man1.0.2/apps/spkac.html
2537
2625
[ RFC 2412 ] : https://www.rfc-editor.org/rfc/rfc2412.txt
2538
2626
[ RFC 3526 ] : https://www.rfc-editor.org/rfc/rfc3526.txt
2627
+ [ RFC 3610 ] : https://www.rfc-editor.org/rfc/rfc3610.txt
2539
2628
[ RFC 4055 ] : https://www.rfc-editor.org/rfc/rfc4055.txt
2540
2629
[ initialization vector ] : https://en.wikipedia.org/wiki/Initialization_vector
2541
2630
[ stream-writable-write ] : stream.html#stream_writable_write_chunk_encoding_callback
0 commit comments