| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -249,11 +249,11 @@ added: v1.0.0 | |||
| 249 | 249 | - `plaintextLength` {number} | |
| 250 | 250 | * Returns: {Cipher} for method chaining. | |
| 251 | 251 | ||
| 252 | - When using an authenticated encryption mode (only `GCM` and `CCM` are currently | ||
| 253 | - supported), the `cipher.setAAD()` method sets the value used for the | ||
| 252 | + When using an authenticated encryption mode (`GCM`, `CCM` and `OCB` are | ||
| 253 | + currently supported), the `cipher.setAAD()` method sets the value used for the | ||
| 254 | 254 | _additional authenticated data_ (AAD) input parameter. | |
| 255 | 255 | ||
| 256 | - The `options` argument is optional for `GCM`. When using `CCM`, the | ||
| 256 | + The `options` argument is optional for `GCM` and `OCB`. When using `CCM`, the | ||
| 257 | 257 | `plaintextLength` option must be specified and its value must match the length | |
| 258 | 258 | of the plaintext in bytes. See [CCM mode][]. | |
| 259 | 259 | ||
@@ -263,8 +263,8 @@ The `cipher.setAAD()` method must be called before [`cipher.update()`][]. | |||
| 263 | 263 | <!-- YAML | |
| 264 | 264 | added: v1.0.0 | |
| 265 | 265 | --> | |
| 266 | - * Returns: {Buffer} When using an authenticated encryption mode (only `GCM` and | ||
| 267 | - `CCM` are currently supported), the `cipher.getAuthTag()` method returns a | ||
| 266 | + * Returns: {Buffer} When using an authenticated encryption mode (`GCM`, `CCM` | ||
| 267 | + and `OCB` are currently supported), the `cipher.getAuthTag()` method returns a | ||
| 268 | 268 | [`Buffer`][] containing the _authentication tag_ that has been computed from | |
| 269 | 269 | the given data. | |
| 270 | 270 | ||
@@ -412,8 +412,8 @@ changes: | |||
| 412 | 412 | - `plaintextLength` {number} | |
| 413 | 413 | * Returns: {Decipher} for method chaining. | |
| 414 | 414 | ||
| 415 | - When using an authenticated encryption mode (only `GCM` and `CCM` are currently | ||
| 416 | - supported), the `decipher.setAAD()` method sets the value used for the | ||
| 415 | + When using an authenticated encryption mode (`GCM`, `CCM` and `OCB` are | ||
| 416 | + currently supported), the `decipher.setAAD()` method sets the value used for the | ||
| 417 | 417 | _additional authenticated data_ (AAD) input parameter. | |
| 418 | 418 | ||
| 419 | 419 | The `options` argument is optional for `GCM`. When using `CCM`, the | |
@@ -433,8 +433,8 @@ changes: | |||
| 433 | 433 | * `buffer` {Buffer | TypedArray | DataView} | |
| 434 | 434 | * Returns: {Decipher} for method chaining. | |
| 435 | 435 | ||
| 436 | - When using an authenticated encryption mode (only `GCM` and `CCM` are currently | ||
| 437 | - supported), the `decipher.setAuthTag()` method is used to pass in the | ||
| 436 | + When using an authenticated encryption mode (`GCM`, `CCM` and `OCB` are | ||
| 437 | + currently supported), the `decipher.setAuthTag()` method is used to pass in the | ||
| 438 | 438 | received _authentication tag_. If no tag is provided, or if the cipher text | |
| 439 | 439 | has been tampered with, [`decipher.final()`][] will throw, indicating that the | |
| 440 | 440 | cipher text should be discarded due to failed authentication. | |
@@ -1324,6 +1324,9 @@ This property is deprecated. Please use `crypto.setFips()` and | |||
| 1324 | 1324 | added: v0.1.94 | |
| 1325 | 1325 | deprecated: v10.0.0 | |
| 1326 | 1326 | changes: | |
| 1327 | + - version: REPLACEME | ||
| 1328 | + pr-url: https://github.com/nodejs/node/pull/21447 | ||
| 1329 | + description: Ciphers in OCB mode are now supported. | ||
| 1327 | 1330 | - version: v10.2.0 | |
| 1328 | 1331 | pr-url: https://github.com/nodejs/node/pull/20235 | |
| 1329 | 1332 | description: The `authTagLength` option can now be used to produce shorter | |
@@ -1341,7 +1344,7 @@ Creates and returns a `Cipher` object that uses the given `algorithm` and | |||
| 1341 | 1344 | `password`. | |
| 1342 | 1345 | ||
| 1343 | 1346 | The `options` argument controls stream behavior and is optional except when a | |
| 1344 | - cipher in CCM mode is used (e.g. `'aes-128-ccm'`). In that case, the | ||
| 1347 | + cipher in CCM or OCB mode is used (e.g. `'aes-128-ccm'`). In that case, the | ||
| 1345 | 1348 | `authTagLength` option is required and specifies the length of the | |
| 1346 | 1349 | authentication tag in bytes, see [CCM mode][]. In GCM mode, the `authTagLength` | |
| 1347 | 1350 | option is not required but can be used to set the length of the authentication | |
@@ -1376,6 +1379,9 @@ Adversaries][] for details. | |||
| 1376 | 1379 | <!-- YAML | |
| 1377 | 1380 | added: v0.1.94 | |
| 1378 | 1381 | changes: | |
| 1382 | + - version: REPLACEME | ||
| 1383 | + pr-url: https://github.com/nodejs/node/pull/21447 | ||
| 1384 | + description: Ciphers in OCB mode are now supported. | ||
| 1379 | 1385 | - version: v10.2.0 | |
| 1380 | 1386 | pr-url: https://github.com/nodejs/node/pull/20235 | |
| 1381 | 1387 | description: The `authTagLength` option can now be used to produce shorter | |
@@ -1395,7 +1401,7 @@ Creates and returns a `Cipher` object, with the given `algorithm`, `key` and | |||
| 1395 | 1401 | initialization vector (`iv`). | |
| 1396 | 1402 | ||
| 1397 | 1403 | The `options` argument controls stream behavior and is optional except when a | |
| 1398 | - cipher in CCM mode is used (e.g. `'aes-128-ccm'`). In that case, the | ||
| 1404 | + cipher in CCM or OCB mode is used (e.g. `'aes-128-ccm'`). In that case, the | ||
| 1399 | 1405 | `authTagLength` option is required and specifies the length of the | |
| 1400 | 1406 | authentication tag in bytes, see [CCM mode][]. In GCM mode, the `authTagLength` | |
| 1401 | 1407 | option is not required but can be used to set the length of the authentication | |
@@ -1441,6 +1447,10 @@ called. | |||
| 1441 | 1447 | <!-- YAML | |
| 1442 | 1448 | added: v0.1.94 | |
| 1443 | 1449 | deprecated: v10.0.0 | |
| 1450 | + changes: | ||
| 1451 | + - version: REPLACEME | ||
| 1452 | + pr-url: https://github.com/nodejs/node/pull/21447 | ||
| 1453 | + description: Ciphers in OCB mode are now supported. | ||
| 1444 | 1454 | --> | |
| 1445 | 1455 | ||
| 1446 | 1456 | > Stability: 0 - Deprecated: Use [`crypto.createDecipheriv()`][] instead. | |
@@ -1454,7 +1464,7 @@ Creates and returns a `Decipher` object that uses the given `algorithm` and | |||
| 1454 | 1464 | `password` (key). | |
| 1455 | 1465 | ||
| 1456 | 1466 | The `options` argument controls stream behavior and is optional except when a | |
| 1457 | - cipher in CCM mode is used (e.g. `'aes-128-ccm'`). In that case, the | ||
| 1467 | + cipher in CCM or OCB mode is used (e.g. `'aes-128-ccm'`). In that case, the | ||
| 1458 | 1468 | `authTagLength` option is required and specifies the length of the | |
| 1459 | 1469 | authentication tag in bytes, see [CCM mode][]. | |
| 1460 | 1470 | ||
@@ -1474,6 +1484,9 @@ to create the `Decipher` object. | |||
| 1474 | 1484 | <!-- YAML | |
| 1475 | 1485 | added: v0.1.94 | |
| 1476 | 1486 | changes: | |
| 1487 | + - version: REPLACEME | ||
| 1488 | + pr-url: https://github.com/nodejs/node/pull/21447 | ||
| 1489 | + description: Ciphers in OCB mode are now supported. | ||
| 1477 | 1490 | - version: v10.2.0 | |
| 1478 | 1491 | pr-url: https://github.com/nodejs/node/pull/20039 | |
| 1479 | 1492 | description: The `authTagLength` option can now be used to restrict accepted | |
@@ -1493,7 +1506,7 @@ Creates and returns a `Decipher` object that uses the given `algorithm`, `key` | |||
| 1493 | 1506 | and initialization vector (`iv`). | |
| 1494 | 1507 | ||
| 1495 | 1508 | The `options` argument controls stream behavior and is optional except when a | |
| 1496 | - cipher in CCM mode is used (e.g. `'aes-128-ccm'`). In that case, the | ||
| 1509 | + cipher in CCM or OCB mode is used (e.g. `'aes-128-ccm'`). In that case, the | ||
| 1497 | 1510 | `authTagLength` option is required and specifies the length of the | |
| 1498 | 1511 | authentication tag in bytes, see [CCM mode][]. In GCM mode, the `authTagLength` | |
| 1499 | 1512 | option is not required but can be used to restrict accepted authentication tags | |
@@ -2367,7 +2380,7 @@ See the reference for other recommendations and details. | |||
| 2367 | 2380 | ||
| 2368 | 2381 | ### CCM mode | |
| 2369 | 2382 | ||
| 2370 | - CCM is one of the two supported [AEAD algorithms][]. Applications which use this | ||
| 2383 | + CCM is one of the supported [AEAD algorithms][]. Applications which use this | ||
| 2371 | 2384 | mode must adhere to certain restrictions when using the cipher API: | |
| 2372 | 2385 | ||
| 2373 | 2386 | - The authentication tag length must be specified during cipher creation by | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2661,6 +2661,11 @@ void CipherBase::Init(const FunctionCallbackInfo<Value>& args) { | |||
| 2661 | 2661 | cipher->Init(*cipher_type, key_buf, key_buf_len, auth_tag_len); | |
| 2662 | 2662 | } | |
| 2663 | 2663 | ||
| 2664 | + static bool IsSupportedAuthenticatedMode(int mode) { | ||
| 2665 | + return mode == EVP_CIPH_CCM_MODE || | ||
| 2666 | + mode == EVP_CIPH_GCM_MODE || | ||
| 2667 | + mode == EVP_CIPH_OCB_MODE; | ||
| 2668 | + } | ||
| 2664 | 2669 | ||
| 2665 | 2670 | void CipherBase::InitIv(const char* cipher_type, | |
| 2666 | 2671 | const char* key, | |
@@ -2678,8 +2683,7 @@ void CipherBase::InitIv(const char* cipher_type, | |||
| 2678 | 2683 | ||
| 2679 | 2684 | const int expected_iv_len = EVP_CIPHER_iv_length(cipher); | |
| 2680 | 2685 | const int mode = EVP_CIPHER_mode(cipher); | |
| 2681 | - const bool is_gcm_mode = (EVP_CIPH_GCM_MODE == mode); | ||
| 2682 | - const bool is_ccm_mode = (EVP_CIPH_CCM_MODE == mode); | ||
| 2686 | + const bool is_authenticated_mode = IsSupportedAuthenticatedMode(mode); | ||
| 2683 | 2687 | const bool has_iv = iv_len >= 0; | |
| 2684 | 2688 | ||
| 2685 | 2689 | // Throw if no IV was passed and the cipher requires an IV | |
@@ -2690,7 +2694,7 @@ void CipherBase::InitIv(const char* cipher_type, | |||
| 2690 | 2694 | } | |
| 2691 | 2695 | ||
| 2692 | 2696 | // Throw if an IV was passed which does not match the cipher's fixed IV length | |
| 2693 | - if (!is_gcm_mode && !is_ccm_mode && has_iv && iv_len != expected_iv_len) { | ||
| 2697 | + if (!is_authenticated_mode && has_iv && iv_len != expected_iv_len) { | ||
| 2694 | 2698 | return env()->ThrowError("Invalid IV length"); | |
| 2695 | 2699 | } | |
| 2696 | 2700 | ||
@@ -2706,7 +2710,7 @@ void CipherBase::InitIv(const char* cipher_type, | |||
| 2706 | 2710 | "Failed to initialize cipher"); | |
| 2707 | 2711 | } | |
| 2708 | 2712 | ||
| 2709 | - if (IsAuthenticatedMode()) { | ||
| 2713 | + if (is_authenticated_mode) { | ||
| 2710 | 2714 | CHECK(has_iv); | |
| 2711 | 2715 | if (!InitAuthenticated(cipher_type, iv_len, auth_tag_len)) | |
| 2712 | 2716 | return; | |
@@ -2781,7 +2785,7 @@ bool CipherBase::InitAuthenticated(const char* cipher_type, int iv_len, | |||
| 2781 | 2785 | } | |
| 2782 | 2786 | ||
| 2783 | 2787 | const int mode = EVP_CIPHER_CTX_mode(ctx_.get()); | |
| 2784 | - if (mode == EVP_CIPH_CCM_MODE) { | ||
| 2788 | + if (mode == EVP_CIPH_CCM_MODE || mode == EVP_CIPH_OCB_MODE) { | ||
| 2785 | 2789 | if (auth_tag_len == kNoAuthTagLength) { | |
| 2786 | 2790 | char msg[128]; | |
| 2787 | 2791 | snprintf(msg, sizeof(msg), "authTagLength required for %s", cipher_type); | |
@@ -2791,27 +2795,29 @@ bool CipherBase::InitAuthenticated(const char* cipher_type, int iv_len, | |||
| 2791 | 2795 | ||
| 2792 | 2796 | #ifdef NODE_FIPS_MODE | |
| 2793 | 2797 | // TODO(tniessen) Support CCM decryption in FIPS mode | |
| 2794 | - if (kind_ == kDecipher && FIPS_mode()) { | ||
| 2798 | + if (mode == EVP_CIPH_CCM_MODE && kind_ == kDecipher && FIPS_mode()) { | ||
| 2795 | 2799 | env()->ThrowError("CCM decryption not supported in FIPS mode"); | |
| 2796 | 2800 | return false; | |
| 2797 | 2801 | } | |
| 2798 | 2802 | #endif | |
| 2799 | 2803 | ||
| 2800 | - if (!EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_CCM_SET_TAG, auth_tag_len, | ||
| 2804 | + // Tell OpenSSL about the desired length. | ||
| 2805 | + if (!EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_SET_TAG, auth_tag_len, | ||
| 2801 | 2806 | nullptr)) { | |
| 2802 | 2807 | env()->ThrowError("Invalid authentication tag length"); | |
| 2803 | 2808 | return false; | |
| 2804 | 2809 | } | |
| 2805 | 2810 | ||
| 2806 | - // When decrypting in CCM mode, this field will be set in setAuthTag(). | ||
| 2807 | - if (kind_ == kCipher) | ||
| 2808 | - auth_tag_len_ = auth_tag_len; | ||
| 2811 | + // Remember the given authentication tag length for later. | ||
| 2812 | + auth_tag_len_ = auth_tag_len; | ||
| 2809 | 2813 | ||
| 2810 | - // Restrict the message length to min(INT_MAX, 2^(8*(15-iv_len))-1) bytes. | ||
| 2811 | - CHECK(iv_len >= 7 && iv_len <= 13); | ||
| 2812 | - max_message_size_ = INT_MAX; | ||
| 2813 | - if (iv_len == 12) max_message_size_ = 16777215; | ||
| 2814 | - if (iv_len == 13) max_message_size_ = 65535; | ||
| 2814 | + if (mode == EVP_CIPH_CCM_MODE) { | ||
| 2815 | + // Restrict the message length to min(INT_MAX, 2^(8*(15-iv_len))-1) bytes. | ||
| 2816 | + CHECK(iv_len >= 7 && iv_len <= 13); | ||
| 2817 | + max_message_size_ = INT_MAX; | ||
| 2818 | + if (iv_len == 12) max_message_size_ = 16777215; | ||
| 2819 | + if (iv_len == 13) max_message_size_ = 65535; | ||
| 2820 | + } | ||
| 2815 | 2821 | } else { | |
| 2816 | 2822 | CHECK_EQ(mode, EVP_CIPH_GCM_MODE); | |
| 2817 | 2823 | ||
@@ -2850,7 +2856,7 @@ bool CipherBase::IsAuthenticatedMode() const { | |||
| 2850 | 2856 | // Check if this cipher operates in an AEAD mode that we support. | |
| 2851 | 2857 | CHECK(ctx_); | |
| 2852 | 2858 | const int mode = EVP_CIPHER_CTX_mode(ctx_.get()); | |
| 2853 | - return mode == EVP_CIPH_GCM_MODE || mode == EVP_CIPH_CCM_MODE; | ||
| 2859 | + return IsSupportedAuthenticatedMode(mode); | ||
| 2854 | 2860 | } | |
| 2855 | 2861 | ||
| 2856 | 2862 | ||
@@ -2883,7 +2889,6 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) { | |||
| 2883 | 2889 | return args.GetReturnValue().Set(false); | |
| 2884 | 2890 | } | |
| 2885 | 2891 | ||
| 2886 | - // Restrict GCM tag lengths according to NIST 800-38d, page 9. | ||
| 2887 | 2892 | unsigned int tag_len = Buffer::Length(args[0]); | |
| 2888 | 2893 | const int mode = EVP_CIPHER_CTX_mode(cipher->ctx_.get()); | |
| 2889 | 2894 | if (mode == EVP_CIPH_GCM_MODE) { | |
@@ -2901,6 +2906,17 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) { | |||
| 2901 | 2906 | "Valid GCM tag lengths are 4, 8, 12, 13, 14, 15, 16.", tag_len); | |
| 2902 | 2907 | ProcessEmitDeprecationWarning(cipher->env(), msg, "DEP0090"); | |
| 2903 | 2908 | } | |
| 2909 | + } else if (mode == EVP_CIPH_OCB_MODE) { | ||
| 2910 | + // At this point, the tag length is already known and must match the | ||
| 2911 | + // length of the given authentication tag. | ||
| 2912 | + CHECK(mode == EVP_CIPH_CCM_MODE || mode == EVP_CIPH_OCB_MODE); | ||
| 2913 | + CHECK_NE(cipher->auth_tag_len_, kNoAuthTagLength); | ||
| 2914 | + if (cipher->auth_tag_len_ != tag_len) { | ||
| 2915 | + char msg[50]; | ||
| 2916 | + snprintf(msg, sizeof(msg), | ||
| 2917 | + "Invalid authentication tag length: %u", tag_len); | ||
| 2918 | + return cipher->env()->ThrowError(msg); | ||
| 2919 | + } | ||
| 2904 | 2920 | } | |
| 2905 | 2921 | ||
| 2906 | 2922 | // Note: we don't use std::min() here to work around a header conflict. | |
@@ -2991,7 +3007,7 @@ CipherBase::UpdateResult CipherBase::Update(const char* data, | |||
| 2991 | 3007 | if (kind_ == kDecipher && IsAuthenticatedMode() && auth_tag_len_ > 0 && | |
| 2992 | 3008 | auth_tag_len_ != kNoAuthTagLength && !auth_tag_set_) { | |
| 2993 | 3009 | CHECK(EVP_CIPHER_CTX_ctrl(ctx_.get(), | |
| 2994 | - EVP_CTRL_GCM_SET_TAG, | ||
| 3010 | + EVP_CTRL_AEAD_SET_TAG, | ||
| 2995 | 3011 | auth_tag_len_, | |
| 2996 | 3012 | reinterpret_cast<unsigned char*>(auth_tag_))); | |
| 2997 | 3013 | auth_tag_set_ = true; | |
@@ -3104,10 +3120,12 @@ bool CipherBase::Final(unsigned char** out, int* out_len) { | |||
| 3104 | 3120 | ||
| 3105 | 3121 | if (ok && kind_ == kCipher && IsAuthenticatedMode()) { | |
| 3106 | 3122 | // In GCM mode, the authentication tag length can be specified in advance, | |
| 3107 | - // but defaults to 16 bytes when encrypting. In CCM mode, it must always | ||
| 3108 | - // be given by the user. | ||
| 3109 | - if (mode == EVP_CIPH_GCM_MODE && auth_tag_len_ == kNoAuthTagLength) | ||
| 3123 | + // but defaults to 16 bytes when encrypting. In CCM and OCB mode, it must | ||
| 3124 | + // always be given by the user. | ||
| 3125 | + if (auth_tag_len_ == kNoAuthTagLength) { | ||
| 3126 | + CHECK(mode == EVP_CIPH_GCM_MODE); | ||
| 3110 | 3127 | auth_tag_len_ = sizeof(auth_tag_); | |
| 3128 | + } | ||
| 3111 | 3129 | CHECK_EQ(1, EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG, | |
| 3112 | 3130 | auth_tag_len_, | |
| 3113 | 3131 | reinterpret_cast<unsigned char*>(auth_tag_))); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments