Commit 6627d90f authored by Kevin Jacobs's avatar Kevin Jacobs

Bug 1612260 - Add Wycheproof vectors for RSA PKCS1 and PSS signing, PKCS1 and...

Bug 1612260 - Add Wycheproof vectors for RSA PKCS1 and PSS signing, PKCS1 and OEAP decryption. r=bbeurdouche

This patch updates the Wycheproof script to build RSA test vectors (covering PKCS1 decryption/verification, as well as PSS and OAEP) and adds the appropriate test drivers.

Differential Revision: https://phabricator.services.mozilla.com/D69847

--HG--
extra : moz-landing-system : lando
parent f4952cf3
......@@ -74,7 +74,7 @@ const EcdhTestVectorStr kCurve25519Vectors[] = {
false,
false}};
const EcdhTestVectorStr kCurve25519WycheproofVectors[] = {
const EcdhTestVector kCurve25519WycheproofVectors[] = {
// Comment: normal case
{1,
......
......@@ -12,7 +12,7 @@
#include "testvectors_base/test-structs.h"
const EcdhTestVectorStr kP256EcdhWycheproofVectors[] = {
const EcdhTestVector kP256EcdhWycheproofVectors[] = {
// Comment: normal case
// tcID: 1
......
......@@ -12,7 +12,7 @@
#include "testvectors_base/test-structs.h"
const EcdhTestVectorStr kP384EcdhWycheproofVectors[] = {
const EcdhTestVector kP384EcdhWycheproofVectors[] = {
// Comment: normal case
// tcID: 1
......
......@@ -12,7 +12,7 @@
#include "testvectors_base/test-structs.h"
const EcdhTestVectorStr kP521EcdhWycheproofVectors[] = {
const EcdhTestVector kP521EcdhWycheproofVectors[] = {
// Comment: normal case
// tcID: 1
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// kSpki is an RSA public key in an X.509 SubjectPublicKeyInfo.
const uint8_t kSpki[] = {
0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81,
0x89, 0x02, 0x81, 0x81, 0x00, 0xf8, 0xb8, 0x6c, 0x83, 0xb4, 0xbc, 0xd9,
0xa8, 0x57, 0xc0, 0xa5, 0xb4, 0x59, 0x76, 0x8c, 0x54, 0x1d, 0x79, 0xeb,
0x22, 0x52, 0x04, 0x7e, 0xd3, 0x37, 0xeb, 0x41, 0xfd, 0x83, 0xf9, 0xf0,
0xa6, 0x85, 0x15, 0x34, 0x75, 0x71, 0x5a, 0x84, 0xa8, 0x3c, 0xd2, 0xef,
0x5a, 0x4e, 0xd3, 0xde, 0x97, 0x8a, 0xdd, 0xff, 0xbb, 0xcf, 0x0a, 0xaa,
0x86, 0x92, 0xbe, 0xb8, 0x50, 0xe4, 0xcd, 0x6f, 0x80, 0x33, 0x30, 0x76,
0x13, 0x8f, 0xca, 0x7b, 0xdc, 0xec, 0x5a, 0xca, 0x63, 0xc7, 0x03, 0x25,
0xef, 0xa8, 0x8a, 0x83, 0x58, 0x76, 0x20, 0xfa, 0x16, 0x77, 0xd7, 0x79,
0x92, 0x63, 0x01, 0x48, 0x1a, 0xd8, 0x7b, 0x67, 0xf1, 0x52, 0x55, 0x49,
0x4e, 0xd6, 0x6e, 0x4a, 0x5c, 0xd7, 0x7a, 0x37, 0x36, 0x0c, 0xde, 0xdd,
0x8f, 0x44, 0xe8, 0xc2, 0xa7, 0x2c, 0x2b, 0xb5, 0xaf, 0x64, 0x4b, 0x61,
0x07, 0x02, 0x03, 0x01, 0x00, 0x01,
};
// kHash is the SHA-256 hash of {1,2,3,4}.
const uint8_t kHash[] = {
0x9f, 0x64, 0xa7, 0x47, 0xe1, 0xb9, 0x7f, 0x13, 0x1f, 0xab, 0xb6,
0xb4, 0x47, 0x29, 0x6c, 0x9b, 0x6f, 0x02, 0x01, 0xe7, 0x9f, 0xb3,
0xc5, 0x35, 0x6e, 0x6c, 0x77, 0xe8, 0x9b, 0x6a, 0x80, 0x6a,
};
// kSignature is the signature of kHash with RSASSA-PKCS1-v1_5.
const uint8_t kSignature[] = {
0xa5, 0xf0, 0x8a, 0x47, 0x5d, 0x3c, 0xb3, 0xcc, 0xa9, 0x79, 0xaf, 0x4d,
0x8c, 0xae, 0x4c, 0x14, 0xef, 0xc2, 0x0b, 0x34, 0x36, 0xde, 0xf4, 0x3e,
0x3d, 0xbb, 0x4a, 0x60, 0x5c, 0xc8, 0x91, 0x28, 0xda, 0xfb, 0x7e, 0x04,
0x96, 0x7e, 0x63, 0x13, 0x90, 0xce, 0xb9, 0xb4, 0x62, 0x7a, 0xfd, 0x09,
0x3d, 0xc7, 0x67, 0x78, 0x54, 0x04, 0xeb, 0x52, 0x62, 0x6e, 0x24, 0x67,
0xb4, 0x40, 0xfc, 0x57, 0x62, 0xc6, 0xf1, 0x67, 0xc1, 0x97, 0x8f, 0x6a,
0xa8, 0xae, 0x44, 0x46, 0x5e, 0xab, 0x67, 0x17, 0x53, 0x19, 0x3a, 0xda,
0x5a, 0xc8, 0x16, 0x3e, 0x86, 0xd5, 0xc5, 0x71, 0x2f, 0xfc, 0x23, 0x48,
0xd9, 0x0b, 0x13, 0xdd, 0x7b, 0x5a, 0x25, 0x79, 0xef, 0xa5, 0x7b, 0x04,
0xed, 0x44, 0xf6, 0x18, 0x55, 0xe4, 0x0a, 0xe9, 0x57, 0x79, 0x5d, 0xd7,
0x55, 0xa7, 0xab, 0x45, 0x02, 0x97, 0x60, 0x42,
};
// kSignature is an invalid signature of kHash with RSASSA-PKCS1-v1_5 with the
// NULL parameter omitted.
const uint8_t kSignatureInvalid[] = {
0x71, 0x6c, 0x24, 0x4e, 0xc9, 0x9b, 0x19, 0xc7, 0x49, 0x29, 0xb8, 0xd4,
0xfb, 0x26, 0x23, 0xc0, 0x96, 0x18, 0xcd, 0x1e, 0x60, 0xe8, 0x88, 0x94,
0x8c, 0x59, 0xfb, 0x58, 0x5c, 0x61, 0x58, 0x7a, 0xae, 0xcc, 0xeb, 0xee,
0x1e, 0x85, 0x7d, 0x83, 0xa9, 0xdc, 0x6f, 0x4c, 0x34, 0x5c, 0xcb, 0xd9,
0xde, 0x58, 0x76, 0xdf, 0x1f, 0x5e, 0xd4, 0x57, 0x5b, 0xeb, 0xaf, 0x4f,
0x7a, 0xa7, 0x6b, 0x21, 0xf1, 0x0a, 0x96, 0x78, 0xc7, 0xa8, 0x02, 0x7a,
0xc2, 0x06, 0xd3, 0x18, 0x79, 0x72, 0x6b, 0xfe, 0x2d, 0xec, 0xd8, 0x8e,
0x98, 0x86, 0x89, 0xf4, 0x67, 0x14, 0x2b, 0xac, 0x6d, 0xd7, 0x04, 0xd8,
0xab, 0x05, 0xe6, 0x51, 0xf6, 0xee, 0x58, 0x63, 0xef, 0x6a, 0x3e, 0x89,
0x99, 0x2a, 0x1c, 0x10, 0xc2, 0xd0, 0x41, 0x9e, 0x1e, 0x9a, 0x9a, 0x57,
0x32, 0x0f, 0x49, 0xb4, 0x57, 0x37, 0xa4, 0x26,
};
......@@ -12,6 +12,8 @@
#include <string>
#include <vector>
#include "secoidt.h"
#include "pkcs11t.h"
typedef struct AesCbcTestVectorStr {
uint32_t id;
......@@ -64,4 +66,43 @@ typedef struct EcdhTestVectorStr {
bool valid;
} EcdhTestVector;
typedef struct RsaSignatureTestVectorStr {
SECOidTag hash_oid;
uint32_t id;
std::vector<uint8_t> sig;
std::vector<uint8_t> public_key;
std::vector<uint8_t> msg;
bool valid;
} RsaSignatureTestVector;
typedef struct RsaDecryptTestVectorStr {
uint32_t id;
std::vector<uint8_t> msg;
std::vector<uint8_t> ct;
std::vector<uint8_t> priv_key;
bool valid;
} RsaDecryptTestVector;
typedef struct RsaOaepTestVectorStr {
SECOidTag hash_oid;
CK_RSA_PKCS_MGF_TYPE mgf_hash;
uint32_t id;
std::vector<uint8_t> msg;
std::vector<uint8_t> ct;
std::vector<uint8_t> label;
std::vector<uint8_t> priv_key;
bool valid;
} RsaOaepTestVector;
typedef struct RsaPssTestVectorStr {
SECOidTag hash_oid;
CK_RSA_PKCS_MGF_TYPE mgf_hash;
uint32_t id;
unsigned long sLen;
std::vector<uint8_t> sig;
std::vector<uint8_t> public_key;
std::vector<uint8_t> msg;
bool valid;
} RsaPssTestVector;
#endif // test_structs_h__
This diff is collapsed.
......@@ -30,6 +30,7 @@ CPPSRCS = \
pk11_prf_unittest.cc \
pk11_prng_unittest.cc \
pk11_rsaencrypt_unittest.cc \
pk11_rsaoaep_unittest.cc \
pk11_rsapkcs1_unittest.cc \
pk11_rsapss_unittest.cc \
pk11_seed_cbc_unittest.cc \
......
......@@ -35,6 +35,7 @@
'pk11_prf_unittest.cc',
'pk11_prng_unittest.cc',
'pk11_rsaencrypt_unittest.cc',
'pk11_rsaoaep_unittest.cc',
'pk11_rsapkcs1_unittest.cc',
'pk11_rsapss_unittest.cc',
'pk11_seed_cbc_unittest.cc',
......
......@@ -14,8 +14,58 @@
#include "nss_scoped_ptrs.h"
#include "pk11pub.h"
#include "testvectors/rsa_pkcs1_2048_test-vectors.h"
#include "testvectors/rsa_pkcs1_3072_test-vectors.h"
#include "testvectors/rsa_pkcs1_4096_test-vectors.h"
namespace nss_test {
class RsaDecryptWycheproofTest
: public ::testing::TestWithParam<RsaDecryptTestVector> {
protected:
void TestDecrypt(const RsaDecryptTestVector vec) {
SECItem pkcs8_item = {siBuffer, toUcharPtr(vec.priv_key.data()),
static_cast<unsigned int>(vec.priv_key.size())};
ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
EXPECT_NE(nullptr, slot);
SECKEYPrivateKey* key = nullptr;
SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
slot.get(), &pkcs8_item, nullptr, nullptr, false, false, KU_ALL, &key,
nullptr);
ASSERT_EQ(SECSuccess, rv);
ASSERT_NE(nullptr, key);
ScopedSECKEYPrivateKey priv_key(key);
// Decrypt
std::vector<uint8_t> decrypted(PR_MAX(1, vec.ct.size()));
unsigned int decrypted_len = 0;
rv = PK11_PrivDecryptPKCS1(priv_key.get(), decrypted.data(), &decrypted_len,
decrypted.size(), vec.ct.data(), vec.ct.size());
// RSA_DecryptBlock returns SECFailure with an empty message.
if (vec.valid && vec.msg.size()) {
EXPECT_EQ(SECSuccess, rv);
decrypted.resize(decrypted_len);
EXPECT_EQ(vec.msg, decrypted);
} else {
EXPECT_EQ(SECFailure, rv);
}
};
};
TEST_P(RsaDecryptWycheproofTest, Pkcs1Decrypt) { TestDecrypt(GetParam()); }
INSTANTIATE_TEST_CASE_P(WycheproofRsa2048DecryptTest, RsaDecryptWycheproofTest,
::testing::ValuesIn(kRsa2048DecryptWycheproofVectors));
INSTANTIATE_TEST_CASE_P(WycheproofRsa3072DecryptTest, RsaDecryptWycheproofTest,
::testing::ValuesIn(kRsa3072DecryptWycheproofVectors));
INSTANTIATE_TEST_CASE_P(WycheproofRsa4096DecryptTest, RsaDecryptWycheproofTest,
::testing::ValuesIn(kRsa4096DecryptWycheproofVectors));
TEST(RsaEncryptTest, MessageLengths) {
const uint8_t spki[] = {
0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
......@@ -74,4 +124,4 @@ TEST(RsaEncryptTest, MessageLengths) {
&ctxt_len, UINT_MAX, msg.data(), UINT_MAX, nullptr);
ASSERT_EQ(SECFailure, rv);
}
}
} // namespace nss_test
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 <stdint.h>
#include "cpputil.h"
#include "cryptohi.h"
#include "gtest/gtest.h"
#include "limits.h"
#include "nss.h"
#include "nss_scoped_ptrs.h"
#include "pk11pub.h"
#include "testvectors/rsa_oaep_2048_sha1_mgf1sha1-vectors.h"
#include "testvectors/rsa_oaep_2048_sha256_mgf1sha1-vectors.h"
#include "testvectors/rsa_oaep_2048_sha256_mgf1sha256-vectors.h"
#include "testvectors/rsa_oaep_2048_sha384_mgf1sha1-vectors.h"
#include "testvectors/rsa_oaep_2048_sha384_mgf1sha384-vectors.h"
#include "testvectors/rsa_oaep_2048_sha512_mgf1sha1-vectors.h"
#include "testvectors/rsa_oaep_2048_sha512_mgf1sha512-vectors.h"
namespace nss_test {
class RsaOaepWycheproofTest
: public ::testing::TestWithParam<RsaOaepTestVectorStr> {
protected:
void TestDecrypt(const RsaOaepTestVectorStr vec) {
SECItem pkcs8_item = {siBuffer, toUcharPtr(vec.priv_key.data()),
static_cast<unsigned int>(vec.priv_key.size())};
ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
EXPECT_NE(nullptr, slot);
SECKEYPrivateKey* key = nullptr;
SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
slot.get(), &pkcs8_item, nullptr, nullptr, false, false, KU_ALL, &key,
nullptr);
ASSERT_EQ(SECSuccess, rv);
ASSERT_NE(nullptr, key);
ScopedSECKEYPrivateKey priv_key(key);
// Set up the OAEP parameters.
CK_RSA_PKCS_OAEP_PARAMS oaepParams;
oaepParams.source = CKZ_DATA_SPECIFIED;
oaepParams.pSourceData = const_cast<unsigned char*>(vec.label.data());
oaepParams.ulSourceDataLen = vec.label.size();
oaepParams.mgf = vec.mgf_hash;
oaepParams.hashAlg = HashOidToHashMech(vec.hash_oid);
SECItem params_item = {siBuffer,
toUcharPtr(reinterpret_cast<uint8_t*>(&oaepParams)),
static_cast<unsigned int>(sizeof(oaepParams))};
// Decrypt.
std::vector<uint8_t> decrypted(PR_MAX(1, vec.ct.size()));
unsigned int decrypted_len = 0;
rv = PK11_PrivDecrypt(priv_key.get(), CKM_RSA_PKCS_OAEP, &params_item,
decrypted.data(), &decrypted_len, decrypted.size(),
vec.ct.data(), vec.ct.size());
if (vec.valid) {
EXPECT_EQ(SECSuccess, rv);
decrypted.resize(decrypted_len);
EXPECT_EQ(vec.msg, decrypted);
} else {
EXPECT_EQ(SECFailure, rv);
}
};
private:
inline CK_MECHANISM_TYPE HashOidToHashMech(SECOidTag hash_oid) {
switch (hash_oid) {
case SEC_OID_SHA1:
return CKM_SHA_1;
case SEC_OID_SHA224:
return CKM_SHA224;
case SEC_OID_SHA256:
return CKM_SHA256;
case SEC_OID_SHA384:
return CKM_SHA384;
case SEC_OID_SHA512:
return CKM_SHA512;
default:
ADD_FAILURE();
}
return CKM_INVALID_MECHANISM;
}
};
TEST_P(RsaOaepWycheproofTest, OaepDecrypt) { TestDecrypt(GetParam()); }
INSTANTIATE_TEST_CASE_P(WycheproofRsa2048Sha1OaepTest, RsaOaepWycheproofTest,
::testing::ValuesIn(kRsaOaep2048Sha1WycheproofVectors));
INSTANTIATE_TEST_CASE_P(
WycheproofOaep2048Sha256Sha1Test, RsaOaepWycheproofTest,
::testing::ValuesIn(kRsaOaep2048Sha256Mgf1Sha1WycheproofVectors));
INSTANTIATE_TEST_CASE_P(
WycheproofOaep2048Sha256Sha256Test, RsaOaepWycheproofTest,
::testing::ValuesIn(kRsaOaep2048Sha256Mgf1Sha256WycheproofVectors));
INSTANTIATE_TEST_CASE_P(
WycheproofOaep2048Sha384Sha1Test, RsaOaepWycheproofTest,
::testing::ValuesIn(kRsaOaep2048Sha384Mgf1Sha1WycheproofVectors));
INSTANTIATE_TEST_CASE_P(
WycheproofOaep2048Sha384Sha384Test, RsaOaepWycheproofTest,
::testing::ValuesIn(kRsaOaep2048Sha384Mgf1Sha384WycheproofVectors));
INSTANTIATE_TEST_CASE_P(
WycheproofOaep2048Sha512Sha1Test, RsaOaepWycheproofTest,
::testing::ValuesIn(kRsaOaep2048Sha512Mgf1Sha1WycheproofVectors));
INSTANTIATE_TEST_CASE_P(
WycheproofOaep2048Sha512Sha512Test, RsaOaepWycheproofTest,
::testing::ValuesIn(kRsaOaep2048Sha512Mgf1Sha512WycheproofVectors));
} // namespace nss_test
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment