Skip to content

Commit b6cc8d3

Browse files
committed
crypto: move DEP0182 to End-of-Life
This commit moves support for implicitly short GCM authentication tags to End-of-Life status, thus requiring applications to explicitly specify the `authTagLength` for authentication tags shorter than 128 bits. There is quite a bit of refactoring to be done in the C++ source code. This commit does not do that; instead, it implements a minimal change only in order to avoid excessive divergence across git branches due to this being a semver-major change. Fixes: #52327 Refs: #17523
1 parent 4e1f39b commit b6cc8d3

File tree

4 files changed

+29
-47
lines changed

4 files changed

+29
-47
lines changed

doc/api/crypto.md

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,11 @@ When passing a string as the `buffer`, please consider
925925
<!-- YAML
926926
added: v1.0.0
927927
changes:
928+
- version: REPLACEME
929+
pr-url: https://github.com/nodejs/node/pull/61084
930+
description: Using GCM tag lengths other than 128 bits without specifying
931+
the `authTagLength` option when creating `decipher` is not
932+
allowed anymore.
928933
- version:
929934
- v22.0.0
930935
- v20.13.0
@@ -962,15 +967,6 @@ for `CCM` mode or before [`decipher.final()`][] for `GCM` and `OCB` modes and
962967
`chacha20-poly1305`.
963968
`decipher.setAuthTag()` can only be called once.
964969

965-
Because the `node:crypto` module was originally designed to closely mirror
966-
OpenSSL's behavior, this function permits short GCM authentication tags unless
967-
an explicit authentication tag length was passed to
968-
[`crypto.createDecipheriv()`][] when the `decipher` object was created. This
969-
behavior is deprecated and subject to change (see [DEP0182][]). <strong class="critical">
970-
In the meantime, applications should either set the `authTagLength` option when
971-
calling `createDecipheriv()` or check the actual
972-
authentication tag length before passing it to `setAuthTag()`.</strong>
973-
974970
When passing a string as the authentication tag, please consider
975971
[caveats when using strings as inputs to cryptographic APIs][].
976972

@@ -3361,13 +3357,8 @@ The `options` argument controls stream behavior and is optional except when a
33613357
cipher in CCM or OCB mode (e.g. `'aes-128-ccm'`) is used. In that case, the
33623358
`authTagLength` option is required and specifies the length of the
33633359
authentication tag in bytes, see [CCM mode][].
3364-
For `chacha20-poly1305`, the `authTagLength` option defaults to 16
3360+
For AES-GCM and `chacha20-poly1305`, the `authTagLength` option defaults to 16
33653361
bytes and must be set to a different value if a different length is used.
3366-
For AES-GCM, the `authTagLength` option has no default value when decrypting,
3367-
and `setAuthTag()` will accept arbitrarily short authentication tags. This
3368-
behavior is deprecated and subject to change (see [DEP0182][]). <strong class="critical">
3369-
In the meantime, applications should either set the `authTagLength` option or
3370-
check the actual authentication tag length before passing it to `setAuthTag()`.</strong>
33713362

33723363
The `algorithm` is dependent on OpenSSL, examples are `'aes192'`, etc. On
33733364
recent OpenSSL releases, `openssl list -cipher-algorithms` will
@@ -6522,7 +6513,6 @@ See the [list of SSL OP Flags][] for details.
65226513
[CVE-2021-44532]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44532
65236514
[Caveats]: #support-for-weak-or-compromised-algorithms
65246515
[Crypto constants]: #crypto-constants
6525-
[DEP0182]: deprecations.md#dep0182-short-gcm-authentication-tags-without-explicit-authtaglength
65266516
[FIPS module configuration file]: https://www.openssl.org/docs/man3.0/man5/fips_config.html
65276517
[FIPS provider from OpenSSL 3]: https://www.openssl.org/docs/man3.0/man7/crypto.html#FIPS-provider
65286518
[HTML 5.2]: https://www.w3.org/TR/html52/changes.html#features-removed

doc/api/deprecations.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3992,6 +3992,9 @@ Please use the [`crypto.createHmac()`][] method to create Hmac instances.
39923992

39933993
<!-- YAML
39943994
changes:
3995+
- version: REPLACEME
3996+
pr-url: https://github.com/nodejs/node/pull/61084
3997+
description: End-of-Life.
39953998
- version: v23.0.0
39963999
pr-url: https://github.com/nodejs/node/pull/52552
39974000
description: Runtime deprecation.
@@ -4000,16 +4003,16 @@ changes:
40004003
description: Documentation-only deprecation.
40014004
-->
40024005

4003-
Type: Runtime
4006+
Type: End-of-Life
40044007

4005-
Applications that intend to use authentication tags that are shorter than the
4006-
default authentication tag length must set the `authTagLength` option of the
4008+
For ciphers in GCM mode, the [`decipher.setAuthTag()`][] function used to accept
4009+
authentication tags of any valid length (see also [DEP0090](#DEP0090)). This
4010+
exception has been removed to better align with recommendations per
4011+
[NIST SP 800-38D][], and applications that intend to use authentication tags
4012+
that are shorter than the default authentication tag length (i.e., shorter than
4013+
16 bytes for AES-GCM) must explicitly set the `authTagLength` option of the
40074014
[`crypto.createDecipheriv()`][] function to the appropriate length.
40084015

4009-
For ciphers in GCM mode, the [`decipher.setAuthTag()`][] function accepts
4010-
authentication tags of any valid length (see [DEP0090](#DEP0090)). This behavior
4011-
is deprecated to better align with recommendations per [NIST SP 800-38D][].
4012-
40134016
### DEP0183: OpenSSL engine-based APIs
40144017

40154018
<!-- YAML

src/crypto/crypto_cipher.cc

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -554,23 +554,14 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
554554
is_valid = cipher->auth_tag_len_ == tag_len;
555555
}
556556

557-
if (!is_valid) {
557+
// TODO(tniessen): refactor this check.
558+
if (!is_valid ||
559+
(cipher->ctx_.isGcmMode() && cipher->auth_tag_len_ == kNoAuthTagLength &&
560+
tag_len != EVP_GCM_TLS_TAG_LEN)) {
558561
return THROW_ERR_CRYPTO_INVALID_AUTH_TAG(
559562
env, "Invalid authentication tag length: %u", tag_len);
560563
}
561564

562-
if (cipher->ctx_.isGcmMode() && cipher->auth_tag_len_ == kNoAuthTagLength &&
563-
tag_len != EVP_GCM_TLS_TAG_LEN && env->EmitProcessEnvWarning()) {
564-
if (ProcessEmitDeprecationWarning(
565-
env,
566-
"Using AES-GCM authentication tags of less than 128 bits without "
567-
"specifying the authTagLength option when initializing decryption "
568-
"is deprecated.",
569-
"DEP0182")
570-
.IsNothing())
571-
return;
572-
}
573-
574565
cipher->auth_tag_len_ = tag_len;
575566
CHECK_LE(cipher->auth_tag_len_, ncrypto::Cipher::MAX_AUTH_TAG_LENGTH);
576567

test/parallel/test-crypto-gcm-implicit-short-tag.js

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,16 @@ const common = require('../common');
33
if (!common.hasCrypto)
44
common.skip('missing crypto');
55

6+
const assert = require('assert');
67
const { createDecipheriv, randomBytes } = require('crypto');
78

8-
common.expectWarning({
9-
DeprecationWarning: [
10-
['Using AES-GCM authentication tags of less than 128 bits without ' +
11-
'specifying the authTagLength option when initializing decryption is ' +
12-
'deprecated.',
13-
'DEP0182'],
14-
]
15-
});
16-
179
const key = randomBytes(32);
1810
const iv = randomBytes(16);
19-
const tag = randomBytes(12);
20-
createDecipheriv('aes-256-gcm', key, iv).setAuthTag(tag);
11+
for (let tagLength = 0; tagLength < 16; tagLength++) {
12+
const tag = randomBytes(tagLength);
13+
assert.throws(() => {
14+
createDecipheriv('aes-256-gcm', key, iv).setAuthTag(tag);
15+
}, {
16+
message: `Invalid authentication tag length: ${tagLength}`,
17+
});
18+
}

0 commit comments

Comments
 (0)