From 9943718a12ad850fa59d94c8d9b906ae6d8fd1c0 Mon Sep 17 00:00:00 2001 From: Shigeki Ohtsu Date: Tue, 20 Jun 2017 23:44:53 +0900 Subject: [PATCH 1/2] crypto: warn if counter mode used in createCipher `crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. --- doc/api/crypto.md | 3 ++- src/node_crypto.cc | 8 ++++++++ test/parallel/test-crypto-cipher-decipher.js | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 07245e8cdc1075..4808ed599f8996 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -1198,7 +1198,8 @@ rapidly. In line with OpenSSL's recommendation to use pbkdf2 instead of [`EVP_BytesToKey`][] it is recommended that developers derive a key and IV on their own using [`crypto.pbkdf2()`][] and to use [`crypto.createCipheriv()`][] -to create the `Cipher` object. +to create the `Cipher` object. A warning is emitted when counter mode (e.g. CTR, +GCM or CCM) is used in `crypto.createCipher()` in order to avoid IV reuse. ### crypto.createCipheriv(algorithm, key, iv) - `algorithm` {string} diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 664bf1a72c7e8c..fa7b3c8ec37f8f 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -3340,6 +3340,14 @@ void CipherBase::Init(const char* cipher_type, EVP_CIPHER_CTX_init(&ctx_); const bool encrypt = (kind_ == kCipher); EVP_CipherInit_ex(&ctx_, cipher, nullptr, nullptr, nullptr, encrypt); + + int mode = EVP_CIPHER_CTX_mode(&ctx_); + if (encrypt && (mode == EVP_CIPH_CTR_MODE || mode == EVP_CIPH_GCM_MODE || + mode == EVP_CIPH_CCM_MODE)) { + ProcessEmitWarning(env(), "Use Cipheriv for counter mode of %s", + cipher_type); + } + if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) { EVP_CIPHER_CTX_cleanup(&ctx_); return env()->ThrowError("Invalid key length"); diff --git a/test/parallel/test-crypto-cipher-decipher.js b/test/parallel/test-crypto-cipher-decipher.js index 0104341653f7f5..336ab3a07ba42e 100644 --- a/test/parallel/test-crypto-cipher-decipher.js +++ b/test/parallel/test-crypto-cipher-decipher.js @@ -155,6 +155,9 @@ testCipher2(Buffer.from('0123456789abcdef')); const aadbuf = Buffer.from('aadbuf'); const data = Buffer.from('test-crypto-cipher-decipher'); + common.expectWarning('Warning', + 'Use Cipheriv for counter mode of aes-256-gcm'); + const cipher = crypto.createCipher('aes-256-gcm', key); cipher.setAAD(aadbuf); cipher.setAutoPadding(); From ae7dbb1ca5144df33115542e0baf4cf9e2ee1ed3 Mon Sep 17 00:00:00 2001 From: Shigeki Ohtsu Date: Tue, 22 Aug 2017 02:03:49 +0900 Subject: [PATCH 2/2] crypto: stronger description for IV reuse --- doc/api/crypto.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 4808ed599f8996..56c196ed23ec98 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -1198,8 +1198,11 @@ rapidly. In line with OpenSSL's recommendation to use pbkdf2 instead of [`EVP_BytesToKey`][] it is recommended that developers derive a key and IV on their own using [`crypto.pbkdf2()`][] and to use [`crypto.createCipheriv()`][] -to create the `Cipher` object. A warning is emitted when counter mode (e.g. CTR, -GCM or CCM) is used in `crypto.createCipher()` in order to avoid IV reuse. +to create the `Cipher` object. Users should not use ciphers with counter mode +(e.g. CTR, GCM or CCM) in `crypto.createCipher()`. A warning is emitted when +they are used in order to avoid the risk of IV reuse that causes +vulnerabilities. For the case when IV is reused in GCM, see [Nonce-Disrespecting +Adversaries][] for details. ### crypto.createCipheriv(algorithm, key, iv) - `algorithm` {string} @@ -2241,6 +2244,7 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL. [HTML5's `keygen` element]: http://www.w3.org/TR/html5/forms.html#the-keygen-element [NIST SP 800-131A]: http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf [NIST SP 800-132]: http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf +[Nonce-Disrespecting Adversaries]: https://github.com/nonce-disrespect/nonce-disrespect [OpenSSL's SPKAC implementation]: https://www.openssl.org/docs/man1.0.2/apps/spkac.html [RFC 2412]: https://www.rfc-editor.org/rfc/rfc2412.txt [RFC 3526]: https://www.rfc-editor.org/rfc/rfc3526.txt