Bug 1488622 - land NSS 2c85f81f9b5e UPGRADE_NSS_RELEASE, r=me
authorJ.C. Jones <jjones@mozilla.com>
Sat, 22 Sep 2018 17:04:35 -0700
changeset 493565 b106fa22e262c94ba29708ada8ad03347f4cc1a4
parent 493557 5c2a8331f82c11037b458f2733ae9813fa16f906
child 493566 42f0da322d14090133d4428764dd38125ec5016c
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs1488622
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1488622 - land NSS 2c85f81f9b5e UPGRADE_NSS_RELEASE, r=me
security/nss/TAG-INFO
security/nss/coreconf/coreconf.dep
security/nss/gtests/pk11_gtest/pk11_cipherop_unittest.cc
security/nss/gtests/pk11_gtest/pk11_gtest.gyp
security/nss/lib/freebl/ctr.c
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-fe738aae0bcc
+2c85f81f9b5e
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,8 +5,9 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
+
new file mode 100644
--- /dev/null
+++ b/security/nss/gtests/pk11_gtest/pk11_cipherop_unittest.cc
@@ -0,0 +1,79 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include "gtest/gtest.h"
+
+#include <assert.h>
+#include <limits.h>
+#include <prinit.h>
+#include <nss.h>
+#include <pk11pub.h>
+
+static const size_t kKeyLen = 128/8;
+
+namespace nss_test {
+
+//
+// The ciper tests using the bltest command cover a great deal of testing.
+// However, Bug 1489691 revealed a corner case which is covered here.
+// This test will make multiple calls to PK11_CipherOp using the same
+// cipher context with data that is not cipher block aligned.
+//
+
+static SECStatus GetBytes(PK11Context *ctx, uint8_t *bytes, size_t len)
+{
+  std::vector<uint8_t> in(len, 0);
+
+  int outlen;
+  SECStatus rv = PK11_CipherOp(ctx, bytes, &outlen, len, &in[0], len);
+  if (static_cast<size_t>(outlen) != len) {
+    return SECFailure;
+  }
+  return rv;
+}
+
+TEST(Pkcs11CipherOp, SingleCtxMultipleUnalignedCipherOps) {
+  PK11SlotInfo* slot;
+  PK11SymKey* key;
+  PK11Context* ctx;
+
+  NSSInitContext* globalctx = NSS_InitContext("", "", "", "", NULL,
+                    NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB |
+                      NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT);
+
+  const CK_MECHANISM_TYPE cipher = CKM_AES_CTR;
+
+  slot = PK11_GetInternalSlot();
+  ASSERT_TRUE(slot);
+
+  // Use arbitrary bytes for the AES key
+  uint8_t key_bytes[kKeyLen];
+  for (size_t i = 0; i < kKeyLen; i++) {
+    key_bytes[i] = i;
+  }
+
+  SECItem keyItem = { siBuffer, key_bytes, kKeyLen };
+
+  // The IV can be all zeros since we only encrypt once with
+  // each AES key.
+  CK_AES_CTR_PARAMS param = { 128, {} };
+  SECItem paramItem = { siBuffer, reinterpret_cast<unsigned char*>(&param), sizeof(CK_AES_CTR_PARAMS) };
+
+  key = PK11_ImportSymKey(slot, cipher, PK11_OriginUnwrap,
+                                        CKA_ENCRYPT, &keyItem, NULL);
+  ctx = PK11_CreateContextBySymKey(cipher, CKA_ENCRYPT, key, &paramItem);
+  ASSERT_TRUE(key);
+  ASSERT_TRUE(ctx);
+
+  uint8_t outbuf[128];
+  ASSERT_EQ(GetBytes(ctx, outbuf, 7), SECSuccess);
+  ASSERT_EQ(GetBytes(ctx, outbuf, 17), SECSuccess);
+
+  PK11_FreeSymKey(key);
+  PK11_FreeSlot(slot);
+  PK11_DestroyContext(ctx, PR_TRUE);
+  NSS_ShutdownContext(globalctx);
+}
+
+}  // namespace nss_test
--- a/security/nss/gtests/pk11_gtest/pk11_gtest.gyp
+++ b/security/nss/gtests/pk11_gtest/pk11_gtest.gyp
@@ -9,16 +9,17 @@
   'targets': [
     {
       'target_name': 'pk11_gtest',
       'type': 'executable',
       'sources': [
         'pk11_aeskeywrap_unittest.cc',
         'pk11_aes_gcm_unittest.cc',
         'pk11_chacha20poly1305_unittest.cc',
+        'pk11_cipherop_unittest.cc',
         'pk11_curve25519_unittest.cc',
         'pk11_ecdsa_unittest.cc',
         'pk11_encrypt_derive_unittest.cc',
         'pk11_pbkdf2_unittest.cc',
         'pk11_prf_unittest.cc',
         'pk11_prng_unittest.cc',
         'pk11_rsapkcs1_unittest.cc',
         'pk11_rsapss_unittest.cc',
--- a/security/nss/lib/freebl/ctr.c
+++ b/security/nss/lib/freebl/ctr.c
@@ -214,25 +214,28 @@ CTR_Update_HW_AES(CTRContext *ctr, unsig
         *outlen += needed;
         inlen -= needed;
         if (inlen == 0) {
             return SECSuccess;
         }
         PORT_Assert(ctr->bufPtr == blocksize);
     }
 
-    intel_aes_ctr_worker(((AESContext *)(ctr->context))->Nr)(
-        ctr, outbuf, outlen, maxout, inbuf, inlen, blocksize);
-    /* XXX intel_aes_ctr_worker should set *outlen. */
-    PORT_Assert(*outlen == 0);
-    fullblocks = (inlen / blocksize) * blocksize;
-    *outlen += fullblocks;
-    outbuf += fullblocks;
-    inbuf += fullblocks;
-    inlen -= fullblocks;
+    if (inlen >= blocksize) {
+        rv = intel_aes_ctr_worker(((AESContext *)(ctr->context))->Nr)(
+                 ctr, outbuf, outlen, maxout, inbuf, inlen, blocksize);
+        if (rv != SECSuccess) {
+            return SECFailure;
+        }
+        fullblocks = (inlen / blocksize) * blocksize;
+        *outlen += fullblocks;
+        outbuf += fullblocks;
+        inbuf += fullblocks;
+        inlen -= fullblocks;
+    }
 
     if (inlen == 0) {
         return SECSuccess;
     }
     rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
                         ctr->counter, blocksize, blocksize);
     ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
     if (rv != SECSuccess) {