tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pk11_symkey_unittest.cc (5659B)


      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 namespace nss_test {
     15 
     16 uint8_t kKeyData[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
     17 SECItem kFull = {siBuffer, (unsigned char *)kKeyData, 16};
     18 SECItem kLeftHalf = {siBuffer, (unsigned char *)kKeyData, 8};
     19 SECItem kRightHalf = {siBuffer, (unsigned char *)kKeyData + 8, 8};
     20 
     21 class Pkcs11SymKeyTest : public ::testing::Test {
     22 protected:
     23  PK11SymKey *ImportSymKey(PK11SlotInfo *slot, SECItem *key_data) {
     24    PK11SymKey *out = PK11_ImportSymKey(slot, CKM_NULL, PK11_OriginUnwrap,
     25                                        CKA_DERIVE, key_data, nullptr);
     26    EXPECT_NE(nullptr, out);
     27    return out;
     28  }
     29 
     30  void CheckKeyData(SECItem &expected, PK11SymKey *actual) {
     31    ASSERT_NE(nullptr, actual);
     32 
     33    SECStatus rv = PK11_ExtractKeyValue(actual);
     34    ASSERT_EQ(SECSuccess, rv);
     35 
     36    SECItem *keyData = PK11_GetKeyData(actual);
     37    ASSERT_NE(nullptr, keyData);
     38    ASSERT_NE(nullptr, keyData->data);
     39    ASSERT_EQ(expected.len, keyData->len);
     40    ASSERT_EQ(0, memcmp(expected.data, keyData->data, keyData->len));
     41  }
     42 
     43  void SetSensitive(PK11SymKey *key) {
     44    ASSERT_NE(nullptr, key);
     45 
     46    CK_BBOOL cktrue = CK_TRUE;
     47    SECItem attrValue = {siBuffer, &cktrue, sizeof(CK_BBOOL)};
     48    EXPECT_EQ(SECSuccess, PK11_WriteRawAttribute(PK11_TypeSymKey, key,
     49                                                 CKA_SENSITIVE, &attrValue));
     50  }
     51 
     52  void CheckIsSensitive(PK11SymKey *key) {
     53    ASSERT_NE(nullptr, key);
     54 
     55    StackSECItem attrValue;
     56    ASSERT_EQ(SECSuccess, PK11_ReadRawAttribute(PK11_TypeSymKey, key,
     57                                                CKA_SENSITIVE, &attrValue));
     58    ASSERT_EQ(attrValue.len, sizeof(CK_BBOOL));
     59    EXPECT_EQ(*(CK_BBOOL *)attrValue.data, CK_TRUE);
     60  }
     61 
     62  void SetNotExtractable(PK11SymKey *key) {
     63    ASSERT_NE(nullptr, key);
     64 
     65    CK_BBOOL ckfalse = CK_FALSE;
     66    SECItem attrValue = {siBuffer, &ckfalse, sizeof(CK_BBOOL)};
     67    EXPECT_EQ(SECSuccess, PK11_WriteRawAttribute(PK11_TypeSymKey, key,
     68                                                 CKA_EXTRACTABLE, &attrValue));
     69  }
     70 
     71  void CheckIsNotExtractable(PK11SymKey *key) {
     72    ASSERT_NE(nullptr, key);
     73 
     74    StackSECItem attrValue;
     75    ASSERT_EQ(SECSuccess, PK11_ReadRawAttribute(PK11_TypeSymKey, key,
     76                                                CKA_EXTRACTABLE, &attrValue));
     77    ASSERT_EQ(attrValue.len, sizeof(CK_BBOOL));
     78    EXPECT_EQ(*(CK_BBOOL *)attrValue.data, CK_FALSE);
     79  }
     80 };
     81 
     82 TEST_F(Pkcs11SymKeyTest, ConcatSymKeyTest) {
     83  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
     84  ASSERT_NE(nullptr, slot);
     85 
     86  ScopedPK11SymKey left(ImportSymKey(slot.get(), &kLeftHalf));
     87 
     88  ScopedPK11SymKey right(ImportSymKey(slot.get(), &kRightHalf));
     89 
     90  ScopedPK11SymKey key(
     91      PK11_ConcatSymKeys(left.get(), right.get(), CKM_HKDF_DERIVE, CKA_DERIVE));
     92  CheckKeyData(kFull, key.get());
     93 }
     94 
     95 // Test that the derived key is sensitive if either input is.
     96 TEST_F(Pkcs11SymKeyTest, SensitiveConcatSymKeyTest) {
     97  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
     98  ASSERT_NE(nullptr, slot);
     99 
    100  ScopedPK11SymKey left(ImportSymKey(slot.get(), &kLeftHalf));
    101  SetSensitive(left.get());
    102 
    103  ScopedPK11SymKey right(ImportSymKey(slot.get(), &kRightHalf));
    104 
    105  ScopedPK11SymKey key(
    106      PK11_ConcatSymKeys(left.get(), right.get(), CKM_HKDF_DERIVE, CKA_DERIVE));
    107  CheckIsSensitive(key.get());
    108 
    109  // Again with left and right swapped
    110  ScopedPK11SymKey key2(
    111      PK11_ConcatSymKeys(right.get(), left.get(), CKM_HKDF_DERIVE, CKA_DERIVE));
    112  CheckIsSensitive(key2.get());
    113 }
    114 
    115 // Test that the derived key is extractable if either input is.
    116 TEST_F(Pkcs11SymKeyTest, NotExtractableConcatSymKeyTest) {
    117  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
    118  ASSERT_NE(nullptr, slot);
    119 
    120  ScopedPK11SymKey left(ImportSymKey(slot.get(), &kLeftHalf));
    121  SetNotExtractable(left.get());
    122 
    123  ScopedPK11SymKey right(ImportSymKey(slot.get(), &kRightHalf));
    124 
    125  ScopedPK11SymKey key(
    126      PK11_ConcatSymKeys(left.get(), right.get(), CKM_HKDF_DERIVE, CKA_DERIVE));
    127  CheckIsNotExtractable(key.get());
    128 
    129  ScopedPK11SymKey key2(
    130      PK11_ConcatSymKeys(right.get(), left.get(), CKM_HKDF_DERIVE, CKA_DERIVE));
    131  CheckIsNotExtractable(key2.get());
    132 }
    133 
    134 // Test that keys can be concatenated on the key slot.
    135 TEST_F(Pkcs11SymKeyTest, KeySlotConcatSymKeyTest) {
    136  ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
    137  ASSERT_NE(nullptr, slot);
    138 
    139  ScopedPK11SymKey left(ImportSymKey(slot.get(), &kLeftHalf));
    140 
    141  ScopedPK11SymKey right(ImportSymKey(slot.get(), &kRightHalf));
    142 
    143  ScopedPK11SymKey key(
    144      PK11_ConcatSymKeys(left.get(), right.get(), CKM_HKDF_DERIVE, CKA_DERIVE));
    145  CheckKeyData(kFull, key.get());
    146 }
    147 
    148 // Test that keys in different slots are moved to the same slot for derivation.
    149 // The PK11SymKey.data fields are set in PK11_ImportSymKey, so this just
    150 // re-imports the key data.
    151 TEST_F(Pkcs11SymKeyTest, CrossSlotConcatSymKeyTest) {
    152  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
    153  ASSERT_NE(nullptr, slot);
    154 
    155  ScopedPK11SlotInfo slot2(PK11_GetInternalKeySlot());
    156  ASSERT_NE(nullptr, slot2);
    157 
    158  EXPECT_NE(slot, slot2);
    159 
    160  ScopedPK11SymKey left(ImportSymKey(slot.get(), &kLeftHalf));
    161 
    162  ScopedPK11SymKey right(ImportSymKey(slot2.get(), &kRightHalf));
    163 
    164  ScopedPK11SymKey key(
    165      PK11_ConcatSymKeys(left.get(), right.get(), CKM_HKDF_DERIVE, CKA_DERIVE));
    166  CheckKeyData(kFull, key.get());
    167 }
    168 
    169 }  // namespace nss_test