pk11_cipherop_unittest.cc (4177B)
1 // This Source Code Form is subject to the terms of the Mozilla Public 2 // License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 // You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 #include "gtest/gtest.h" 6 #include "nss_scoped_ptrs.h" 7 8 #include <assert.h> 9 #include <limits.h> 10 #include <prinit.h> 11 #include <nss.h> 12 #include <pk11pub.h> 13 14 static const size_t kKeyLen = 128 / 8; 15 16 namespace nss_test { 17 18 // 19 // The ciper tests using the bltest command cover a great deal of testing. 20 // However, Bug 1489691 revealed a corner case which is covered here. 21 // This test will make multiple calls to PK11_CipherOp using the same 22 // cipher context with data that is not cipher block aligned. 23 // 24 25 static SECStatus GetBytes(const ScopedPK11Context& ctx, size_t len) { 26 std::vector<uint8_t> in(len, 0); 27 28 uint8_t outbuf[128]; 29 PORT_Assert(len <= sizeof(outbuf)); 30 int outlen; 31 SECStatus rv = PK11_CipherOp(ctx.get(), outbuf, &outlen, len, in.data(), len); 32 if (static_cast<size_t>(outlen) != len) { 33 EXPECT_EQ(rv, SECFailure); 34 } 35 return rv; 36 } 37 38 TEST(Pkcs11CipherOp, SingleCtxMultipleUnalignedCipherOps) { 39 ScopedNSSInitContext globalctx( 40 NSS_InitContext("", "", "", "", NULL, 41 NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | 42 NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT)); 43 ASSERT_TRUE(globalctx); 44 45 const CK_MECHANISM_TYPE cipher = CKM_AES_CTR; 46 47 ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); 48 ASSERT_TRUE(slot); 49 50 // Use arbitrary bytes for the AES key 51 uint8_t key_bytes[kKeyLen]; 52 for (size_t i = 0; i < kKeyLen; i++) { 53 key_bytes[i] = i; 54 } 55 56 SECItem keyItem = {siBuffer, key_bytes, kKeyLen}; 57 58 // The IV can be all zeros since we only encrypt once with 59 // each AES key. 60 CK_AES_CTR_PARAMS param = {128, {}}; 61 SECItem paramItem = {siBuffer, reinterpret_cast<unsigned char*>(¶m), 62 sizeof(CK_AES_CTR_PARAMS)}; 63 64 ScopedPK11SymKey key(PK11_ImportSymKey(slot.get(), cipher, PK11_OriginUnwrap, 65 CKA_ENCRYPT, &keyItem, NULL)); 66 ASSERT_TRUE(key); 67 ScopedPK11Context ctx( 68 PK11_CreateContextBySymKey(cipher, CKA_ENCRYPT, key.get(), ¶mItem)); 69 ASSERT_TRUE(ctx); 70 71 ASSERT_EQ(GetBytes(ctx, 7), SECSuccess); 72 ASSERT_EQ(GetBytes(ctx, 17), SECSuccess); 73 } 74 75 // A context can't be used for Chacha20 as the underlying 76 // PK11_CipherOp operation is calling the C_EncryptUpdate function for 77 // which multi-part is disabled for ChaCha20 in counter mode. 78 void ChachaMulti(CK_MECHANISM_TYPE cipher, SECItem* param) { 79 ScopedNSSInitContext globalctx( 80 NSS_InitContext("", "", "", "", NULL, 81 NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | 82 NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT)); 83 ASSERT_TRUE(globalctx); 84 85 ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); 86 ASSERT_TRUE(slot); 87 88 // Use arbitrary bytes for the ChaCha20 key and IV 89 uint8_t key_bytes[32]; 90 for (size_t i = 0; i < 32; i++) { 91 key_bytes[i] = i; 92 } 93 SECItem keyItem = {siBuffer, key_bytes, sizeof(key_bytes)}; 94 95 ScopedPK11SymKey key(PK11_ImportSymKey(slot.get(), cipher, PK11_OriginUnwrap, 96 CKA_ENCRYPT, &keyItem, NULL)); 97 ASSERT_TRUE(key); 98 ScopedSECItem param_item(PK11_ParamFromIV(cipher, param)); 99 ASSERT_TRUE(param_item); 100 ScopedPK11Context ctx(PK11_CreateContextBySymKey( 101 cipher, CKA_ENCRYPT, key.get(), param_item.get())); 102 ASSERT_TRUE(ctx); 103 104 ASSERT_EQ(GetBytes(ctx, 7), SECFailure); 105 } 106 107 TEST(Pkcs11CipherOp, ChachaMultiLegacy) { 108 uint8_t iv_bytes[16]; 109 for (size_t i = 0; i < 16; i++) { 110 iv_bytes[i] = i; 111 } 112 SECItem param_item = {siBuffer, iv_bytes, sizeof(iv_bytes)}; 113 114 ChachaMulti(CKM_NSS_CHACHA20_CTR, ¶m_item); 115 } 116 117 TEST(Pkcs11CipherOp, ChachaMulti) { 118 uint8_t iv_bytes[16]; 119 for (size_t i = 0; i < 16; i++) { 120 iv_bytes[i] = i; 121 } 122 CK_CHACHA20_PARAMS chacha_params = {iv_bytes, 32, iv_bytes + 4, 96}; 123 SECItem param_item = {siBuffer, reinterpret_cast<uint8_t*>(&chacha_params), 124 sizeof(chacha_params)}; 125 126 ChachaMulti(CKM_CHACHA20, ¶m_item); 127 } 128 129 } // namespace nss_test