ecl_unittest.cc (4545B)
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 7 #include <stdint.h> 8 9 #include "blapi.h" 10 #include "nss_scoped_ptrs.h" 11 #include "secerr.h" 12 13 namespace nss_test { 14 15 class ECLTest : public ::testing::Test { 16 protected: 17 ECCurveName GetCurveName(std::string name) { 18 if (name == "P256") return ECCurve_NIST_P256; 19 if (name == "P384") return ECCurve_NIST_P384; 20 if (name == "P521") return ECCurve_NIST_P521; 21 return ECCurve_pastLastCurve; 22 } 23 std::vector<uint8_t> hexStringToBytes(std::string s) { 24 std::vector<uint8_t> bytes; 25 for (size_t i = 0; i < s.length(); i += 2) { 26 bytes.push_back(std::stoul(s.substr(i, 2), nullptr, 16)); 27 } 28 return bytes; 29 } 30 std::string bytesToHexString(std::vector<uint8_t> bytes) { 31 std::stringstream s; 32 for (auto b : bytes) { 33 s << std::setfill('0') << std::setw(2) << std::uppercase << std::hex 34 << static_cast<int>(b); 35 } 36 return s.str(); 37 } 38 void ecName2params(const std::string curve, SECItem *params) { 39 SECOidData *oidData = nullptr; 40 41 switch (GetCurveName(curve)) { 42 case ECCurve_NIST_P256: 43 oidData = SECOID_FindOIDByTag(SEC_OID_ANSIX962_EC_PRIME256V1); 44 break; 45 case ECCurve_NIST_P384: 46 oidData = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP384R1); 47 break; 48 case ECCurve_NIST_P521: 49 oidData = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP521R1); 50 break; 51 default: 52 FAIL(); 53 } 54 ASSERT_NE(oidData, nullptr); 55 56 if (SECITEM_AllocItem(nullptr, params, (2 + oidData->oid.len)) == nullptr) { 57 FAIL() << "Couldn't allocate memory for OID."; 58 } 59 params->data[0] = SEC_ASN1_OBJECT_ID; 60 params->data[1] = oidData->oid.len; 61 memcpy(params->data + 2, oidData->oid.data, oidData->oid.len); 62 } 63 64 void TestECDH_Derive(const std::string p, const std::string secret, 65 const std::string group_name, const std::string result, 66 const SECStatus expected_status) { 67 ECParams ecParams = {0}; 68 ScopedSECItem ecEncodedParams(SECITEM_AllocItem(nullptr, nullptr, 0U)); 69 ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); 70 71 ASSERT_TRUE(arena && ecEncodedParams); 72 73 ecName2params(group_name, ecEncodedParams.get()); 74 EC_FillParams(arena.get(), ecEncodedParams.get(), &ecParams); 75 76 std::vector<uint8_t> p_bytes = hexStringToBytes(p); 77 ASSERT_GT(p_bytes.size(), 0U); 78 SECItem public_value = {siBuffer, p_bytes.data(), 79 static_cast<unsigned int>(p_bytes.size())}; 80 81 std::vector<uint8_t> secret_bytes = hexStringToBytes(secret); 82 ASSERT_GT(secret_bytes.size(), 0U); 83 SECItem secret_value = {siBuffer, secret_bytes.data(), 84 static_cast<unsigned int>(secret_bytes.size())}; 85 86 ScopedSECItem derived_secret(SECITEM_AllocItem(nullptr, nullptr, 0U)); 87 88 SECStatus rv = ECDH_Derive(&public_value, &ecParams, &secret_value, false, 89 derived_secret.get()); 90 ASSERT_EQ(expected_status, rv); 91 if (expected_status != SECSuccess) { 92 // Abort when we expect an error. 93 return; 94 } 95 96 std::string derived_result = bytesToHexString(std::vector<uint8_t>( 97 derived_secret->data, derived_secret->data + derived_secret->len)); 98 std::cout << "derived secret: " << derived_result << std::endl; 99 EXPECT_EQ(derived_result, result); 100 } 101 }; 102 103 TEST_F(ECLTest, TestECDH_DeriveP256) { 104 TestECDH_Derive( 105 "045ce5c643dffa402bc1837bbcbc223e51d06f20200470d341adfa9deed1bba10e850a16" 106 "368b673732a5c220a778990b22a0e74cdc3b22c7410b9dd552a5635497", 107 "971", "P256", "0", SECFailure); 108 } 109 TEST_F(ECLTest, TestECDH_DeriveP521) { 110 TestECDH_Derive( 111 "04" 112 "00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b" 113 "5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66" 114 "011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee" 115 "72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 116 "01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa5186" 117 "8783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863f7", 118 "P521", 119 "01BC33425E72A12779EACB2EDCC5B63D1281F7E86DBC7BF99A7ABD0CFE367DE4666D6EDB" 120 "B8525BFFE5222F0702C3096DEC0884CE572F5A15C423FDF44D01DD99C61D", 121 SECSuccess); 122 } 123 124 } // namespace nss_test