From d14d6ae74514b89f548aa7886503a2facc23fc44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Wed, 3 Apr 2024 14:52:51 +0100 Subject: [PATCH] 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 --- doc/api/crypto.md | 5 +++++ doc/api/deprecations.md | 19 +++++++++++++++++ src/crypto/crypto_cipher.cc | 13 ++++++++++++ .../test-crypto-gcm-decipheriv-short-tag.js | 21 +++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 test/parallel/test-crypto-gcm-decipheriv-short-tag.js diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 8b0ca04b486600..44a4e249759b3a 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -891,6 +891,11 @@ When passing a string as the `buffer`, please consider + +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 diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index 8cc2b1786c98b9..fae5b608062422 100644 --- a/src/crypto/crypto_cipher.cc +++ b/src/crypto/crypto_cipher.cc @@ -697,6 +697,19 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo& 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_)); diff --git a/test/parallel/test-crypto-gcm-decipheriv-short-tag.js b/test/parallel/test-crypto-gcm-decipheriv-short-tag.js new file mode 100644 index 00000000000000..0776506bb63523 --- /dev/null +++ b/test/parallel/test-crypto-gcm-decipheriv-short-tag.js @@ -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);