diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md
index 0b6dfa65bd1eee..bba4b8663d2d4c 100644
--- a/doc/api/deprecations.md
+++ b/doc/api/deprecations.md
@@ -807,6 +807,18 @@ Importing assert directly is not recommended as the exposed functions will use
loose equality checks. Use `require('assert').strict` instead. The API is the
same as the legacy assert but it will always use strict equality checks.
+
+### DEP0090: Invalid GCM authentication tag lengths
+
+Type: Runtime
+
+Node.js supports all GCM authentication tag lengths which are accepted by
+OpenSSL when calling [`decipher.setAuthTag()`][]. This behavior will change in
+a future version at which point only authentication tag lengths of 128, 120,
+112, 104, 96, 64, and 32 bits will be allowed. Authentication tags whose length
+is not included in this list will be considered invalid in compliance with
+[NIST SP 800-38D][].
+
[`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_class_method_buffer_allocunsafeslow_size
[`Buffer.from(array)`]: buffer.html#buffer_class_method_buffer_from_array
[`Buffer.from(buffer)`]: buffer.html#buffer_class_method_buffer_from_buffer
@@ -821,6 +833,7 @@ same as the legacy assert but it will always use strict equality checks.
[`console.log()`]: console.html#console_console_log_data_args
[`crypto.createCredentials()`]: crypto.html#crypto_crypto_createcredentials_details
[`crypto.pbkdf2()`]: crypto.html#crypto_crypto_pbkdf2_password_salt_iterations_keylen_digest_callback
+[`decipher.setAuthTag()`]: crypto.html#crypto_decipher_setauthtag_buffer
[`domain`]: domain.html
[`ecdh.setPublicKey()`]: crypto.html#crypto_ecdh_setpublickey_publickey_encoding
[`emitter.listenerCount(eventName)`]: events.html#events_emitter_listenercount_eventname
@@ -871,4 +884,5 @@ same as the legacy assert but it will always use strict equality checks.
[alloc_unsafe_size]: buffer.html#buffer_class_method_buffer_allocunsafe_size
[from_arraybuffer]: buffer.html#buffer_class_method_buffer_from_arraybuffer_byteoffset_length
[from_string_encoding]: buffer.html#buffer_class_method_buffer_from_string_encoding
+[NIST SP 800-38D]: http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
[`REPLServer.clearBufferedCommand()`]: repl.html#repl_replserver_clearbufferedcommand
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index d512266bffdb37..b572c90aa50037 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -3157,10 +3157,11 @@ void CipherBase::SetAuthTag(const FunctionCallbackInfo& args) {
// Restrict GCM tag lengths according to NIST 800-38d, page 9.
unsigned int tag_len = Buffer::Length(args[0]);
if (tag_len > 16 || (tag_len < 12 && tag_len != 8 && tag_len != 4)) {
- ProcessEmitWarning(cipher->env(),
- "Permitting authentication tag lengths of %u bytes is deprecated. "
- "Valid GCM tag lengths are 4, 8, 12, 13, 14, 15, 16.",
- tag_len);
+ char msg[125];
+ snprintf(msg, sizeof(msg),
+ "Permitting authentication tag lengths of %u bytes is deprecated. "
+ "Valid GCM tag lengths are 4, 8, 12, 13, 14, 15, 16.", tag_len);
+ ProcessEmitDeprecationWarning(cipher->env(), msg, "DEP0090");
}
// Note: we don't use std::max() here to work around a header conflict.
diff --git a/test/parallel/test-crypto-authenticated.js b/test/parallel/test-crypto-authenticated.js
index 221009cb4a7a25..384044210d5b85 100644
--- a/test/parallel/test-crypto-authenticated.js
+++ b/test/parallel/test-crypto-authenticated.js
@@ -335,13 +335,17 @@ const errMessages = {
const ciphers = crypto.getCiphers();
-common.expectWarning('Warning', (common.hasFipsCrypto ? [] : [
- 'Use Cipheriv for counter mode of aes-192-gcm'
-]).concat(
- [0, 1, 2, 6, 9, 10, 11, 17]
+const expectedWarnings = common.hasFipsCrypto ?
+ [] : ['Use Cipheriv for counter mode of aes-192-gcm'];
+
+const expectedDeprecationWarnings = [0, 1, 2, 6, 9, 10, 11, 17]
.map((i) => `Permitting authentication tag lengths of ${i} bytes is ` +
- 'deprecated. Valid GCM tag lengths are 4, 8, 12, 13, 14, 15, 16.')
-));
+ 'deprecated. Valid GCM tag lengths are 4, 8, 12, 13, 14, 15, 16.');
+
+common.expectWarning({
+ Warning: expectedWarnings,
+ DeprecationWarning: expectedDeprecationWarnings
+});
for (const test of TEST_CASES) {
if (!ciphers.includes(test.algo)) {