crypto: deprecate implicitly shortened GCM tags
This introduces a doc-only deprecation of using GCM authentication tags that are shorter than the cipher's block size, unless the user specified the authTagLength option. Refs: https://github.com/nodejs/node/issues/52327 PR-URL: https://github.com/nodejs/node/pull/52345 Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
c82f3c9e80
commit
8f61b658de
@ -891,6 +891,11 @@ When passing a string as the `buffer`, please consider
|
||||
<!-- YAML
|
||||
added: v1.0.0
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/52345
|
||||
description: Using GCM tag lengths other than 128 bits without specifying
|
||||
the `authTagLength` option when creating `decipher` is
|
||||
deprecated.
|
||||
- version: v15.0.0
|
||||
pr-url: https://github.com/nodejs/node/pull/35093
|
||||
description: The buffer argument can be a string or ArrayBuffer and is
|
||||
|
@ -3619,6 +3619,25 @@ Calling `Hmac` class directly with `Hmac()` or `new Hmac()` is
|
||||
deprecated due to being internals, not intended for public use.
|
||||
Please use the [`crypto.createHmac()`][] method to create Hmac instances.
|
||||
|
||||
### DEP0182: Short GCM authentication tags without explicit `authTagLength`
|
||||
|
||||
<!-- YAML
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/52345
|
||||
description: Documentation-only deprecation.
|
||||
-->
|
||||
|
||||
Type: Documentation-only (supports [`--pending-deprecation`][])
|
||||
|
||||
Applications that intend to use authentication tags that are shorter than the
|
||||
default authentication tag length should set the `authTagLength` option of the
|
||||
[`crypto.createDecipheriv()`][] function to the appropriate length.
|
||||
|
||||
For ciphers in GCM mode, the [`decipher.setAuthTag()`][] function accepts
|
||||
authentication tags of any valid length (see [DEP0090](#DEP0090)). This behavior
|
||||
is deprecated to better align with recommendations per [NIST SP 800-38D][].
|
||||
|
||||
[NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
|
||||
[RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3
|
||||
[RFC 8247 Section 2.4]: https://www.rfc-editor.org/rfc/rfc8247#section-2.4
|
||||
|
@ -697,6 +697,19 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
|
||||
env, "Invalid authentication tag length: %u", tag_len);
|
||||
}
|
||||
|
||||
if (mode == EVP_CIPH_GCM_MODE && cipher->auth_tag_len_ == kNoAuthTagLength &&
|
||||
tag_len != 16 && env->options()->pending_deprecation &&
|
||||
env->EmitProcessEnvWarning()) {
|
||||
if (ProcessEmitDeprecationWarning(
|
||||
env,
|
||||
"Using AES-GCM authentication tags of less than 128 bits without "
|
||||
"specifying the authTagLength option when initializing decryption "
|
||||
"is deprecated.",
|
||||
"DEP0182")
|
||||
.IsNothing())
|
||||
return;
|
||||
}
|
||||
|
||||
cipher->auth_tag_len_ = tag_len;
|
||||
cipher->auth_tag_state_ = kAuthTagKnown;
|
||||
CHECK_LE(cipher->auth_tag_len_, sizeof(cipher->auth_tag_));
|
||||
|
@ -659,12 +659,12 @@ function _expectWarning(name, expected, code) {
|
||||
expected = [[expected, code]];
|
||||
} else if (!Array.isArray(expected)) {
|
||||
expected = Object.entries(expected).map(([a, b]) => [b, a]);
|
||||
} else if (!(Array.isArray(expected[0]))) {
|
||||
} else if (expected.length !== 0 && !Array.isArray(expected[0])) {
|
||||
expected = [[expected[0], expected[1]]];
|
||||
}
|
||||
// Deprecation codes are mandatory, everything else is not.
|
||||
if (name === 'DeprecationWarning') {
|
||||
expected.forEach(([_, code]) => assert(code, expected));
|
||||
expected.forEach(([_, code]) => assert(code, `Missing deprecation code: ${expected}`));
|
||||
}
|
||||
return mustCall((warning) => {
|
||||
const expectedProperties = expected.shift();
|
||||
|
47
test/parallel/test-crypto-gcm-explicit-short-tag.js
Normal file
47
test/parallel/test-crypto-gcm-explicit-short-tag.js
Normal file
@ -0,0 +1,47 @@
|
||||
// Flags: --pending-deprecation
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
if (!common.hasCrypto)
|
||||
common.skip('missing crypto');
|
||||
|
||||
const assert = require('assert');
|
||||
const { createDecipheriv, randomBytes } = require('crypto');
|
||||
|
||||
common.expectWarning({
|
||||
DeprecationWarning: []
|
||||
});
|
||||
|
||||
const key = randomBytes(32);
|
||||
const iv = randomBytes(16);
|
||||
|
||||
{
|
||||
// Full 128-bit tag.
|
||||
|
||||
const tag = randomBytes(16);
|
||||
createDecipheriv('aes-256-gcm', key, iv).setAuthTag(tag);
|
||||
}
|
||||
|
||||
{
|
||||
// Shortened tag with explicit length option.
|
||||
|
||||
const tag = randomBytes(12);
|
||||
createDecipheriv('aes-256-gcm', key, iv, {
|
||||
authTagLength: tag.byteLength
|
||||
}).setAuthTag(tag);
|
||||
}
|
||||
|
||||
{
|
||||
// Shortened tag with explicit but incorrect length option.
|
||||
|
||||
const tag = randomBytes(12);
|
||||
assert.throws(() => {
|
||||
createDecipheriv('aes-256-gcm', key, iv, {
|
||||
authTagLength: 14
|
||||
}).setAuthTag(tag);
|
||||
}, {
|
||||
name: 'TypeError',
|
||||
message: 'Invalid authentication tag length: 12',
|
||||
code: 'ERR_CRYPTO_INVALID_AUTH_TAG'
|
||||
});
|
||||
}
|
21
test/parallel/test-crypto-gcm-implicit-short-tag.js
Normal file
21
test/parallel/test-crypto-gcm-implicit-short-tag.js
Normal file
@ -0,0 +1,21 @@
|
||||
// Flags: --pending-deprecation
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
if (!common.hasCrypto)
|
||||
common.skip('missing crypto');
|
||||
|
||||
const { createDecipheriv, randomBytes } = require('crypto');
|
||||
|
||||
common.expectWarning({
|
||||
DeprecationWarning: [
|
||||
['Using AES-GCM authentication tags of less than 128 bits without ' +
|
||||
'specifying the authTagLength option when initializing decryption is ' +
|
||||
'deprecated.',
|
||||
'DEP0182'],
|
||||
]
|
||||
});
|
||||
|
||||
const key = randomBytes(32);
|
||||
const iv = randomBytes(16);
|
||||
const tag = randomBytes(12);
|
||||
createDecipheriv('aes-256-gcm', key, iv).setAuthTag(tag);
|
Loading…
x
Reference in New Issue
Block a user