From 15a0c9a8e6cf820c65b67ca2cc5947c4dca57550 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Fri, 12 May 2023 01:01:14 -0400 Subject: [PATCH 1/3] Remove now redundant RSA test RSATest.MissingParameters tests this case a bit more extensively. Change-Id: I61e38bd139c6334ff9d5c9636a159cb20bcd7f7b Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/59825 Commit-Queue: Adam Langley Reviewed-by: Adam Langley Auto-Submit: David Benjamin --- crypto/rsa_extra/rsa_test.cc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/crypto/rsa_extra/rsa_test.cc b/crypto/rsa_extra/rsa_test.cc index 48f48d846..070e1f654 100644 --- a/crypto/rsa_extra/rsa_test.cc +++ b/crypto/rsa_extra/rsa_test.cc @@ -740,22 +740,6 @@ TEST(RSATest, BlindingDisabled) { RSA_verify(NID_sha256, kZeros, sizeof(kZeros), sig, sig_len, rsa.get())); } -// Test that decrypting with a public key fails gracefully rather than crashing. -TEST(RSATest, DecryptPublic) { - bssl::UniquePtr pub( - RSA_public_key_from_bytes(kFIPSPublicKey, sizeof(kFIPSPublicKey) - 1)); - ASSERT_TRUE(pub); - ASSERT_EQ(1024u / 8u, RSA_size(pub.get())); - - size_t len; - uint8_t in[1024 / 8] = {0}, out[1024 / 8]; - EXPECT_FALSE(RSA_decrypt(pub.get(), &len, out, sizeof(out), in, sizeof(in), - RSA_PKCS1_PADDING)); - uint32_t err = ERR_get_error(); - EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err)); - EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err)); -} - TEST(RSATest, CheckKey) { static const char kN[] = "b5a5651bc2e15ce31d789f0984053a2ea0cf8f964a78068c45acfdf078c57fd62d5a287c" @@ -1170,22 +1154,38 @@ TEST(RSATest, MissingParameters) { bssl::UniquePtr rsa( RSA_new_public_key(RSA_get0_n(sample.get()), RSA_get0_e(sample.get()))); ASSERT_TRUE(rsa); + std::vector out(RSA_size(sample.get())); EXPECT_FALSE(RSA_sign(NID_sha256, kZeros, sizeof(kZeros), out.data(), &len_u, rsa.get())); + uint32_t err = ERR_get_error(); + EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err)); + EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err)); + size_t len; EXPECT_FALSE(RSA_decrypt(rsa.get(), &len, out.data(), out.size(), kOAEPCiphertext1, sizeof(kOAEPCiphertext1) - 1, RSA_PKCS1_OAEP_PADDING)); + err = ERR_get_error(); + EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err)); + EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err)); // A private key without e cannot perform public key operations. rsa.reset(RSA_new_private_key_no_e(RSA_get0_n(sample.get()), RSA_get0_d(sample.get()))); ASSERT_TRUE(rsa); + EXPECT_FALSE(RSA_verify(NID_sha256, kZeros, sizeof(kZeros), sig.data(), sig.size(), rsa.get())); + err = ERR_get_error(); + EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err)); + EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err)); + EXPECT_FALSE(RSA_encrypt(rsa.get(), &len, out.data(), out.size(), kPlaintext, kPlaintextLen, RSA_PKCS1_OAEP_PADDING)); + err = ERR_get_error(); + EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err)); + EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err)); } TEST(RSATest, Negative) { From 786554f8f4e8c75bb18c5f91f69b7a328c177618 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Fri, 12 May 2023 01:08:47 -0400 Subject: [PATCH 2/3] Check public components in freeze_private_key We currently don't enforce rsa_check_public_key invariants on private key operations, only public key operations and RSA_check_key. This means it was actually possible, in some corner cases, to perform operations with oversized e or n. Fix this. This gets us a bit closer to aligning the mess of RSA invariants. (RSA_check_key still performs some extra checks, but most of those should be redundant with the CRT self-check.) Update-Note: Manually constructed RSA private keys with invalid n or e will now fail private key operations. Such keys would always fail at public key operations (so the signatures would never verify). They also already failed RSA_check_key and parsing. The one incompatibility of note is keys with only n and d, constructed by reaching into the internal RSA struct, no longer work. Instead, use RSA_new_private_key_no_e. Conscrypt used to do this but has since been migrated to the new API. Bug: 316 Change-Id: I062fdad924b8698e257dab9760687e4b381c970d Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/59826 Reviewed-by: Adam Langley Commit-Queue: David Benjamin --- crypto/fipsmodule/rsa/rsa_impl.c | 7 ++++ crypto/rsa_extra/rsa_test.cc | 68 ++++++++++---------------------- 2 files changed, 27 insertions(+), 48 deletions(-) diff --git a/crypto/fipsmodule/rsa/rsa_impl.c b/crypto/fipsmodule/rsa/rsa_impl.c index b907ae405..928346657 100644 --- a/crypto/fipsmodule/rsa/rsa_impl.c +++ b/crypto/fipsmodule/rsa/rsa_impl.c @@ -79,6 +79,8 @@ int rsa_check_public_key(const RSA *rsa) { return 0; } + // TODO(davidben): 16384-bit RSA is huge. Can we bring this down to a limit of + // 8192-bit? unsigned n_bits = BN_num_bits(rsa->n); if (n_bits > 16 * 1024) { OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE); @@ -176,6 +178,11 @@ static int freeze_private_key(RSA *rsa, BN_CTX *ctx) { goto err; } + // Check the public components are within DoS bounds. + if (!rsa_check_public_key(rsa)) { + goto err; + } + // Pre-compute various intermediate values, as well as copies of private // exponents with correct widths. Note that other threads may concurrently // read from |rsa->n|, |rsa->e|, etc., so any fixes must be in separate diff --git a/crypto/rsa_extra/rsa_test.cc b/crypto/rsa_extra/rsa_test.cc index 070e1f654..fc5d5f86e 100644 --- a/crypto/rsa_extra/rsa_test.cc +++ b/crypto/rsa_extra/rsa_test.cc @@ -584,51 +584,6 @@ TEST(RSATest, BadKey) { EXPECT_FALSE(key); } -TEST(RSATest, OnlyDGiven) { - static const char kN[] = - "00e77bbf3889d4ef36a9a25d4d69f3f632eb4362214c74517da6d6aeaa9bd09ac42b2662" - "1cd88f3a6eb013772fc3bf9f83914b6467231c630202c35b3e5808c659"; - static const char kE[] = "010001"; - static const char kD[] = - "0365db9eb6d73b53b015c40cd8db4de7dd7035c68b5ac1bf786d7a4ee2cea316eaeca21a" - "73ac365e58713195f2ae9849348525ca855386b6d028e437a9495a01"; - - bssl::UniquePtr key(RSA_new()); - ASSERT_TRUE(key); - ASSERT_TRUE(BN_hex2bn(&key->n, kN)); - ASSERT_TRUE(BN_hex2bn(&key->e, kE)); - ASSERT_TRUE(BN_hex2bn(&key->d, kD)); - - // Keys with only n, e, and d are functional. - EXPECT_TRUE(RSA_check_key(key.get())); - - const uint8_t kDummyHash[32] = {0}; - uint8_t buf[64]; - unsigned buf_len = sizeof(buf); - ASSERT_LE(RSA_size(key.get()), sizeof(buf)); - EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, - &buf_len, key.get())); - EXPECT_TRUE(RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, - buf_len, key.get())); - - // Keys without the public exponent must continue to work when blinding is - // disabled to support Java's RSAPrivateKeySpec API. See - // https://bugs.chromium.org/p/boringssl/issues/detail?id=12. - bssl::UniquePtr key2(RSA_new()); - ASSERT_TRUE(key2); - ASSERT_TRUE(BN_hex2bn(&key2->n, kN)); - ASSERT_TRUE(BN_hex2bn(&key2->d, kD)); - key2->flags |= RSA_FLAG_NO_BLINDING; - - ASSERT_LE(RSA_size(key2.get()), sizeof(buf)); - EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, - &buf_len, key2.get())); - - // Verify the signature with |key|. |key2| has no public exponent. - EXPECT_TRUE(RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, - buf_len, key.get())); -} - TEST(RSATest, ASN1) { // Test that private keys may be decoded. bssl::UniquePtr rsa( @@ -1258,6 +1213,25 @@ TEST(RSATest, LargeE) { /*dmp1=*/e, /*dmq1=*/e, iqmp)); EXPECT_FALSE(priv); + // Constructing such a key piecemeal also would not work. This was only + // possible with private APIs, so when |RSA| is opaque, this case will be + // impossible. + priv.reset(RSA_new()); + ASSERT_TRUE(priv); + priv->n = BN_dup(n); + ASSERT_TRUE(priv->n); + priv->e = BN_dup(d); // Swapped + ASSERT_TRUE(priv->e); + priv->d = BN_dup(e); + ASSERT_TRUE(priv->d); + + static const uint8_t kDigest[32] = {0}; + std::vector sig(RSA_size(priv.get())); + size_t len; + EXPECT_FALSE(RSA_sign_pss_mgf1(priv.get(), &len, sig.data(), sig.size(), + kDigest, sizeof(kDigest), EVP_sha256(), + EVP_sha256(), /*salt_len=*/32)); + // But the "large e" APIs tolerate it. pub.reset(RSA_new_public_key_large_e(n, /*e=*/d)); ASSERT_TRUE(pub); @@ -1266,9 +1240,7 @@ TEST(RSATest, LargeE) { ASSERT_TRUE(priv); // Test that operations work correctly. - static const uint8_t kDigest[32] = {0}; - std::vector sig(RSA_size(priv.get())); - size_t len; + sig.resize(RSA_size(priv.get())); ASSERT_TRUE(RSA_sign_pss_mgf1(priv.get(), &len, sig.data(), sig.size(), kDigest, sizeof(kDigest), EVP_sha256(), EVP_sha256(), /*salt_len=*/32)); From dd9ee6068667ca58c8d6f1c1cea617fd69452ecf Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Thu, 11 May 2023 10:12:03 -0400 Subject: [PATCH 3/3] Reject RSA keys under 512 bits 512-bit RSA was factored in 1999, so this limit barely means anything. But establish some limit now to ratchet in what we can. We'll raise this limit as we clear through further rounds of bad keys in tests. As part of this, I've touched up rsa_test.cc a bit. All the functions that made assumptions on key size now use std::vector with RSA_size. kKey1 and kKey2 were also 512- and 400-bit RSA, respectively. In principle, we could keep kKey1 for now, but the next stage will break it anyway. I've replaced them with kFIPSKey (which was "FIPS-compliant" but actually 1024-bit) and kTwoPrime (remnant of multi-prime RSA, 2048-bit). As neither name makes sense, they're just the new kKey1 and kKey2. I've also switched from string literals to arrays, which avoids the pesky trailing NUL. Sadly, it is a bit more verbose. Maybe we should switch to writing something like: const std::vector kKey1 = MustDecodeHex("abcdef1234..."); Static initializers don't matter in tests, after all. Update-Note: We no longer accept 511-bit RSA and below. If you run into this, update test keys to more modern sizes as we plan to raise the limit beyond 512-bit RSA in the future. 512-bit RSA was factored in 1999, so keys at or near this limit have been obsolete for a very, very long time. Bug: 607 Change-Id: I13c3366d7e5f326710f1d1b298f4150a4e8e4d78 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/59827 Commit-Queue: David Benjamin Reviewed-by: Adam Langley --- crypto/fipsmodule/rsa/rsa_impl.c | 21 +- crypto/rsa_extra/rsa_test.cc | 777 ++++++++++++++++++------------- 2 files changed, 474 insertions(+), 324 deletions(-) diff --git a/crypto/fipsmodule/rsa/rsa_impl.c b/crypto/fipsmodule/rsa/rsa_impl.c index 928346657..120639703 100644 --- a/crypto/fipsmodule/rsa/rsa_impl.c +++ b/crypto/fipsmodule/rsa/rsa_impl.c @@ -87,6 +87,13 @@ int rsa_check_public_key(const RSA *rsa) { return 0; } + // TODO(crbug.com/boringssl/607): Raise this limit. 512-bit RSA was factored + // in 1999. + if (n_bits < 512) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + // RSA moduli must be positive and odd. In addition to being necessary for RSA // in general, we cannot setup Montgomery reduction with even moduli. if (!BN_is_odd(rsa->n) || BN_is_negative(rsa->n)) { @@ -124,22 +131,16 @@ int rsa_check_public_key(const RSA *rsa) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); return 0; } + + // The upper bound on |e_bits| and lower bound on |n_bits| imply e is + // bounded by n. + assert(BN_ucmp(rsa->n, rsa->e) > 0); } } else if (!(rsa->flags & RSA_FLAG_NO_PUBLIC_EXPONENT)) { OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); return 0; } - // Verify |n > e|. Comparing |n_bits| to |kMaxExponentBits| is a small - // shortcut to comparing |n| and |e| directly. In reality, |kMaxExponentBits| - // is much smaller than the minimum RSA key size that any application should - // accept. - if (n_bits <= kMaxExponentBits) { - OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); - return 0; - } - assert(rsa->e == NULL || BN_ucmp(rsa->n, rsa->e) > 0); - return 1; } diff --git a/crypto/rsa_extra/rsa_test.cc b/crypto/rsa_extra/rsa_test.cc index fc5d5f86e..87e0396d1 100644 --- a/crypto/rsa_extra/rsa_test.cc +++ b/crypto/rsa_extra/rsa_test.cc @@ -80,229 +80,202 @@ // kPlaintext is a sample plaintext. -static const uint8_t kPlaintext[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a"; -static const size_t kPlaintextLen = sizeof(kPlaintext) - 1; +static const uint8_t kPlaintext[] = {0x54, 0x85, 0x9b, 0x34, + 0x2c, 0x49, 0xea, 0x2a}; -// kKey1 is a DER-encoded RSAPrivateKey. -static const uint8_t kKey1[] = - "\x30\x82\x01\x38\x02\x01\x00\x02\x41\x00\xaa\x36\xab\xce\x88\xac\xfd\xff" - "\x55\x52\x3c\x7f\xc4\x52\x3f\x90\xef\xa0\x0d\xf3\x77\x4a\x25\x9f\x2e\x62" - "\xb4\xc5\xd9\x9c\xb5\xad\xb3\x00\xa0\x28\x5e\x53\x01\x93\x0e\x0c\x70\xfb" - "\x68\x76\x93\x9c\xe6\x16\xce\x62\x4a\x11\xe0\x08\x6d\x34\x1e\xbc\xac\xa0" - "\xa1\xf5\x02\x01\x11\x02\x40\x0a\x03\x37\x48\x62\x64\x87\x69\x5f\x5f\x30" - "\xbc\x38\xb9\x8b\x44\xc2\xcd\x2d\xff\x43\x40\x98\xcd\x20\xd8\xa1\x38\xd0" - "\x90\xbf\x64\x79\x7c\x3f\xa7\xa2\xcd\xcb\x3c\xd1\xe0\xbd\xba\x26\x54\xb4" - "\xf9\xdf\x8e\x8a\xe5\x9d\x73\x3d\x9f\x33\xb3\x01\x62\x4a\xfd\x1d\x51\x02" - "\x21\x00\xd8\x40\xb4\x16\x66\xb4\x2e\x92\xea\x0d\xa3\xb4\x32\x04\xb5\xcf" - "\xce\x33\x52\x52\x4d\x04\x16\xa5\xa4\x41\xe7\x00\xaf\x46\x12\x0d\x02\x21" - "\x00\xc9\x7f\xb1\xf0\x27\xf4\x53\xf6\x34\x12\x33\xea\xaa\xd1\xd9\x35\x3f" - "\x6c\x42\xd0\x88\x66\xb1\xd0\x5a\x0f\x20\x35\x02\x8b\x9d\x89\x02\x20\x59" - "\x0b\x95\x72\xa2\xc2\xa9\xc4\x06\x05\x9d\xc2\xab\x2f\x1d\xaf\xeb\x7e\x8b" - "\x4f\x10\xa7\x54\x9e\x8e\xed\xf5\xb4\xfc\xe0\x9e\x05\x02\x21\x00\x8e\x3c" - "\x05\x21\xfe\x15\xe0\xea\x06\xa3\x6f\xf0\xf1\x0c\x99\x52\xc3\x5b\x7a\x75" - "\x14\xfd\x32\x38\xb8\x0a\xad\x52\x98\x62\x8d\x51\x02\x20\x36\x3f\xf7\x18" - "\x9d\xa8\xe9\x0b\x1d\x34\x1f\x71\xd0\x9b\x76\xa8\xa9\x43\xe1\x1d\x10\xb2" - "\x4d\x24\x9f\x2d\xea\xfe\xf8\x0c\x18\x26"; -// kFIPSKey is a DER-encoded RSAPrivateKey that is FIPS-compliant. -static const uint8_t kFIPSKey[] = - "\x30\x82\x02\x5c\x02\x01\x00\x02\x81\x81\x00\xa1\x71\x90\x77\x86\x8a\xc7" - "\xb8\xfc\x2a\x45\x82\x6d\xee\xeb\x35\x3a\x18\x3f\xb6\xb0\x1e\xb1\xd3\x09" - "\x6b\x05\x4d\xec\x1c\x37\x6f\x09\x31\x32\xda\x21\x8a\x49\x0e\x16\x28\xed" - "\x9a\x30\xf3\x14\x53\xfd\x5b\xb0\xf6\x4a\x5d\x52\xe1\xda\xe1\x40\x6e\x65" - "\xbf\xca\x45\xd9\x62\x96\x4a\x1e\x11\xc4\x61\x83\x1f\x58\x8d\x5e\xd0\x12" - "\xaf\xa5\xec\x9b\x97\x2f\x6c\xb2\x82\x4a\x73\xd0\xd3\x9a\xc9\x69\x6b\x24" - "\x3c\x82\x6f\xee\x4d\x0c\x7e\xdf\xd7\xae\xea\x3a\xeb\x04\x27\x8d\x43\x81" - "\x59\xa7\x90\x56\xc1\x69\x42\xb3\xaf\x1c\x8d\x4e\xbf\x02\x03\x01\x00\x01" - "\x02\x81\x80\x60\x82\xcd\x44\x46\xcf\xeb\xf9\x6f\xf5\xad\x3b\xfd\x90\x18" - "\x57\xe7\x74\xdb\x91\xd0\xd3\x68\xa6\xaa\x38\xaa\x21\x1d\x06\xf9\x34\x8d" - "\xa0\x35\xb0\x24\xe0\xd0\x2f\x75\x9b\xdd\xfe\x91\x48\x9f\x5c\x5e\x57\x54" - "\x00\xc8\x0f\xe6\x1e\x52\x84\xd9\xc9\xa5\x55\xf4\x0a\xbe\x88\x46\x7a\xfb" - "\x18\x37\x8e\xe6\x6e\xa2\x5f\x80\x48\x34\x3f\x5c\xbe\x0e\x1e\xe8\x2f\x50" - "\xba\x14\x96\x3c\xea\xfb\xd2\x49\x33\xdc\x12\xb8\xa7\x8a\xb5\x27\xf9\x00" - "\x4b\xf5\xd2\x2a\xd0\x2c\x1d\x9b\xd5\x6c\x3e\x4b\xb9\x7e\x39\xf7\x3e\x39" - "\xc9\x47\x5e\xbe\x91\x02\x41\x00\xcd\x33\xcf\x37\x01\xd7\x59\xcc\xbe\xa0" - "\x1c\xb9\xf5\xe7\x44\x9f\x62\x91\xa7\xa7\x7b\x0c\x52\xcd\x7e\xe6\x31\x11" - "\x8b\xd8\x2c\x8a\x63\xe1\x07\xc9\xcb\xce\x01\x45\x63\xf5\x5d\x44\xfb\xeb" - "\x8d\x74\x16\x20\x7d\x3b\xb4\xa1\x61\xb0\xa8\x29\x51\xc9\xef\xb6\xa1\xd5" - "\x02\x41\x00\xc9\x68\xa6\xd3\x88\xd5\x49\x9d\x6b\x44\x96\xfd\xbf\x66\x27" - "\xb4\x1f\x90\x76\x86\x2f\xe2\xce\x20\x5d\xee\x9b\xeb\xc4\xb4\x62\x47\x79" - "\x99\xb1\x99\xbc\xa2\xa6\xb6\x96\x64\xd5\x77\x9b\x45\xd4\xf0\x99\xb5\x9e" - "\x61\x4d\xf5\x12\xdd\x84\x14\xaf\x1e\xdd\x83\x24\x43\x02\x40\x60\x29\x7f" - "\x59\xcf\xcb\x13\x92\x17\x63\x01\x13\x44\x61\x74\x8f\x1c\xaa\x15\x5f\x2f" - "\x12\xbf\x5a\xfd\xb4\xf2\x19\xbe\xe7\x37\x38\x43\x46\x19\x58\x3f\xe1\xf2" - "\x46\x8a\x69\x59\xa4\x12\x4a\x78\xa7\x86\x17\x03\x99\x0f\x34\xf1\x8a\xcf" - "\xc3\x4d\x48\xcc\xc5\x51\x61\x02\x41\x00\xc2\x12\xb3\x5d\xf5\xe5\xff\xcf" - "\x4e\x43\x83\x72\xf2\xf1\x4e\xa4\xc4\x1d\x81\xf7\xff\x40\x7e\xfa\xb5\x48" - "\x6c\xba\x1c\x8a\xec\x80\x8e\xed\xc8\x32\xa9\x8f\xd9\x30\xeb\x6e\x32\x3b" - "\xd4\x44\xcf\xd1\x1f\x6b\xe0\x37\x46\xd5\x35\xde\x79\x9d\x2c\xb9\x83\x1d" - "\x10\xdd\x02\x40\x0f\x14\x95\x96\xa0\xe2\x6c\xd4\x88\xa7\x0b\x82\x14\x10" - "\xad\x26\x0d\xe4\xa1\x5e\x01\x3d\x21\xd2\xfb\x0e\xf9\x58\xa5\xca\x1e\x21" - "\xb3\xf5\x9a\x6c\x3d\x5a\x72\xb1\x2d\xfe\xac\x09\x4f\xdd\xe5\x44\xd1\x4e" - "\xf8\x59\x85\x3a\x65\xe2\xcd\xbc\x27\x1d\x9b\x48\x9f\xb9"; +// kKey1 is a DER-encoded 1024-bit RSAPrivateKey with e = 65537. +static const uint8_t kKey1[] = { + 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xa1, + 0x71, 0x90, 0x77, 0x86, 0x8a, 0xc7, 0xb8, 0xfc, 0x2a, 0x45, 0x82, 0x6d, + 0xee, 0xeb, 0x35, 0x3a, 0x18, 0x3f, 0xb6, 0xb0, 0x1e, 0xb1, 0xd3, 0x09, + 0x6b, 0x05, 0x4d, 0xec, 0x1c, 0x37, 0x6f, 0x09, 0x31, 0x32, 0xda, 0x21, + 0x8a, 0x49, 0x0e, 0x16, 0x28, 0xed, 0x9a, 0x30, 0xf3, 0x14, 0x53, 0xfd, + 0x5b, 0xb0, 0xf6, 0x4a, 0x5d, 0x52, 0xe1, 0xda, 0xe1, 0x40, 0x6e, 0x65, + 0xbf, 0xca, 0x45, 0xd9, 0x62, 0x96, 0x4a, 0x1e, 0x11, 0xc4, 0x61, 0x83, + 0x1f, 0x58, 0x8d, 0x5e, 0xd0, 0x12, 0xaf, 0xa5, 0xec, 0x9b, 0x97, 0x2f, + 0x6c, 0xb2, 0x82, 0x4a, 0x73, 0xd0, 0xd3, 0x9a, 0xc9, 0x69, 0x6b, 0x24, + 0x3c, 0x82, 0x6f, 0xee, 0x4d, 0x0c, 0x7e, 0xdf, 0xd7, 0xae, 0xea, 0x3a, + 0xeb, 0x04, 0x27, 0x8d, 0x43, 0x81, 0x59, 0xa7, 0x90, 0x56, 0xc1, 0x69, + 0x42, 0xb3, 0xaf, 0x1c, 0x8d, 0x4e, 0xbf, 0x02, 0x03, 0x01, 0x00, 0x01, + 0x02, 0x81, 0x80, 0x60, 0x82, 0xcd, 0x44, 0x46, 0xcf, 0xeb, 0xf9, 0x6f, + 0xf5, 0xad, 0x3b, 0xfd, 0x90, 0x18, 0x57, 0xe7, 0x74, 0xdb, 0x91, 0xd0, + 0xd3, 0x68, 0xa6, 0xaa, 0x38, 0xaa, 0x21, 0x1d, 0x06, 0xf9, 0x34, 0x8d, + 0xa0, 0x35, 0xb0, 0x24, 0xe0, 0xd0, 0x2f, 0x75, 0x9b, 0xdd, 0xfe, 0x91, + 0x48, 0x9f, 0x5c, 0x5e, 0x57, 0x54, 0x00, 0xc8, 0x0f, 0xe6, 0x1e, 0x52, + 0x84, 0xd9, 0xc9, 0xa5, 0x55, 0xf4, 0x0a, 0xbe, 0x88, 0x46, 0x7a, 0xfb, + 0x18, 0x37, 0x8e, 0xe6, 0x6e, 0xa2, 0x5f, 0x80, 0x48, 0x34, 0x3f, 0x5c, + 0xbe, 0x0e, 0x1e, 0xe8, 0x2f, 0x50, 0xba, 0x14, 0x96, 0x3c, 0xea, 0xfb, + 0xd2, 0x49, 0x33, 0xdc, 0x12, 0xb8, 0xa7, 0x8a, 0xb5, 0x27, 0xf9, 0x00, + 0x4b, 0xf5, 0xd2, 0x2a, 0xd0, 0x2c, 0x1d, 0x9b, 0xd5, 0x6c, 0x3e, 0x4b, + 0xb9, 0x7e, 0x39, 0xf7, 0x3e, 0x39, 0xc9, 0x47, 0x5e, 0xbe, 0x91, 0x02, + 0x41, 0x00, 0xcd, 0x33, 0xcf, 0x37, 0x01, 0xd7, 0x59, 0xcc, 0xbe, 0xa0, + 0x1c, 0xb9, 0xf5, 0xe7, 0x44, 0x9f, 0x62, 0x91, 0xa7, 0xa7, 0x7b, 0x0c, + 0x52, 0xcd, 0x7e, 0xe6, 0x31, 0x11, 0x8b, 0xd8, 0x2c, 0x8a, 0x63, 0xe1, + 0x07, 0xc9, 0xcb, 0xce, 0x01, 0x45, 0x63, 0xf5, 0x5d, 0x44, 0xfb, 0xeb, + 0x8d, 0x74, 0x16, 0x20, 0x7d, 0x3b, 0xb4, 0xa1, 0x61, 0xb0, 0xa8, 0x29, + 0x51, 0xc9, 0xef, 0xb6, 0xa1, 0xd5, 0x02, 0x41, 0x00, 0xc9, 0x68, 0xa6, + 0xd3, 0x88, 0xd5, 0x49, 0x9d, 0x6b, 0x44, 0x96, 0xfd, 0xbf, 0x66, 0x27, + 0xb4, 0x1f, 0x90, 0x76, 0x86, 0x2f, 0xe2, 0xce, 0x20, 0x5d, 0xee, 0x9b, + 0xeb, 0xc4, 0xb4, 0x62, 0x47, 0x79, 0x99, 0xb1, 0x99, 0xbc, 0xa2, 0xa6, + 0xb6, 0x96, 0x64, 0xd5, 0x77, 0x9b, 0x45, 0xd4, 0xf0, 0x99, 0xb5, 0x9e, + 0x61, 0x4d, 0xf5, 0x12, 0xdd, 0x84, 0x14, 0xaf, 0x1e, 0xdd, 0x83, 0x24, + 0x43, 0x02, 0x40, 0x60, 0x29, 0x7f, 0x59, 0xcf, 0xcb, 0x13, 0x92, 0x17, + 0x63, 0x01, 0x13, 0x44, 0x61, 0x74, 0x8f, 0x1c, 0xaa, 0x15, 0x5f, 0x2f, + 0x12, 0xbf, 0x5a, 0xfd, 0xb4, 0xf2, 0x19, 0xbe, 0xe7, 0x37, 0x38, 0x43, + 0x46, 0x19, 0x58, 0x3f, 0xe1, 0xf2, 0x46, 0x8a, 0x69, 0x59, 0xa4, 0x12, + 0x4a, 0x78, 0xa7, 0x86, 0x17, 0x03, 0x99, 0x0f, 0x34, 0xf1, 0x8a, 0xcf, + 0xc3, 0x4d, 0x48, 0xcc, 0xc5, 0x51, 0x61, 0x02, 0x41, 0x00, 0xc2, 0x12, + 0xb3, 0x5d, 0xf5, 0xe5, 0xff, 0xcf, 0x4e, 0x43, 0x83, 0x72, 0xf2, 0xf1, + 0x4e, 0xa4, 0xc4, 0x1d, 0x81, 0xf7, 0xff, 0x40, 0x7e, 0xfa, 0xb5, 0x48, + 0x6c, 0xba, 0x1c, 0x8a, 0xec, 0x80, 0x8e, 0xed, 0xc8, 0x32, 0xa9, 0x8f, + 0xd9, 0x30, 0xeb, 0x6e, 0x32, 0x3b, 0xd4, 0x44, 0xcf, 0xd1, 0x1f, 0x6b, + 0xe0, 0x37, 0x46, 0xd5, 0x35, 0xde, 0x79, 0x9d, 0x2c, 0xb9, 0x83, 0x1d, + 0x10, 0xdd, 0x02, 0x40, 0x0f, 0x14, 0x95, 0x96, 0xa0, 0xe2, 0x6c, 0xd4, + 0x88, 0xa7, 0x0b, 0x82, 0x14, 0x10, 0xad, 0x26, 0x0d, 0xe4, 0xa1, 0x5e, + 0x01, 0x3d, 0x21, 0xd2, 0xfb, 0x0e, 0xf9, 0x58, 0xa5, 0xca, 0x1e, 0x21, + 0xb3, 0xf5, 0x9a, 0x6c, 0x3d, 0x5a, 0x72, 0xb1, 0x2d, 0xfe, 0xac, 0x09, + 0x4f, 0xdd, 0xe5, 0x44, 0xd1, 0x4e, 0xf8, 0x59, 0x85, 0x3a, 0x65, 0xe2, + 0xcd, 0xbc, 0x27, 0x1d, 0x9b, 0x48, 0x9f, 0xb9}; -static const uint8_t kFIPSPublicKey[] = - "\x30\x81\x89\x02\x81\x81\x00\xa1\x71\x90\x77\x86\x8a\xc7\xb8\xfc\x2a\x45" - "\x82\x6d\xee\xeb\x35\x3a\x18\x3f\xb6\xb0\x1e\xb1\xd3\x09\x6b\x05\x4d\xec" - "\x1c\x37\x6f\x09\x31\x32\xda\x21\x8a\x49\x0e\x16\x28\xed\x9a\x30\xf3\x14" - "\x53\xfd\x5b\xb0\xf6\x4a\x5d\x52\xe1\xda\xe1\x40\x6e\x65\xbf\xca\x45\xd9" - "\x62\x96\x4a\x1e\x11\xc4\x61\x83\x1f\x58\x8d\x5e\xd0\x12\xaf\xa5\xec\x9b" - "\x97\x2f\x6c\xb2\x82\x4a\x73\xd0\xd3\x9a\xc9\x69\x6b\x24\x3c\x82\x6f\xee" - "\x4d\x0c\x7e\xdf\xd7\xae\xea\x3a\xeb\x04\x27\x8d\x43\x81\x59\xa7\x90\x56" - "\xc1\x69\x42\xb3\xaf\x1c\x8d\x4e\xbf\x02\x03\x01\x00\x01"; +static const uint8_t kKey1Public[] = { + 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xa1, 0x71, 0x90, 0x77, 0x86, + 0x8a, 0xc7, 0xb8, 0xfc, 0x2a, 0x45, 0x82, 0x6d, 0xee, 0xeb, 0x35, 0x3a, + 0x18, 0x3f, 0xb6, 0xb0, 0x1e, 0xb1, 0xd3, 0x09, 0x6b, 0x05, 0x4d, 0xec, + 0x1c, 0x37, 0x6f, 0x09, 0x31, 0x32, 0xda, 0x21, 0x8a, 0x49, 0x0e, 0x16, + 0x28, 0xed, 0x9a, 0x30, 0xf3, 0x14, 0x53, 0xfd, 0x5b, 0xb0, 0xf6, 0x4a, + 0x5d, 0x52, 0xe1, 0xda, 0xe1, 0x40, 0x6e, 0x65, 0xbf, 0xca, 0x45, 0xd9, + 0x62, 0x96, 0x4a, 0x1e, 0x11, 0xc4, 0x61, 0x83, 0x1f, 0x58, 0x8d, 0x5e, + 0xd0, 0x12, 0xaf, 0xa5, 0xec, 0x9b, 0x97, 0x2f, 0x6c, 0xb2, 0x82, 0x4a, + 0x73, 0xd0, 0xd3, 0x9a, 0xc9, 0x69, 0x6b, 0x24, 0x3c, 0x82, 0x6f, 0xee, + 0x4d, 0x0c, 0x7e, 0xdf, 0xd7, 0xae, 0xea, 0x3a, 0xeb, 0x04, 0x27, 0x8d, + 0x43, 0x81, 0x59, 0xa7, 0x90, 0x56, 0xc1, 0x69, 0x42, 0xb3, 0xaf, 0x1c, + 0x8d, 0x4e, 0xbf, 0x02, 0x03, 0x01, 0x00, 0x01}; // kOAEPCiphertext1 is a sample encryption of |kPlaintext| with |kKey1| using -// RSA OAEP. -static const uint8_t kOAEPCiphertext1[] = - "\x1b\x8f\x05\xf9\xca\x1a\x79\x52\x6e\x53\xf3\xcc\x51\x4f\xdb\x89\x2b\xfb" - "\x91\x93\x23\x1e\x78\xb9\x92\xe6\x8d\x50\xa4\x80\xcb\x52\x33\x89\x5c\x74" - "\x95\x8d\x5d\x02\xab\x8c\x0f\xd0\x40\xeb\x58\x44\xb0\x05\xc3\x9e\xd8\x27" - "\x4a\x9d\xbf\xa8\x06\x71\x40\x94\x39\xd2"; +// RSA OAEP, SHA-1, and no label. It was generated with: +// +// clang-format off +// openssl pkeyutl -encrypt -inkey key1.pem -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha1 -in plaintext | xxd -i +// clang-format on +static const uint8_t kOAEPCiphertext1[] = { + 0x53, 0xa3, 0x0e, 0xc7, 0x95, 0x52, 0x80, 0x6f, 0x9d, 0x4c, 0xd2, 0x87, + 0xa0, 0x5d, 0x4b, 0xee, 0x78, 0x7d, 0xaa, 0x2a, 0xf6, 0x48, 0x5e, 0x83, + 0xb4, 0xc7, 0xd5, 0x82, 0xa7, 0xe9, 0x3e, 0x4c, 0x54, 0xa0, 0x1e, 0x5f, + 0x49, 0x17, 0x26, 0x36, 0x37, 0x22, 0x09, 0xe8, 0xde, 0x8d, 0x51, 0x49, + 0x0b, 0x34, 0x27, 0x30, 0x1f, 0x12, 0xbd, 0xf4, 0x2f, 0xed, 0x9e, 0xcf, + 0x9e, 0xda, 0x41, 0x69, 0xf7, 0x86, 0x64, 0xfc, 0x7d, 0x0a, 0x4b, 0x28, + 0x28, 0x9e, 0x38, 0x97, 0xae, 0x01, 0x86, 0xbe, 0xb0, 0x92, 0xfd, 0xa0, + 0x5c, 0x75, 0xaf, 0x01, 0x88, 0xf7, 0x24, 0xa8, 0xcd, 0x44, 0x3c, 0x13, + 0x42, 0xf7, 0x03, 0x9b, 0x88, 0x1c, 0x65, 0xf4, 0x83, 0xba, 0xc8, 0x10, + 0xe2, 0x9a, 0x37, 0x79, 0x77, 0xef, 0x20, 0x3d, 0x2d, 0xa4, 0xe5, 0x3e, + 0xd4, 0x18, 0x3e, 0x12, 0xc1, 0xc3, 0x68, 0x65}; -// kKey2 is a DER-encoded RSAPrivateKey. -static const uint8_t kKey2[] = - "\x30\x81\xfb\x02\x01\x00\x02\x33\x00\xa3\x07\x9a\x90\xdf\x0d\xfd\x72\xac" - "\x09\x0c\xcc\x2a\x78\xb8\x74\x13\x13\x3e\x40\x75\x9c\x98\xfa\xf8\x20\x4f" - "\x35\x8a\x0b\x26\x3c\x67\x70\xe7\x83\xa9\x3b\x69\x71\xb7\x37\x79\xd2\x71" - "\x7b\xe8\x34\x77\xcf\x02\x01\x03\x02\x32\x6c\xaf\xbc\x60\x94\xb3\xfe\x4c" - "\x72\xb0\xb3\x32\xc6\xfb\x25\xa2\xb7\x62\x29\x80\x4e\x68\x65\xfc\xa4\x5a" - "\x74\xdf\x0f\x8f\xb8\x41\x3b\x52\xc0\xd0\xe5\x3d\x9b\x59\x0f\xf1\x9b\xe7" - "\x9f\x49\xdd\x21\xe5\xeb\x02\x1a\x00\xcf\x20\x35\x02\x8b\x9d\x86\x98\x40" - "\xb4\x16\x66\xb4\x2e\x92\xea\x0d\xa3\xb4\x32\x04\xb5\xcf\xce\x91\x02\x1a" - "\x00\xc9\x7f\xb1\xf0\x27\xf4\x53\xf6\x34\x12\x33\xea\xaa\xd1\xd9\x35\x3f" - "\x6c\x42\xd0\x88\x66\xb1\xd0\x5f\x02\x1a\x00\x8a\x15\x78\xac\x5d\x13\xaf" - "\x10\x2b\x22\xb9\x99\xcd\x74\x61\xf1\x5e\x6d\x22\xcc\x03\x23\xdf\xdf\x0b" - "\x02\x1a\x00\x86\x55\x21\x4a\xc5\x4d\x8d\x4e\xcd\x61\x77\xf1\xc7\x36\x90" - "\xce\x2a\x48\x2c\x8b\x05\x99\xcb\xe0\x3f\x02\x1a\x00\x83\xef\xef\xb8\xa9" - "\xa4\x0d\x1d\xb6\xed\x98\xad\x84\xed\x13\x35\xdc\xc1\x08\xf3\x22\xd0\x57" - "\xcf\x8d"; +// kKey2 is a 2048-bit RSA private key, with e = 3. +static const uint8_t kKey2[] = { + 0x30, 0x82, 0x04, 0xa1, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, + 0x93, 0x3a, 0x4f, 0xc9, 0x6a, 0x0a, 0x6b, 0x28, 0x04, 0xfa, 0xb7, 0x05, + 0x56, 0xdf, 0xa0, 0xaa, 0x4f, 0xaa, 0xab, 0x94, 0xa0, 0xa9, 0x25, 0xef, + 0xc5, 0x96, 0xd2, 0xd4, 0x66, 0x16, 0x62, 0x2c, 0x13, 0x7b, 0x91, 0xd0, + 0x36, 0x0a, 0x10, 0x11, 0x6d, 0x7a, 0x91, 0xb6, 0xe4, 0x74, 0x57, 0xc1, + 0x3d, 0x7a, 0xbe, 0x24, 0x05, 0x3a, 0x04, 0x0b, 0x73, 0x91, 0x53, 0xb1, + 0x74, 0x10, 0xe1, 0x87, 0xdc, 0x91, 0x28, 0x9c, 0x1e, 0xe5, 0xf2, 0xb9, + 0xfc, 0xa2, 0x48, 0x34, 0xb6, 0x78, 0xed, 0x6d, 0x95, 0xfb, 0xf2, 0xc0, + 0x4e, 0x1c, 0xa4, 0x15, 0x00, 0x3c, 0x8a, 0x68, 0x2b, 0xd6, 0xce, 0xd5, + 0xb3, 0x9f, 0x66, 0x02, 0xa7, 0x0d, 0x08, 0xa3, 0x23, 0x9b, 0xe5, 0x36, + 0x96, 0x13, 0x22, 0xf9, 0x69, 0xa6, 0x87, 0x88, 0x9b, 0x85, 0x3f, 0x83, + 0x9c, 0xab, 0x1a, 0x1b, 0x6d, 0x8d, 0x16, 0xf4, 0x5e, 0xbd, 0xee, 0x4b, + 0x59, 0x56, 0xf8, 0x9d, 0x58, 0xcd, 0xd2, 0x83, 0x85, 0x59, 0x43, 0x84, + 0x63, 0x4f, 0xe6, 0x1a, 0x86, 0x66, 0x0d, 0xb5, 0xa0, 0x87, 0x89, 0xb6, + 0x13, 0x82, 0x43, 0xda, 0x34, 0x92, 0x3b, 0x68, 0xc4, 0x95, 0x71, 0x2f, + 0x15, 0xc2, 0xe0, 0x43, 0x67, 0x3c, 0x08, 0x00, 0x36, 0x10, 0xc3, 0xb4, + 0x46, 0x4c, 0x4e, 0x6e, 0xf5, 0x44, 0xa9, 0x04, 0x44, 0x9d, 0xce, 0xc7, + 0x05, 0x79, 0xee, 0x11, 0xcf, 0xaf, 0x2c, 0xd7, 0x9a, 0x32, 0xd3, 0xa5, + 0x30, 0xd4, 0x3a, 0x78, 0x43, 0x37, 0x74, 0x22, 0x90, 0x24, 0x04, 0x11, + 0xd7, 0x95, 0x08, 0x52, 0xa4, 0x71, 0x41, 0x68, 0x94, 0xb0, 0xa0, 0xc3, + 0xec, 0x4e, 0xd2, 0xc4, 0x30, 0x71, 0x98, 0x64, 0x9c, 0xe3, 0x7c, 0x76, + 0xef, 0x33, 0xa3, 0x2b, 0xb1, 0x87, 0x63, 0xd2, 0x5c, 0x09, 0xfc, 0x90, + 0x2d, 0x92, 0xf4, 0x57, 0x02, 0x01, 0x03, 0x02, 0x82, 0x01, 0x00, 0x62, + 0x26, 0xdf, 0xdb, 0x9c, 0x06, 0xf2, 0x1a, 0xad, 0xfc, 0x7a, 0x03, 0x8f, + 0x3f, 0xc0, 0x71, 0x8a, 0x71, 0xc7, 0xb8, 0x6b, 0x1b, 0x6e, 0x9f, 0xd9, + 0x0f, 0x37, 0x38, 0x44, 0x0e, 0xec, 0x1d, 0x62, 0x52, 0x61, 0x35, 0x79, + 0x5c, 0x0a, 0xb6, 0x48, 0xfc, 0x61, 0x24, 0x98, 0x4d, 0x8f, 0xd6, 0x28, + 0xfc, 0x7e, 0xc2, 0xae, 0x26, 0xad, 0x5c, 0xf7, 0xb6, 0x37, 0xcb, 0xa2, + 0xb5, 0xeb, 0xaf, 0xe8, 0x60, 0xc5, 0xbd, 0x69, 0xee, 0xa1, 0xd1, 0x53, + 0x16, 0xda, 0xcd, 0xce, 0xfb, 0x48, 0xf3, 0xb9, 0x52, 0xa1, 0xd5, 0x89, + 0x68, 0x6d, 0x63, 0x55, 0x7d, 0xb1, 0x9a, 0xc7, 0xe4, 0x89, 0xe3, 0xcd, + 0x14, 0xee, 0xac, 0x6f, 0x5e, 0x05, 0xc2, 0x17, 0xbd, 0x43, 0x79, 0xb9, + 0x62, 0x17, 0x50, 0xf1, 0x19, 0xaf, 0xb0, 0x67, 0xae, 0x2a, 0x57, 0xbd, + 0xc7, 0x66, 0xbc, 0xf3, 0xb3, 0x64, 0xa1, 0xe3, 0x16, 0x74, 0x9e, 0xea, + 0x02, 0x5c, 0xab, 0x94, 0xd8, 0x97, 0x02, 0x42, 0x0c, 0x2c, 0xba, 0x54, + 0xb9, 0xaf, 0xe0, 0x45, 0x93, 0xad, 0x7f, 0xb3, 0x10, 0x6a, 0x96, 0x50, + 0x4b, 0xaf, 0xcf, 0xc8, 0x27, 0x62, 0x2d, 0x83, 0xe9, 0x26, 0xc6, 0x94, + 0xc1, 0xef, 0x5c, 0x8e, 0x06, 0x42, 0x53, 0xe5, 0x56, 0xaf, 0xc2, 0x99, + 0x01, 0xaa, 0x9a, 0x71, 0xbc, 0xe8, 0x21, 0x33, 0x2a, 0x2d, 0xa3, 0x36, + 0xac, 0x1b, 0x86, 0x19, 0xf8, 0xcd, 0x1f, 0x80, 0xa4, 0x26, 0x98, 0xb8, + 0x9f, 0x62, 0x62, 0xd5, 0x1a, 0x7f, 0xee, 0xdb, 0xdf, 0x81, 0xd3, 0x21, + 0xdb, 0x33, 0x92, 0xee, 0xff, 0xe2, 0x2f, 0x32, 0x77, 0x73, 0x6a, 0x58, + 0xab, 0x21, 0xf3, 0xe3, 0xe1, 0xbc, 0x4f, 0x12, 0x72, 0xa6, 0xb5, 0xc2, + 0xfb, 0x27, 0x9e, 0xc8, 0xca, 0xab, 0x64, 0xa0, 0x87, 0x07, 0x9d, 0xef, + 0xca, 0x0f, 0xdb, 0x02, 0x81, 0x81, 0x00, 0xe6, 0xd3, 0x4d, 0xc0, 0xa1, + 0x91, 0x0e, 0x62, 0xfd, 0xb0, 0xdd, 0xc6, 0x30, 0xb8, 0x8c, 0xcb, 0x14, + 0xc1, 0x4b, 0x69, 0x30, 0xdd, 0xcd, 0x86, 0x67, 0xcb, 0x37, 0x14, 0xc5, + 0x03, 0xd2, 0xb4, 0x69, 0xab, 0x3d, 0xe5, 0x16, 0x81, 0x0f, 0xe5, 0x50, + 0xf4, 0x18, 0xb1, 0xec, 0xbc, 0x71, 0xe9, 0x80, 0x99, 0x06, 0xe4, 0xa3, + 0xfe, 0x44, 0x84, 0x4a, 0x2d, 0x1e, 0x07, 0x7f, 0x22, 0x70, 0x6d, 0x4f, + 0xd4, 0x93, 0x0b, 0x8b, 0x99, 0xce, 0x1e, 0xab, 0xcd, 0x4c, 0xd2, 0xd3, + 0x10, 0x47, 0x5c, 0x09, 0x9f, 0x6d, 0x82, 0xc0, 0x08, 0x75, 0xe3, 0x3d, + 0x83, 0xc2, 0x19, 0x50, 0x29, 0xec, 0x1f, 0x84, 0x29, 0xcc, 0xf1, 0x56, + 0xee, 0xbd, 0x54, 0x5d, 0xe6, 0x19, 0xdf, 0x0d, 0x1c, 0xa4, 0xbb, 0x0a, + 0xfe, 0x84, 0x44, 0x29, 0x1d, 0xf9, 0x5c, 0x80, 0x96, 0x5b, 0x24, 0xb4, + 0xf7, 0x02, 0x1b, 0x02, 0x81, 0x81, 0x00, 0xa3, 0x48, 0xf1, 0x9c, 0x58, + 0xc2, 0x5f, 0x38, 0xfb, 0xd8, 0x12, 0x39, 0xf1, 0x8e, 0x73, 0xa1, 0xcf, + 0x78, 0x12, 0xe0, 0xed, 0x2a, 0xbb, 0xef, 0xac, 0x23, 0xb2, 0xbf, 0xd6, + 0x0c, 0xe9, 0x6e, 0x1e, 0xab, 0xea, 0x3f, 0x68, 0x36, 0xa7, 0x1f, 0xe5, + 0xab, 0xe0, 0x86, 0xa5, 0x76, 0x32, 0x98, 0xdd, 0x75, 0xb5, 0x2b, 0xbc, + 0xcb, 0x8a, 0x03, 0x00, 0x7c, 0x2e, 0xca, 0xf8, 0xbc, 0x19, 0xe4, 0xe3, + 0xa3, 0x31, 0xbd, 0x1d, 0x20, 0x2b, 0x09, 0xad, 0x6f, 0x4c, 0xed, 0x48, + 0xd4, 0xdf, 0x87, 0xf9, 0xf0, 0x46, 0xb9, 0x86, 0x4c, 0x4b, 0x71, 0xe7, + 0x48, 0x78, 0xdc, 0xed, 0xc7, 0x82, 0x02, 0x44, 0xd3, 0xa6, 0xb3, 0x10, + 0x5f, 0x62, 0x81, 0xfc, 0xb8, 0xe4, 0x0e, 0xf4, 0x1a, 0xdd, 0xab, 0x3f, + 0xbc, 0x63, 0x79, 0x5b, 0x39, 0x69, 0x5e, 0xea, 0xa9, 0x15, 0xfe, 0x90, + 0xec, 0xda, 0x75, 0x02, 0x81, 0x81, 0x00, 0x99, 0xe2, 0x33, 0xd5, 0xc1, + 0x0b, 0x5e, 0xec, 0xa9, 0x20, 0x93, 0xd9, 0x75, 0xd0, 0x5d, 0xdc, 0xb8, + 0x80, 0xdc, 0xf0, 0xcb, 0x3e, 0x89, 0x04, 0x45, 0x32, 0x24, 0xb8, 0x83, + 0x57, 0xe1, 0xcd, 0x9b, 0xc7, 0x7e, 0x98, 0xb9, 0xab, 0x5f, 0xee, 0x35, + 0xf8, 0x10, 0x76, 0x9d, 0xd2, 0xf6, 0x9b, 0xab, 0x10, 0xaf, 0x43, 0x17, + 0xfe, 0xd8, 0x58, 0x31, 0x73, 0x69, 0x5a, 0x54, 0xc1, 0xa0, 0x48, 0xdf, + 0xe3, 0x0c, 0xb2, 0x5d, 0x11, 0x34, 0x14, 0x72, 0x88, 0xdd, 0xe1, 0xe2, + 0x0a, 0xda, 0x3d, 0x5b, 0xbf, 0x9e, 0x57, 0x2a, 0xb0, 0x4e, 0x97, 0x7e, + 0x57, 0xd6, 0xbb, 0x8a, 0xc6, 0x9d, 0x6a, 0x58, 0x1b, 0xdd, 0xf6, 0x39, + 0xf4, 0x7e, 0x38, 0x3e, 0x99, 0x66, 0x94, 0xb3, 0x68, 0x6d, 0xd2, 0x07, + 0x54, 0x58, 0x2d, 0x70, 0xbe, 0xa6, 0x3d, 0xab, 0x0e, 0xe7, 0x6d, 0xcd, + 0xfa, 0x01, 0x67, 0x02, 0x81, 0x80, 0x6c, 0xdb, 0x4b, 0xbd, 0x90, 0x81, + 0x94, 0xd0, 0xa7, 0xe5, 0x61, 0x7b, 0xf6, 0x5e, 0xf7, 0xc1, 0x34, 0xfa, + 0xb7, 0x40, 0x9e, 0x1c, 0x7d, 0x4a, 0x72, 0xc2, 0x77, 0x2a, 0x8e, 0xb3, + 0x46, 0x49, 0x69, 0xc7, 0xf1, 0x7f, 0x9a, 0xcf, 0x1a, 0x15, 0x43, 0xc7, + 0xeb, 0x04, 0x6e, 0x4e, 0xcc, 0x65, 0xe8, 0xf9, 0x23, 0x72, 0x7d, 0xdd, + 0x06, 0xac, 0xaa, 0xfd, 0x74, 0x87, 0x50, 0x7d, 0x66, 0x98, 0x97, 0xc2, + 0x21, 0x28, 0xbe, 0x15, 0x72, 0x06, 0x73, 0x9f, 0x88, 0x9e, 0x30, 0x8d, + 0xea, 0x5a, 0xa6, 0xa0, 0x2f, 0x26, 0x59, 0x88, 0x32, 0x4b, 0xef, 0x85, + 0xa5, 0xe8, 0x9e, 0x85, 0x01, 0x56, 0xd8, 0x8d, 0x19, 0xcc, 0xb5, 0x94, + 0xec, 0x56, 0xa8, 0x7b, 0x42, 0xb4, 0xa2, 0xbc, 0x93, 0xc7, 0x7f, 0xd2, + 0xec, 0xfb, 0x92, 0x26, 0x46, 0x3f, 0x47, 0x1b, 0x63, 0xff, 0x0b, 0x48, + 0x91, 0xa3, 0x02, 0x81, 0x80, 0x2c, 0x4a, 0xb9, 0xa4, 0x46, 0x7b, 0xff, + 0x50, 0x7e, 0xbf, 0x60, 0x47, 0x3b, 0x2b, 0x66, 0x82, 0xdc, 0x0e, 0x53, + 0x65, 0x71, 0xe9, 0xda, 0x2a, 0xb8, 0x32, 0x93, 0x42, 0xb7, 0xff, 0xea, + 0x67, 0x66, 0xf1, 0xbc, 0x87, 0x28, 0x65, 0x29, 0x79, 0xca, 0xab, 0x93, + 0x56, 0xda, 0x95, 0xc1, 0x26, 0x44, 0x3d, 0x27, 0xc1, 0x91, 0xc6, 0x9b, + 0xd9, 0xec, 0x9d, 0xb7, 0x49, 0xe7, 0x16, 0xee, 0x99, 0x87, 0x50, 0x95, + 0x81, 0xd4, 0x5c, 0x5b, 0x5a, 0x5d, 0x0a, 0x43, 0xa5, 0xa7, 0x8f, 0x5a, + 0x80, 0x49, 0xa0, 0xb7, 0x10, 0x85, 0xc7, 0xf4, 0x42, 0x34, 0x86, 0xb6, + 0x5f, 0x3f, 0x88, 0x9e, 0xc7, 0xf5, 0x59, 0x29, 0x39, 0x68, 0x48, 0xf2, + 0xd7, 0x08, 0x5b, 0x92, 0x8e, 0x6b, 0xea, 0xa5, 0x63, 0x5f, 0xc0, 0xfb, + 0xe4, 0xe1, 0xb2, 0x7d, 0xb7, 0x40, 0xe9, 0x55, 0x06, 0xbf, 0x58, 0x25, + 0x6f}; -// kOAEPCiphertext2 is a sample encryption of |kPlaintext| with |kKey2| using -// RSA OAEP. -static const uint8_t kOAEPCiphertext2[] = - "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a\x8b\x40" - "\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4\x17\x53\x03\x29" - "\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52\x62\x51"; - -// kKey3 is a DER-encoded RSAPrivateKey. -static const uint8_t kKey3[] = - "\x30\x82\x02\x5b\x02\x01\x00\x02\x81\x81\x00\xbb\xf8\x2f\x09\x06\x82\xce" - "\x9c\x23\x38\xac\x2b\x9d\xa8\x71\xf7\x36\x8d\x07\xee\xd4\x10\x43\xa4\x40" - "\xd6\xb6\xf0\x74\x54\xf5\x1f\xb8\xdf\xba\xaf\x03\x5c\x02\xab\x61\xea\x48" - "\xce\xeb\x6f\xcd\x48\x76\xed\x52\x0d\x60\xe1\xec\x46\x19\x71\x9d\x8a\x5b" - "\x8b\x80\x7f\xaf\xb8\xe0\xa3\xdf\xc7\x37\x72\x3e\xe6\xb4\xb7\xd9\x3a\x25" - "\x84\xee\x6a\x64\x9d\x06\x09\x53\x74\x88\x34\xb2\x45\x45\x98\x39\x4e\xe0" - "\xaa\xb1\x2d\x7b\x61\xa5\x1f\x52\x7a\x9a\x41\xf6\xc1\x68\x7f\xe2\x53\x72" - "\x98\xca\x2a\x8f\x59\x46\xf8\xe5\xfd\x09\x1d\xbd\xcb\x02\x01\x11\x02\x81" - "\x81\x00\xa5\xda\xfc\x53\x41\xfa\xf2\x89\xc4\xb9\x88\xdb\x30\xc1\xcd\xf8" - "\x3f\x31\x25\x1e\x06\x68\xb4\x27\x84\x81\x38\x01\x57\x96\x41\xb2\x94\x10" - "\xb3\xc7\x99\x8d\x6b\xc4\x65\x74\x5e\x5c\x39\x26\x69\xd6\x87\x0d\xa2\xc0" - "\x82\xa9\x39\xe3\x7f\xdc\xb8\x2e\xc9\x3e\xda\xc9\x7f\xf3\xad\x59\x50\xac" - "\xcf\xbc\x11\x1c\x76\xf1\xa9\x52\x94\x44\xe5\x6a\xaf\x68\xc5\x6c\x09\x2c" - "\xd3\x8d\xc3\xbe\xf5\xd2\x0a\x93\x99\x26\xed\x4f\x74\xa1\x3e\xdd\xfb\xe1" - "\xa1\xce\xcc\x48\x94\xaf\x94\x28\xc2\xb7\xb8\x88\x3f\xe4\x46\x3a\x4b\xc8" - "\x5b\x1c\xb3\xc1\x02\x41\x00\xee\xcf\xae\x81\xb1\xb9\xb3\xc9\x08\x81\x0b" - "\x10\xa1\xb5\x60\x01\x99\xeb\x9f\x44\xae\xf4\xfd\xa4\x93\xb8\x1a\x9e\x3d" - "\x84\xf6\x32\x12\x4e\xf0\x23\x6e\x5d\x1e\x3b\x7e\x28\xfa\xe7\xaa\x04\x0a" - "\x2d\x5b\x25\x21\x76\x45\x9d\x1f\x39\x75\x41\xba\x2a\x58\xfb\x65\x99\x02" - "\x41\x00\xc9\x7f\xb1\xf0\x27\xf4\x53\xf6\x34\x12\x33\xea\xaa\xd1\xd9\x35" - "\x3f\x6c\x42\xd0\x88\x66\xb1\xd0\x5a\x0f\x20\x35\x02\x8b\x9d\x86\x98\x40" - "\xb4\x16\x66\xb4\x2e\x92\xea\x0d\xa3\xb4\x32\x04\xb5\xcf\xce\x33\x52\x52" - "\x4d\x04\x16\xa5\xa4\x41\xe7\x00\xaf\x46\x15\x03\x02\x40\x54\x49\x4c\xa6" - "\x3e\xba\x03\x37\xe4\xe2\x40\x23\xfc\xd6\x9a\x5a\xeb\x07\xdd\xdc\x01\x83" - "\xa4\xd0\xac\x9b\x54\xb0\x51\xf2\xb1\x3e\xd9\x49\x09\x75\xea\xb7\x74\x14" - "\xff\x59\xc1\xf7\x69\x2e\x9a\x2e\x20\x2b\x38\xfc\x91\x0a\x47\x41\x74\xad" - "\xc9\x3c\x1f\x67\xc9\x81\x02\x40\x47\x1e\x02\x90\xff\x0a\xf0\x75\x03\x51" - "\xb7\xf8\x78\x86\x4c\xa9\x61\xad\xbd\x3a\x8a\x7e\x99\x1c\x5c\x05\x56\xa9" - "\x4c\x31\x46\xa7\xf9\x80\x3f\x8f\x6f\x8a\xe3\x42\xe9\x31\xfd\x8a\xe4\x7a" - "\x22\x0d\x1b\x99\xa4\x95\x84\x98\x07\xfe\x39\xf9\x24\x5a\x98\x36\xda\x3d" - "\x02\x41\x00\xb0\x6c\x4f\xda\xbb\x63\x01\x19\x8d\x26\x5b\xdb\xae\x94\x23" - "\xb3\x80\xf2\x71\xf7\x34\x53\x88\x50\x93\x07\x7f\xcd\x39\xe2\x11\x9f\xc9" - "\x86\x32\x15\x4f\x58\x83\xb1\x67\xa9\x67\xbf\x40\x2b\x4e\x9e\x2e\x0f\x96" - "\x56\xe6\x98\xea\x36\x66\xed\xfb\x25\x79\x80\x39\xf7"; - -// kOAEPCiphertext3 is a sample encryption of |kPlaintext| with |kKey3| using -// RSA OAEP. -static const uint8_t kOAEPCiphertext3[] = - "\xb8\x24\x6b\x56\xa6\xed\x58\x81\xae\xb5\x85\xd9\xa2\x5b\x2a\xd7\x90\xc4" - "\x17\xe0\x80\x68\x1b\xf1\xac\x2b\xc3\xde\xb6\x9d\x8b\xce\xf0\xc4\x36\x6f" - "\xec\x40\x0a\xf0\x52\xa7\x2e\x9b\x0e\xff\xb5\xb3\xf2\xf1\x92\xdb\xea\xca" - "\x03\xc1\x27\x40\x05\x71\x13\xbf\x1f\x06\x69\xac\x22\xe9\xf3\xa7\x85\x2e" - "\x3c\x15\xd9\x13\xca\xb0\xb8\x86\x3a\x95\xc9\x92\x94\xce\x86\x74\x21\x49" - "\x54\x61\x03\x46\xf4\xd4\x74\xb2\x6f\x7c\x48\xb4\x2e\xe6\x8e\x1f\x57\x2a" - "\x1f\xc4\x02\x6a\xc4\x56\xb4\xf5\x9f\x7b\x62\x1e\xa1\xb9\xd8\x8f\x64\x20" - "\x2f\xb1"; - -static const uint8_t kTwoPrimeKey[] = - "\x30\x82\x04\xa1\x02\x01\x00\x02\x82\x01\x01\x00\x93\x3a\x4f\xc9\x6a\x0a" - "\x6b\x28\x04\xfa\xb7\x05\x56\xdf\xa0\xaa\x4f\xaa\xab\x94\xa0\xa9\x25\xef" - "\xc5\x96\xd2\xd4\x66\x16\x62\x2c\x13\x7b\x91\xd0\x36\x0a\x10\x11\x6d\x7a" - "\x91\xb6\xe4\x74\x57\xc1\x3d\x7a\xbe\x24\x05\x3a\x04\x0b\x73\x91\x53\xb1" - "\x74\x10\xe1\x87\xdc\x91\x28\x9c\x1e\xe5\xf2\xb9\xfc\xa2\x48\x34\xb6\x78" - "\xed\x6d\x95\xfb\xf2\xc0\x4e\x1c\xa4\x15\x00\x3c\x8a\x68\x2b\xd6\xce\xd5" - "\xb3\x9f\x66\x02\xa7\x0d\x08\xa3\x23\x9b\xe5\x36\x96\x13\x22\xf9\x69\xa6" - "\x87\x88\x9b\x85\x3f\x83\x9c\xab\x1a\x1b\x6d\x8d\x16\xf4\x5e\xbd\xee\x4b" - "\x59\x56\xf8\x9d\x58\xcd\xd2\x83\x85\x59\x43\x84\x63\x4f\xe6\x1a\x86\x66" - "\x0d\xb5\xa0\x87\x89\xb6\x13\x82\x43\xda\x34\x92\x3b\x68\xc4\x95\x71\x2f" - "\x15\xc2\xe0\x43\x67\x3c\x08\x00\x36\x10\xc3\xb4\x46\x4c\x4e\x6e\xf5\x44" - "\xa9\x04\x44\x9d\xce\xc7\x05\x79\xee\x11\xcf\xaf\x2c\xd7\x9a\x32\xd3\xa5" - "\x30\xd4\x3a\x78\x43\x37\x74\x22\x90\x24\x04\x11\xd7\x95\x08\x52\xa4\x71" - "\x41\x68\x94\xb0\xa0\xc3\xec\x4e\xd2\xc4\x30\x71\x98\x64\x9c\xe3\x7c\x76" - "\xef\x33\xa3\x2b\xb1\x87\x63\xd2\x5c\x09\xfc\x90\x2d\x92\xf4\x57\x02\x01" - "\x03\x02\x82\x01\x00\x62\x26\xdf\xdb\x9c\x06\xf2\x1a\xad\xfc\x7a\x03\x8f" - "\x3f\xc0\x71\x8a\x71\xc7\xb8\x6b\x1b\x6e\x9f\xd9\x0f\x37\x38\x44\x0e\xec" - "\x1d\x62\x52\x61\x35\x79\x5c\x0a\xb6\x48\xfc\x61\x24\x98\x4d\x8f\xd6\x28" - "\xfc\x7e\xc2\xae\x26\xad\x5c\xf7\xb6\x37\xcb\xa2\xb5\xeb\xaf\xe8\x60\xc5" - "\xbd\x69\xee\xa1\xd1\x53\x16\xda\xcd\xce\xfb\x48\xf3\xb9\x52\xa1\xd5\x89" - "\x68\x6d\x63\x55\x7d\xb1\x9a\xc7\xe4\x89\xe3\xcd\x14\xee\xac\x6f\x5e\x05" - "\xc2\x17\xbd\x43\x79\xb9\x62\x17\x50\xf1\x19\xaf\xb0\x67\xae\x2a\x57\xbd" - "\xc7\x66\xbc\xf3\xb3\x64\xa1\xe3\x16\x74\x9e\xea\x02\x5c\xab\x94\xd8\x97" - "\x02\x42\x0c\x2c\xba\x54\xb9\xaf\xe0\x45\x93\xad\x7f\xb3\x10\x6a\x96\x50" - "\x4b\xaf\xcf\xc8\x27\x62\x2d\x83\xe9\x26\xc6\x94\xc1\xef\x5c\x8e\x06\x42" - "\x53\xe5\x56\xaf\xc2\x99\x01\xaa\x9a\x71\xbc\xe8\x21\x33\x2a\x2d\xa3\x36" - "\xac\x1b\x86\x19\xf8\xcd\x1f\x80\xa4\x26\x98\xb8\x9f\x62\x62\xd5\x1a\x7f" - "\xee\xdb\xdf\x81\xd3\x21\xdb\x33\x92\xee\xff\xe2\x2f\x32\x77\x73\x6a\x58" - "\xab\x21\xf3\xe3\xe1\xbc\x4f\x12\x72\xa6\xb5\xc2\xfb\x27\x9e\xc8\xca\xab" - "\x64\xa0\x87\x07\x9d\xef\xca\x0f\xdb\x02\x81\x81\x00\xe6\xd3\x4d\xc0\xa1" - "\x91\x0e\x62\xfd\xb0\xdd\xc6\x30\xb8\x8c\xcb\x14\xc1\x4b\x69\x30\xdd\xcd" - "\x86\x67\xcb\x37\x14\xc5\x03\xd2\xb4\x69\xab\x3d\xe5\x16\x81\x0f\xe5\x50" - "\xf4\x18\xb1\xec\xbc\x71\xe9\x80\x99\x06\xe4\xa3\xfe\x44\x84\x4a\x2d\x1e" - "\x07\x7f\x22\x70\x6d\x4f\xd4\x93\x0b\x8b\x99\xce\x1e\xab\xcd\x4c\xd2\xd3" - "\x10\x47\x5c\x09\x9f\x6d\x82\xc0\x08\x75\xe3\x3d\x83\xc2\x19\x50\x29\xec" - "\x1f\x84\x29\xcc\xf1\x56\xee\xbd\x54\x5d\xe6\x19\xdf\x0d\x1c\xa4\xbb\x0a" - "\xfe\x84\x44\x29\x1d\xf9\x5c\x80\x96\x5b\x24\xb4\xf7\x02\x1b\x02\x81\x81" - "\x00\xa3\x48\xf1\x9c\x58\xc2\x5f\x38\xfb\xd8\x12\x39\xf1\x8e\x73\xa1\xcf" - "\x78\x12\xe0\xed\x2a\xbb\xef\xac\x23\xb2\xbf\xd6\x0c\xe9\x6e\x1e\xab\xea" - "\x3f\x68\x36\xa7\x1f\xe5\xab\xe0\x86\xa5\x76\x32\x98\xdd\x75\xb5\x2b\xbc" - "\xcb\x8a\x03\x00\x7c\x2e\xca\xf8\xbc\x19\xe4\xe3\xa3\x31\xbd\x1d\x20\x2b" - "\x09\xad\x6f\x4c\xed\x48\xd4\xdf\x87\xf9\xf0\x46\xb9\x86\x4c\x4b\x71\xe7" - "\x48\x78\xdc\xed\xc7\x82\x02\x44\xd3\xa6\xb3\x10\x5f\x62\x81\xfc\xb8\xe4" - "\x0e\xf4\x1a\xdd\xab\x3f\xbc\x63\x79\x5b\x39\x69\x5e\xea\xa9\x15\xfe\x90" - "\xec\xda\x75\x02\x81\x81\x00\x99\xe2\x33\xd5\xc1\x0b\x5e\xec\xa9\x20\x93" - "\xd9\x75\xd0\x5d\xdc\xb8\x80\xdc\xf0\xcb\x3e\x89\x04\x45\x32\x24\xb8\x83" - "\x57\xe1\xcd\x9b\xc7\x7e\x98\xb9\xab\x5f\xee\x35\xf8\x10\x76\x9d\xd2\xf6" - "\x9b\xab\x10\xaf\x43\x17\xfe\xd8\x58\x31\x73\x69\x5a\x54\xc1\xa0\x48\xdf" - "\xe3\x0c\xb2\x5d\x11\x34\x14\x72\x88\xdd\xe1\xe2\x0a\xda\x3d\x5b\xbf\x9e" - "\x57\x2a\xb0\x4e\x97\x7e\x57\xd6\xbb\x8a\xc6\x9d\x6a\x58\x1b\xdd\xf6\x39" - "\xf4\x7e\x38\x3e\x99\x66\x94\xb3\x68\x6d\xd2\x07\x54\x58\x2d\x70\xbe\xa6" - "\x3d\xab\x0e\xe7\x6d\xcd\xfa\x01\x67\x02\x81\x80\x6c\xdb\x4b\xbd\x90\x81" - "\x94\xd0\xa7\xe5\x61\x7b\xf6\x5e\xf7\xc1\x34\xfa\xb7\x40\x9e\x1c\x7d\x4a" - "\x72\xc2\x77\x2a\x8e\xb3\x46\x49\x69\xc7\xf1\x7f\x9a\xcf\x1a\x15\x43\xc7" - "\xeb\x04\x6e\x4e\xcc\x65\xe8\xf9\x23\x72\x7d\xdd\x06\xac\xaa\xfd\x74\x87" - "\x50\x7d\x66\x98\x97\xc2\x21\x28\xbe\x15\x72\x06\x73\x9f\x88\x9e\x30\x8d" - "\xea\x5a\xa6\xa0\x2f\x26\x59\x88\x32\x4b\xef\x85\xa5\xe8\x9e\x85\x01\x56" - "\xd8\x8d\x19\xcc\xb5\x94\xec\x56\xa8\x7b\x42\xb4\xa2\xbc\x93\xc7\x7f\xd2" - "\xec\xfb\x92\x26\x46\x3f\x47\x1b\x63\xff\x0b\x48\x91\xa3\x02\x81\x80\x2c" - "\x4a\xb9\xa4\x46\x7b\xff\x50\x7e\xbf\x60\x47\x3b\x2b\x66\x82\xdc\x0e\x53" - "\x65\x71\xe9\xda\x2a\xb8\x32\x93\x42\xb7\xff\xea\x67\x66\xf1\xbc\x87\x28" - "\x65\x29\x79\xca\xab\x93\x56\xda\x95\xc1\x26\x44\x3d\x27\xc1\x91\xc6\x9b" - "\xd9\xec\x9d\xb7\x49\xe7\x16\xee\x99\x87\x50\x95\x81\xd4\x5c\x5b\x5a\x5d" - "\x0a\x43\xa5\xa7\x8f\x5a\x80\x49\xa0\xb7\x10\x85\xc7\xf4\x42\x34\x86\xb6" - "\x5f\x3f\x88\x9e\xc7\xf5\x59\x29\x39\x68\x48\xf2\xd7\x08\x5b\x92\x8e\x6b" - "\xea\xa5\x63\x5f\xc0\xfb\xe4\xe1\xb2\x7d\xb7\x40\xe9\x55\x06\xbf\x58\x25" - "\x6f"; - -static const uint8_t kTwoPrimeEncryptedMessage[] = { +// kPKCS1Ciphertext2 is "hello world" encrypted with kKey2 and RSAES-PKCS1-v1_5. +static const uint8_t kPKCS1Ciphertext2[] = { 0x63, 0x0a, 0x30, 0x45, 0x43, 0x11, 0x45, 0xb7, 0x99, 0x67, 0x90, 0x35, 0x37, 0x27, 0xff, 0xbc, 0xe0, 0xbf, 0xa6, 0xd1, 0x47, 0x50, 0xbb, 0x6c, 0x1c, 0xaa, 0x66, 0xf2, 0xff, 0x9d, 0x9a, 0xa6, 0xb4, 0x16, 0x63, 0xb0, @@ -324,8 +297,107 @@ static const uint8_t kTwoPrimeEncryptedMessage[] = { 0xc2, 0x73, 0x51, 0xb5, 0x03, 0xfb, 0xf9, 0xf6, 0xb5, 0x8d, 0x4e, 0x6c, 0x21, 0x0e, 0xf9, 0x97, 0x26, 0x57, 0xf3, 0x52, 0x72, 0x07, 0xf8, 0xb4, 0xcd, 0xb4, 0x39, 0xcf, 0xbf, 0x78, 0xcc, 0xb6, 0x87, 0xf9, 0xb7, 0x8b, - 0x6a, 0xce, 0x9f, 0xc8, -}; + 0x6a, 0xce, 0x9f, 0xc8}; + +// kOAEPCiphertext2 is a sample encryption of |kPlaintext| with |kKey2| using +// RSA OAEP, SHA-1, and no label. It was generated with: +// +// clang-format off +// openssl pkeyutl -encrypt -inkey key2.pem -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha1 -in plaintext | xxd -i +// clang-format on +static const uint8_t kOAEPCiphertext2[] = { + 0x56, 0x10, 0x50, 0x5b, 0x9a, 0xa8, 0x2e, 0x3f, 0x24, 0x06, 0x5b, 0xd3, + 0x06, 0x03, 0xde, 0x18, 0x69, 0xb2, 0x1b, 0xec, 0x12, 0x14, 0x76, 0xb9, + 0x8c, 0x7b, 0xf8, 0x4a, 0xaf, 0x87, 0xa8, 0x83, 0x49, 0x1c, 0x5e, 0xb4, + 0xe5, 0x9f, 0xff, 0x00, 0xf2, 0xdd, 0x34, 0xf0, 0x10, 0x9f, 0xca, 0xc6, + 0x02, 0x54, 0x23, 0xb2, 0xc3, 0xdc, 0x74, 0xa8, 0x9f, 0xd2, 0xdc, 0x87, + 0x48, 0x2f, 0x02, 0x8b, 0xf1, 0x7a, 0x91, 0x8d, 0x2d, 0x77, 0x7f, 0x6f, + 0x8f, 0x19, 0xde, 0x90, 0x54, 0x0d, 0x1b, 0x7b, 0x96, 0x81, 0x84, 0xf9, + 0x03, 0x48, 0xef, 0xab, 0xe5, 0x07, 0xcd, 0x7f, 0x01, 0xeb, 0x86, 0x8d, + 0x7e, 0x7e, 0xf8, 0x2a, 0x50, 0x02, 0xcd, 0xcb, 0xa5, 0xfe, 0xc2, 0x35, + 0x1f, 0x82, 0xef, 0xb9, 0x1d, 0x98, 0xd5, 0x07, 0x94, 0x37, 0x08, 0x13, + 0x1c, 0xc8, 0x19, 0x06, 0x13, 0x2d, 0x1c, 0xb2, 0x50, 0x34, 0xad, 0x99, + 0x3c, 0xe6, 0xce, 0x4c, 0x88, 0x6d, 0x96, 0xc8, 0x85, 0xd1, 0x5e, 0xd5, + 0x77, 0x02, 0x0a, 0xa9, 0x2a, 0xf1, 0xa3, 0x4a, 0x04, 0x65, 0x87, 0x05, + 0x6b, 0x34, 0x65, 0x1c, 0xef, 0x64, 0x11, 0xee, 0x23, 0x7e, 0x36, 0x4f, + 0x4c, 0x5d, 0xb7, 0xd6, 0x79, 0x30, 0xec, 0xdf, 0xde, 0x35, 0x32, 0xd0, + 0xb0, 0x7e, 0x26, 0x1f, 0xea, 0xa2, 0x78, 0x98, 0x4b, 0x77, 0x9b, 0x03, + 0x75, 0x33, 0x08, 0x72, 0x91, 0x0b, 0x77, 0xc0, 0x6e, 0xe1, 0x0f, 0x14, + 0xf1, 0xf0, 0xb9, 0xe5, 0x5f, 0x08, 0xc2, 0x92, 0x79, 0x2e, 0x6f, 0xef, + 0x2a, 0x1b, 0x31, 0x64, 0x36, 0x67, 0xf8, 0x1d, 0xc8, 0xb7, 0xc3, 0x15, + 0x6c, 0xd8, 0x35, 0x34, 0x44, 0xb2, 0x91, 0xf2, 0x07, 0x86, 0xd6, 0xfa, + 0x42, 0x04, 0xae, 0xc5, 0x17, 0x14, 0x61, 0x6f, 0x12, 0x84, 0xb9, 0x99, + 0x47, 0xd1, 0xdc, 0x3c}; + +// kKey3 is a DER-encoded RSAPrivateKey. It is a 1024-bit RSA private key with +// exponent 17. +static const uint8_t kKey3[] = { + 0x30, 0x82, 0x02, 0x5b, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xbb, + 0xf8, 0x2f, 0x09, 0x06, 0x82, 0xce, 0x9c, 0x23, 0x38, 0xac, 0x2b, 0x9d, + 0xa8, 0x71, 0xf7, 0x36, 0x8d, 0x07, 0xee, 0xd4, 0x10, 0x43, 0xa4, 0x40, + 0xd6, 0xb6, 0xf0, 0x74, 0x54, 0xf5, 0x1f, 0xb8, 0xdf, 0xba, 0xaf, 0x03, + 0x5c, 0x02, 0xab, 0x61, 0xea, 0x48, 0xce, 0xeb, 0x6f, 0xcd, 0x48, 0x76, + 0xed, 0x52, 0x0d, 0x60, 0xe1, 0xec, 0x46, 0x19, 0x71, 0x9d, 0x8a, 0x5b, + 0x8b, 0x80, 0x7f, 0xaf, 0xb8, 0xe0, 0xa3, 0xdf, 0xc7, 0x37, 0x72, 0x3e, + 0xe6, 0xb4, 0xb7, 0xd9, 0x3a, 0x25, 0x84, 0xee, 0x6a, 0x64, 0x9d, 0x06, + 0x09, 0x53, 0x74, 0x88, 0x34, 0xb2, 0x45, 0x45, 0x98, 0x39, 0x4e, 0xe0, + 0xaa, 0xb1, 0x2d, 0x7b, 0x61, 0xa5, 0x1f, 0x52, 0x7a, 0x9a, 0x41, 0xf6, + 0xc1, 0x68, 0x7f, 0xe2, 0x53, 0x72, 0x98, 0xca, 0x2a, 0x8f, 0x59, 0x46, + 0xf8, 0xe5, 0xfd, 0x09, 0x1d, 0xbd, 0xcb, 0x02, 0x01, 0x11, 0x02, 0x81, + 0x81, 0x00, 0xa5, 0xda, 0xfc, 0x53, 0x41, 0xfa, 0xf2, 0x89, 0xc4, 0xb9, + 0x88, 0xdb, 0x30, 0xc1, 0xcd, 0xf8, 0x3f, 0x31, 0x25, 0x1e, 0x06, 0x68, + 0xb4, 0x27, 0x84, 0x81, 0x38, 0x01, 0x57, 0x96, 0x41, 0xb2, 0x94, 0x10, + 0xb3, 0xc7, 0x99, 0x8d, 0x6b, 0xc4, 0x65, 0x74, 0x5e, 0x5c, 0x39, 0x26, + 0x69, 0xd6, 0x87, 0x0d, 0xa2, 0xc0, 0x82, 0xa9, 0x39, 0xe3, 0x7f, 0xdc, + 0xb8, 0x2e, 0xc9, 0x3e, 0xda, 0xc9, 0x7f, 0xf3, 0xad, 0x59, 0x50, 0xac, + 0xcf, 0xbc, 0x11, 0x1c, 0x76, 0xf1, 0xa9, 0x52, 0x94, 0x44, 0xe5, 0x6a, + 0xaf, 0x68, 0xc5, 0x6c, 0x09, 0x2c, 0xd3, 0x8d, 0xc3, 0xbe, 0xf5, 0xd2, + 0x0a, 0x93, 0x99, 0x26, 0xed, 0x4f, 0x74, 0xa1, 0x3e, 0xdd, 0xfb, 0xe1, + 0xa1, 0xce, 0xcc, 0x48, 0x94, 0xaf, 0x94, 0x28, 0xc2, 0xb7, 0xb8, 0x88, + 0x3f, 0xe4, 0x46, 0x3a, 0x4b, 0xc8, 0x5b, 0x1c, 0xb3, 0xc1, 0x02, 0x41, + 0x00, 0xee, 0xcf, 0xae, 0x81, 0xb1, 0xb9, 0xb3, 0xc9, 0x08, 0x81, 0x0b, + 0x10, 0xa1, 0xb5, 0x60, 0x01, 0x99, 0xeb, 0x9f, 0x44, 0xae, 0xf4, 0xfd, + 0xa4, 0x93, 0xb8, 0x1a, 0x9e, 0x3d, 0x84, 0xf6, 0x32, 0x12, 0x4e, 0xf0, + 0x23, 0x6e, 0x5d, 0x1e, 0x3b, 0x7e, 0x28, 0xfa, 0xe7, 0xaa, 0x04, 0x0a, + 0x2d, 0x5b, 0x25, 0x21, 0x76, 0x45, 0x9d, 0x1f, 0x39, 0x75, 0x41, 0xba, + 0x2a, 0x58, 0xfb, 0x65, 0x99, 0x02, 0x41, 0x00, 0xc9, 0x7f, 0xb1, 0xf0, + 0x27, 0xf4, 0x53, 0xf6, 0x34, 0x12, 0x33, 0xea, 0xaa, 0xd1, 0xd9, 0x35, + 0x3f, 0x6c, 0x42, 0xd0, 0x88, 0x66, 0xb1, 0xd0, 0x5a, 0x0f, 0x20, 0x35, + 0x02, 0x8b, 0x9d, 0x86, 0x98, 0x40, 0xb4, 0x16, 0x66, 0xb4, 0x2e, 0x92, + 0xea, 0x0d, 0xa3, 0xb4, 0x32, 0x04, 0xb5, 0xcf, 0xce, 0x33, 0x52, 0x52, + 0x4d, 0x04, 0x16, 0xa5, 0xa4, 0x41, 0xe7, 0x00, 0xaf, 0x46, 0x15, 0x03, + 0x02, 0x40, 0x54, 0x49, 0x4c, 0xa6, 0x3e, 0xba, 0x03, 0x37, 0xe4, 0xe2, + 0x40, 0x23, 0xfc, 0xd6, 0x9a, 0x5a, 0xeb, 0x07, 0xdd, 0xdc, 0x01, 0x83, + 0xa4, 0xd0, 0xac, 0x9b, 0x54, 0xb0, 0x51, 0xf2, 0xb1, 0x3e, 0xd9, 0x49, + 0x09, 0x75, 0xea, 0xb7, 0x74, 0x14, 0xff, 0x59, 0xc1, 0xf7, 0x69, 0x2e, + 0x9a, 0x2e, 0x20, 0x2b, 0x38, 0xfc, 0x91, 0x0a, 0x47, 0x41, 0x74, 0xad, + 0xc9, 0x3c, 0x1f, 0x67, 0xc9, 0x81, 0x02, 0x40, 0x47, 0x1e, 0x02, 0x90, + 0xff, 0x0a, 0xf0, 0x75, 0x03, 0x51, 0xb7, 0xf8, 0x78, 0x86, 0x4c, 0xa9, + 0x61, 0xad, 0xbd, 0x3a, 0x8a, 0x7e, 0x99, 0x1c, 0x5c, 0x05, 0x56, 0xa9, + 0x4c, 0x31, 0x46, 0xa7, 0xf9, 0x80, 0x3f, 0x8f, 0x6f, 0x8a, 0xe3, 0x42, + 0xe9, 0x31, 0xfd, 0x8a, 0xe4, 0x7a, 0x22, 0x0d, 0x1b, 0x99, 0xa4, 0x95, + 0x84, 0x98, 0x07, 0xfe, 0x39, 0xf9, 0x24, 0x5a, 0x98, 0x36, 0xda, 0x3d, + 0x02, 0x41, 0x00, 0xb0, 0x6c, 0x4f, 0xda, 0xbb, 0x63, 0x01, 0x19, 0x8d, + 0x26, 0x5b, 0xdb, 0xae, 0x94, 0x23, 0xb3, 0x80, 0xf2, 0x71, 0xf7, 0x34, + 0x53, 0x88, 0x50, 0x93, 0x07, 0x7f, 0xcd, 0x39, 0xe2, 0x11, 0x9f, 0xc9, + 0x86, 0x32, 0x15, 0x4f, 0x58, 0x83, 0xb1, 0x67, 0xa9, 0x67, 0xbf, 0x40, + 0x2b, 0x4e, 0x9e, 0x2e, 0x0f, 0x96, 0x56, 0xe6, 0x98, 0xea, 0x36, 0x66, + 0xed, 0xfb, 0x25, 0x79, 0x80, 0x39, 0xf7}; + +// kOAEPCiphertext3 is a sample encryption of |kPlaintext| with |kKey3| using +// RSA OAEP, SHA-1, and no label. +static const uint8_t kOAEPCiphertext3[] = { + 0xb8, 0x24, 0x6b, 0x56, 0xa6, 0xed, 0x58, 0x81, 0xae, 0xb5, 0x85, 0xd9, + 0xa2, 0x5b, 0x2a, 0xd7, 0x90, 0xc4, 0x17, 0xe0, 0x80, 0x68, 0x1b, 0xf1, + 0xac, 0x2b, 0xc3, 0xde, 0xb6, 0x9d, 0x8b, 0xce, 0xf0, 0xc4, 0x36, 0x6f, + 0xec, 0x40, 0x0a, 0xf0, 0x52, 0xa7, 0x2e, 0x9b, 0x0e, 0xff, 0xb5, 0xb3, + 0xf2, 0xf1, 0x92, 0xdb, 0xea, 0xca, 0x03, 0xc1, 0x27, 0x40, 0x05, 0x71, + 0x13, 0xbf, 0x1f, 0x06, 0x69, 0xac, 0x22, 0xe9, 0xf3, 0xa7, 0x85, 0x2e, + 0x3c, 0x15, 0xd9, 0x13, 0xca, 0xb0, 0xb8, 0x86, 0x3a, 0x95, 0xc9, 0x92, + 0x94, 0xce, 0x86, 0x74, 0x21, 0x49, 0x54, 0x61, 0x03, 0x46, 0xf4, 0xd4, + 0x74, 0xb2, 0x6f, 0x7c, 0x48, 0xb4, 0x2e, 0xe6, 0x8e, 0x1f, 0x57, 0x2a, + 0x1f, 0xc4, 0x02, 0x6a, 0xc4, 0x56, 0xb4, 0xf5, 0x9f, 0x7b, 0x62, 0x1e, + 0xa1, 0xb9, 0xd8, 0x8f, 0x64, 0x20, 0x2f, 0xb1}; // kEstonianRSAKey is an RSAPublicKey encoded with a negative modulus. See // https://crbug.com/532048. @@ -384,14 +456,12 @@ static const uint8_t kExponent1RSAKey[] = { }; struct RSAEncryptParam { - const uint8_t *der; - size_t der_len; - const uint8_t *oaep_ciphertext; - size_t oaep_ciphertext_len; + bssl::Span der; + bssl::Span oaep_ciphertext; } kRSAEncryptParams[] = { - {kKey1, sizeof(kKey1) - 1, kOAEPCiphertext1, sizeof(kOAEPCiphertext1) - 1}, - {kKey2, sizeof(kKey2) - 1, kOAEPCiphertext2, sizeof(kOAEPCiphertext2) - 1}, - {kKey3, sizeof(kKey3) - 1, kOAEPCiphertext3, sizeof(kOAEPCiphertext3) - 1}, + {kKey1, kOAEPCiphertext1}, + {kKey2, kOAEPCiphertext2}, + {kKey3, kOAEPCiphertext3}, }; class RSAEncryptTest : public testing::TestWithParam {}; @@ -400,7 +470,7 @@ TEST_P(RSAEncryptTest, TestKey) { // Construct an RSA key in different ways. const auto ¶m = GetParam(); bssl::UniquePtr parsed( - RSA_private_key_from_bytes(param.der, param.der_len)); + RSA_private_key_from_bytes(param.der.data(), param.der.size())); ASSERT_TRUE(parsed); EXPECT_TRUE(RSA_get0_e(parsed.get())); EXPECT_TRUE(RSA_get0_d(parsed.get())); @@ -437,64 +507,63 @@ TEST_P(RSAEncryptTest, TestKey) { {parsed.get(), constructed.get(), no_crt.get(), no_e.get(), pub.get()}) { EXPECT_TRUE(RSA_check_key(key)); - uint8_t ciphertext[256], plaintext[256]; + std::vector ciphertext(RSA_size(key)), plaintext(RSA_size(key)); size_t ciphertext_len = 0, plaintext_len = 0; if (RSA_get0_e(key) != nullptr) { // Test that PKCS#1 v1.5 encryption round-trips. - ASSERT_TRUE(RSA_encrypt(key, &ciphertext_len, ciphertext, - sizeof(ciphertext), kPlaintext, kPlaintextLen, + ASSERT_TRUE(RSA_encrypt(key, &ciphertext_len, ciphertext.data(), + ciphertext.size(), kPlaintext, sizeof(kPlaintext), RSA_PKCS1_PADDING)); EXPECT_EQ(RSA_size(key), ciphertext_len); - ASSERT_TRUE(RSA_decrypt(parsed.get(), &plaintext_len, plaintext, - sizeof(plaintext), ciphertext, ciphertext_len, - RSA_PKCS1_PADDING)); - EXPECT_EQ(Bytes(kPlaintext, kPlaintextLen), - Bytes(plaintext, plaintext_len)); + ASSERT_TRUE(RSA_decrypt(parsed.get(), &plaintext_len, plaintext.data(), + plaintext.size(), ciphertext.data(), + ciphertext_len, RSA_PKCS1_PADDING)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(plaintext.data(), plaintext_len)); // Test that OAEP encryption round-trips. ciphertext_len = 0; - ASSERT_TRUE(RSA_encrypt(key, &ciphertext_len, ciphertext, - sizeof(ciphertext), kPlaintext, kPlaintextLen, + ASSERT_TRUE(RSA_encrypt(key, &ciphertext_len, ciphertext.data(), + ciphertext.size(), kPlaintext, sizeof(kPlaintext), RSA_PKCS1_OAEP_PADDING)); EXPECT_EQ(RSA_size(key), ciphertext_len); plaintext_len = 0; - ASSERT_TRUE(RSA_decrypt(parsed.get(), &plaintext_len, plaintext, - sizeof(plaintext), ciphertext, ciphertext_len, - RSA_PKCS1_OAEP_PADDING)); - EXPECT_EQ(Bytes(kPlaintext, kPlaintextLen), - Bytes(plaintext, plaintext_len)); + ASSERT_TRUE(RSA_decrypt(parsed.get(), &plaintext_len, plaintext.data(), + plaintext.size(), ciphertext.data(), + ciphertext_len, RSA_PKCS1_OAEP_PADDING)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(plaintext.data(), plaintext_len)); } if (RSA_get0_d(key) != nullptr) { // |oaep_ciphertext| should decrypt to |kPlaintext|. plaintext_len = 0; - ASSERT_TRUE(RSA_decrypt(key, &plaintext_len, plaintext, sizeof(plaintext), - param.oaep_ciphertext, param.oaep_ciphertext_len, + ASSERT_TRUE(RSA_decrypt(key, &plaintext_len, plaintext.data(), + plaintext.size(), param.oaep_ciphertext.data(), + param.oaep_ciphertext.size(), RSA_PKCS1_OAEP_PADDING)); - EXPECT_EQ(Bytes(kPlaintext, kPlaintextLen), - Bytes(plaintext, plaintext_len)); + EXPECT_EQ(Bytes(kPlaintext), Bytes(plaintext.data(), plaintext_len)); // Try decrypting corrupted ciphertexts. - OPENSSL_memcpy(ciphertext, param.oaep_ciphertext, - param.oaep_ciphertext_len); - for (size_t i = 0; i < param.oaep_ciphertext_len; i++) { + ciphertext.assign( + param.oaep_ciphertext.data(), + param.oaep_ciphertext.data() + param.oaep_ciphertext.size()); + for (size_t i = 0; i < ciphertext.size(); i++) { SCOPED_TRACE(i); ciphertext[i] ^= 1; - EXPECT_FALSE(RSA_decrypt( - key, &plaintext_len, plaintext, sizeof(plaintext), ciphertext, - param.oaep_ciphertext_len, RSA_PKCS1_OAEP_PADDING)); + EXPECT_FALSE(RSA_decrypt(key, &plaintext_len, plaintext.data(), + plaintext.size(), ciphertext.data(), + ciphertext.size(), RSA_PKCS1_OAEP_PADDING)); ERR_clear_error(); ciphertext[i] ^= 1; } // Test truncated ciphertexts. - for (size_t len = 0; len < param.oaep_ciphertext_len; len++) { + for (size_t len = 0; len < ciphertext.size(); len++) { SCOPED_TRACE(len); - EXPECT_FALSE(RSA_decrypt(key, &plaintext_len, plaintext, - sizeof(plaintext), ciphertext, len, + EXPECT_FALSE(RSA_decrypt(key, &plaintext_len, plaintext.data(), + plaintext.size(), ciphertext.data(), len, RSA_PKCS1_OAEP_PADDING)); ERR_clear_error(); } @@ -506,29 +575,28 @@ INSTANTIATE_TEST_SUITE_P(All, RSAEncryptTest, testing::ValuesIn(kRSAEncryptParams)); TEST(RSATest, TestDecrypt) { - bssl::UniquePtr rsa( - RSA_private_key_from_bytes(kTwoPrimeKey, sizeof(kTwoPrimeKey) - 1)); + bssl::UniquePtr rsa(RSA_private_key_from_bytes(kKey2, sizeof(kKey2))); ASSERT_TRUE(rsa); EXPECT_TRUE(RSA_check_key(rsa.get())); - uint8_t out[256]; + std::vector out(RSA_size(rsa.get())); size_t out_len; - ASSERT_TRUE(RSA_decrypt( - rsa.get(), &out_len, out, sizeof(out), kTwoPrimeEncryptedMessage, - sizeof(kTwoPrimeEncryptedMessage), RSA_PKCS1_PADDING)); - EXPECT_EQ(Bytes("hello world"), Bytes(out, out_len)); + ASSERT_TRUE(RSA_decrypt(rsa.get(), &out_len, out.data(), out.size(), + kPKCS1Ciphertext2, sizeof(kPKCS1Ciphertext2), + RSA_PKCS1_PADDING)); + out.resize(out_len); + EXPECT_EQ(Bytes("hello world"), Bytes(out)); } TEST(RSATest, CheckFIPS) { - bssl::UniquePtr rsa( - RSA_private_key_from_bytes(kFIPSKey, sizeof(kFIPSKey) - 1)); + bssl::UniquePtr rsa(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); ASSERT_TRUE(rsa); EXPECT_TRUE(RSA_check_fips(rsa.get())); // Check that RSA_check_fips works on a public key. bssl::UniquePtr pub( - RSA_public_key_from_bytes(kFIPSPublicKey, sizeof(kFIPSPublicKey) - 1)); + RSA_public_key_from_bytes(kKey1Public, sizeof(kKey1Public))); ASSERT_TRUE(pub); EXPECT_TRUE(RSA_check_fips(pub.get())); } @@ -586,8 +654,7 @@ TEST(RSATest, BadKey) { TEST(RSATest, ASN1) { // Test that private keys may be decoded. - bssl::UniquePtr rsa( - RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1)); + bssl::UniquePtr rsa(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); ASSERT_TRUE(rsa); // Test that the serialization round-trips. @@ -595,7 +662,7 @@ TEST(RSATest, ASN1) { size_t der_len; ASSERT_TRUE(RSA_private_key_to_bytes(&der, &der_len, rsa.get())); bssl::UniquePtr delete_der(der); - EXPECT_EQ(Bytes(kKey1, sizeof(kKey1) - 1), Bytes(der, der_len)); + EXPECT_EQ(Bytes(kKey1), Bytes(der, der_len)); // Test that serializing public keys works. ASSERT_TRUE(RSA_public_key_to_bytes(&der, &der_len, rsa.get())); @@ -679,20 +746,18 @@ TEST(RSATest, RoundKeyLengths) { TEST(RSATest, BlindingDisabled) { bssl::UniquePtr rsa( - RSA_private_key_from_bytes(kTwoPrimeKey, sizeof(kTwoPrimeKey) - 1)); + RSA_private_key_from_bytes(kKey2, sizeof(kKey2))); ASSERT_TRUE(rsa); rsa->flags |= RSA_FLAG_NO_BLINDING; - uint8_t sig[256]; - ASSERT_GE(sizeof(sig), RSA_size(rsa.get())); - + std::vector sig(RSA_size(rsa.get())); static const uint8_t kZeros[32] = {0}; unsigned sig_len; - ASSERT_TRUE( - RSA_sign(NID_sha256, kZeros, sizeof(kZeros), sig, &sig_len, rsa.get())); - EXPECT_TRUE( - RSA_verify(NID_sha256, kZeros, sizeof(kZeros), sig, sig_len, rsa.get())); + ASSERT_TRUE(RSA_sign(NID_sha256, kZeros, sizeof(kZeros), sig.data(), &sig_len, + rsa.get())); + EXPECT_TRUE(RSA_verify(NID_sha256, kZeros, sizeof(kZeros), sig.data(), + sig_len, rsa.get())); } TEST(RSATest, CheckKey) { @@ -1007,15 +1072,14 @@ TEST(RSATest, KeygenInternalRetry) { TEST(RSATest, OverwriteKey) { // Make a key and perform public and private key operations with it, so that // all derived values are filled in. - bssl::UniquePtr key1( - RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1)); + bssl::UniquePtr key1(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); ASSERT_TRUE(key1); ASSERT_TRUE(RSA_check_key(key1.get())); size_t len; std::vector ciphertext(RSA_size(key1.get())); ASSERT_TRUE(RSA_encrypt(key1.get(), &len, ciphertext.data(), - ciphertext.size(), kPlaintext, kPlaintextLen, + ciphertext.size(), kPlaintext, sizeof(kPlaintext), RSA_PKCS1_OAEP_PADDING)); ciphertext.resize(len); @@ -1024,11 +1088,10 @@ TEST(RSATest, OverwriteKey) { plaintext.size(), ciphertext.data(), ciphertext.size(), RSA_PKCS1_OAEP_PADDING)); plaintext.resize(len); - EXPECT_EQ(Bytes(plaintext), Bytes(kPlaintext, kPlaintextLen)); + EXPECT_EQ(Bytes(plaintext), Bytes(kPlaintext)); // Overwrite |key1| with the contents of |key2|. - bssl::UniquePtr key2( - RSA_private_key_from_bytes(kKey2, sizeof(kKey2) - 1)); + bssl::UniquePtr key2(RSA_private_key_from_bytes(kKey2, sizeof(kKey2))); ASSERT_TRUE(key2); auto copy_rsa_fields = [](RSA *dst, const RSA *src) { @@ -1057,8 +1120,8 @@ TEST(RSATest, OverwriteKey) { auto check_rsa_compatible = [&](RSA *enc, RSA *dec) { ciphertext.resize(RSA_size(enc)); - ASSERT_TRUE(RSA_encrypt(enc, &len, ciphertext.data(), - ciphertext.size(), kPlaintext, kPlaintextLen, + ASSERT_TRUE(RSA_encrypt(enc, &len, ciphertext.data(), ciphertext.size(), + kPlaintext, sizeof(kPlaintext), RSA_PKCS1_OAEP_PADDING)); ciphertext.resize(len); @@ -1067,7 +1130,7 @@ TEST(RSATest, OverwriteKey) { plaintext.size(), ciphertext.data(), ciphertext.size(), RSA_PKCS1_OAEP_PADDING)); plaintext.resize(len); - EXPECT_EQ(Bytes(plaintext), Bytes(kPlaintext, kPlaintextLen)); + EXPECT_EQ(Bytes(plaintext), Bytes(kPlaintext)); }; ASSERT_NO_FATAL_FAILURE( @@ -1093,8 +1156,7 @@ TEST(RSATest, OverwriteKey) { // Test that RSA keys do not support operations will cleanly fail them. TEST(RSATest, MissingParameters) { - bssl::UniquePtr sample( - RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1)); + bssl::UniquePtr sample(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); ASSERT_TRUE(sample); // Make a sample signature. @@ -1119,7 +1181,7 @@ TEST(RSATest, MissingParameters) { size_t len; EXPECT_FALSE(RSA_decrypt(rsa.get(), &len, out.data(), out.size(), - kOAEPCiphertext1, sizeof(kOAEPCiphertext1) - 1, + kOAEPCiphertext1, sizeof(kOAEPCiphertext1), RSA_PKCS1_OAEP_PADDING)); err = ERR_get_error(); EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err)); @@ -1137,7 +1199,7 @@ TEST(RSATest, MissingParameters) { EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err)); EXPECT_FALSE(RSA_encrypt(rsa.get(), &len, out.data(), out.size(), kPlaintext, - kPlaintextLen, RSA_PKCS1_OAEP_PADDING)); + sizeof(kPlaintext), RSA_PKCS1_OAEP_PADDING)); err = ERR_get_error(); EXPECT_EQ(ERR_LIB_RSA, ERR_GET_LIB(err)); EXPECT_EQ(RSA_R_VALUE_MISSING, ERR_GET_REASON(err)); @@ -1154,7 +1216,7 @@ TEST(RSATest, Negative) { }; bssl::UniquePtr key( - RSA_private_key_from_bytes(kFIPSKey, sizeof(kFIPSKey) - 1)); + RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); ASSERT_TRUE(key); const BIGNUM *n = RSA_get0_n(key.get()); bssl::UniquePtr neg_n = dup_neg(n); @@ -1194,10 +1256,9 @@ TEST(RSATest, Negative) { } TEST(RSATest, LargeE) { - // Test an RSA key with large e by swapping d and e in kFIPSKey. Since e is - // small, e mod (p-1) and e mod (q-1) will simply be e. - bssl::UniquePtr key( - RSA_private_key_from_bytes(kFIPSKey, sizeof(kFIPSKey) - 1)); + // Test an RSA key with large e by swapping d and e in kKey1. + // Since e is small, e mod (p-1) and e mod (q-1) will simply be e. + bssl::UniquePtr key(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); ASSERT_TRUE(key); const BIGNUM *n = RSA_get0_n(key.get()); const BIGNUM *e = RSA_get0_e(key.get()); @@ -1266,6 +1327,97 @@ TEST(RSATest, LargeE) { EXPECT_FALSE(RSA_new_public_key_large_e(n, bad_e.get())); } +// Test minimum key limits on RSA keys. Currently, we require a minimum of +// 512-bit RSA. +// +// TODO(crbug.com/boringssl/607): Raise this limit. 512-bit RSA was factored in +// 1999. +TEST(RSATest, SmallKey) { + static const uint8_t kRSA511Private[] = { + 0x30, 0x82, 0x01, 0x39, 0x02, 0x01, 0x00, 0x02, 0x40, 0x56, 0xc1, 0x3d, + 0xb3, 0x4f, 0xe4, 0xe9, 0x2f, 0x29, 0x8a, 0xd3, 0xe2, 0xfe, 0xb3, 0x3b, + 0x88, 0x02, 0x8b, 0xdd, 0x44, 0xb5, 0x41, 0x4b, 0x43, 0x97, 0x93, 0x75, + 0x78, 0x4b, 0x10, 0x30, 0x88, 0xce, 0xd2, 0x32, 0xe3, 0x9e, 0xda, 0x68, + 0xc9, 0xc3, 0xcd, 0xa1, 0xde, 0xbc, 0x4a, 0xeb, 0x37, 0x60, 0xd2, 0x82, + 0x2f, 0x5d, 0x21, 0x3b, 0x88, 0x0e, 0x12, 0x44, 0x4d, 0x5d, 0x44, 0xc1, + 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x40, 0x08, 0xe5, 0xf5, 0x30, + 0x29, 0x27, 0xaf, 0x8b, 0x38, 0xd5, 0x96, 0x7a, 0x17, 0xe9, 0xc6, 0x57, + 0x62, 0xfb, 0x79, 0x8c, 0x8c, 0x92, 0xcf, 0xe7, 0x74, 0xea, 0x99, 0x07, + 0xe7, 0x9b, 0x17, 0x7f, 0x30, 0x9f, 0x86, 0x55, 0x15, 0x8d, 0xe6, 0xa8, + 0x0d, 0x7b, 0x42, 0x41, 0x27, 0x18, 0x29, 0x55, 0xb1, 0x08, 0x07, 0x2a, + 0x4e, 0x67, 0x19, 0x9c, 0xe3, 0xe4, 0x84, 0xd6, 0x82, 0x62, 0xd4, 0x81, + 0x02, 0x21, 0x00, 0xcd, 0x5a, 0x9b, 0x23, 0x3d, 0xb5, 0x9c, 0x56, 0xbc, + 0xc5, 0x56, 0xcf, 0x77, 0x58, 0xc0, 0x62, 0x72, 0xa0, 0x85, 0x77, 0xf4, + 0xc3, 0xf8, 0x47, 0x6d, 0xc0, 0x8f, 0x18, 0x77, 0xee, 0xf1, 0xad, 0x02, + 0x20, 0x6c, 0x26, 0xaa, 0x8a, 0xaf, 0x7b, 0x9f, 0x35, 0x19, 0x08, 0xc2, + 0xa0, 0x9f, 0x4e, 0x9e, 0x62, 0x48, 0xb1, 0x7c, 0x0e, 0x68, 0x63, 0x0d, + 0x05, 0x76, 0x73, 0x0a, 0xa0, 0xb3, 0xed, 0x6d, 0xb1, 0x02, 0x21, 0x00, + 0xc2, 0x26, 0x1c, 0xb0, 0xa7, 0xe2, 0x31, 0x4a, 0x4c, 0x34, 0xe2, 0xcb, + 0x49, 0x51, 0xce, 0xaa, 0x05, 0x27, 0xc0, 0xa8, 0x55, 0xf0, 0x85, 0xa6, + 0xba, 0x9c, 0x28, 0x6e, 0x00, 0xce, 0x17, 0x0d, 0x02, 0x20, 0x65, 0x51, + 0xb0, 0x11, 0xaf, 0x26, 0xbc, 0x57, 0x4d, 0x35, 0xb4, 0xc8, 0x2f, 0x96, + 0xc2, 0xb0, 0xc6, 0xf3, 0x67, 0x8a, 0x43, 0xe7, 0x0f, 0xaa, 0xdf, 0x76, + 0x15, 0x2d, 0xca, 0x82, 0x93, 0x71, 0x02, 0x21, 0x00, 0x9e, 0x89, 0x74, + 0x15, 0x7e, 0x73, 0x43, 0xa0, 0x1e, 0xa9, 0xa5, 0x9f, 0xad, 0xf1, 0xa0, + 0xfa, 0x13, 0x86, 0x10, 0x3f, 0xb0, 0xba, 0x3f, 0x45, 0x87, 0x13, 0x02, + 0x86, 0xa4, 0xa4, 0x31, 0x92}; + static const uint8_t kRSA511Public[] = { + 0x30, 0x47, 0x02, 0x40, 0x56, 0xc1, 0x3d, 0xb3, 0x4f, 0xe4, 0xe9, + 0x2f, 0x29, 0x8a, 0xd3, 0xe2, 0xfe, 0xb3, 0x3b, 0x88, 0x02, 0x8b, + 0xdd, 0x44, 0xb5, 0x41, 0x4b, 0x43, 0x97, 0x93, 0x75, 0x78, 0x4b, + 0x10, 0x30, 0x88, 0xce, 0xd2, 0x32, 0xe3, 0x9e, 0xda, 0x68, 0xc9, + 0xc3, 0xcd, 0xa1, 0xde, 0xbc, 0x4a, 0xeb, 0x37, 0x60, 0xd2, 0x82, + 0x2f, 0x5d, 0x21, 0x3b, 0x88, 0x0e, 0x12, 0x44, 0x4d, 0x5d, 0x44, + 0xc1, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01}; + static const uint8_t kRSA512Private[] = { + 0x30, 0x82, 0x01, 0x3a, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xa5, 0x44, + 0x8f, 0x3d, 0xa2, 0x0b, 0x20, 0xc6, 0xac, 0x10, 0xc1, 0x27, 0x11, 0xf0, + 0x43, 0x5d, 0x05, 0xb7, 0x0f, 0x80, 0x3b, 0x9b, 0x85, 0xf1, 0x7a, 0x0e, + 0xbd, 0x72, 0xed, 0x8a, 0xdc, 0xa1, 0xaa, 0xd4, 0x53, 0xcb, 0x65, 0x78, + 0x4b, 0x30, 0x6b, 0x52, 0x51, 0xee, 0xcd, 0x2f, 0x90, 0x7b, 0xd1, 0x9c, + 0xe9, 0x79, 0x98, 0x58, 0xe3, 0x47, 0x35, 0xa7, 0xcd, 0x6a, 0x71, 0x38, + 0xb5, 0x0d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x41, 0x00, 0x94, 0x24, + 0x82, 0xa9, 0xe2, 0xa9, 0x4a, 0xf6, 0x0b, 0xa2, 0xf1, 0x21, 0x0e, 0x89, + 0x6a, 0x38, 0xe6, 0x38, 0x93, 0xe2, 0x84, 0x8c, 0x02, 0x62, 0xd4, 0xe0, + 0x85, 0x9d, 0x91, 0xa4, 0xd9, 0xe3, 0x77, 0x6c, 0x26, 0x85, 0xf6, 0x2e, + 0x0a, 0xe4, 0x18, 0x73, 0x06, 0x9a, 0xea, 0xde, 0x78, 0x65, 0xba, 0x7a, + 0xdb, 0xc0, 0x3b, 0xf7, 0x29, 0x1e, 0x43, 0xed, 0xaf, 0xf5, 0xaf, 0xa8, + 0xdf, 0x01, 0x02, 0x21, 0x00, 0xdb, 0x93, 0x05, 0x2d, 0xf3, 0xdf, 0xe4, + 0x31, 0xef, 0x50, 0xc7, 0x54, 0x0f, 0x08, 0x5d, 0x50, 0x42, 0xfa, 0xb9, + 0x20, 0x37, 0x98, 0xd3, 0xc0, 0x64, 0x2f, 0xb6, 0xe4, 0xb2, 0xfe, 0xe5, + 0x6d, 0x02, 0x21, 0x00, 0xc0, 0xaf, 0x3a, 0x1f, 0xd9, 0xba, 0x5a, 0x6a, + 0xc2, 0x80, 0x2e, 0x7b, 0x65, 0x3d, 0x8a, 0x76, 0xae, 0x4b, 0x5a, 0xff, + 0x7a, 0x9a, 0x5e, 0xc2, 0xfa, 0x07, 0xfb, 0x2d, 0x0c, 0x16, 0x6a, 0x21, + 0x02, 0x20, 0x06, 0xf3, 0xb9, 0xb7, 0x41, 0xc0, 0x75, 0xfe, 0x2a, 0xc0, + 0x98, 0xff, 0x0d, 0x56, 0xcb, 0x75, 0x8e, 0x19, 0x58, 0x21, 0x30, 0x01, + 0x73, 0xba, 0xe4, 0xb1, 0x2a, 0x0e, 0x45, 0xa8, 0x92, 0x65, 0x02, 0x20, + 0x25, 0xcd, 0xbb, 0x3f, 0xa8, 0x7e, 0x11, 0x63, 0x44, 0xc9, 0xd5, 0x54, + 0xcc, 0x66, 0x28, 0x96, 0x64, 0x57, 0xd0, 0x80, 0xb3, 0x53, 0x3a, 0x28, + 0x52, 0xd9, 0xe2, 0x03, 0xd2, 0x8d, 0x4b, 0x41, 0x02, 0x20, 0x09, 0x30, + 0xd9, 0xfd, 0xad, 0x31, 0x1a, 0x38, 0xb7, 0x71, 0x06, 0xed, 0x49, 0xa6, + 0xe2, 0xec, 0x42, 0xc2, 0x8e, 0xe9, 0xec, 0xf7, 0x3e, 0xb7, 0x4a, 0x5e, + 0x2e, 0xa2, 0x7a, 0x8d, 0xa4, 0x95}; + static const uint8_t kRSA512Public[] = { + 0x30, 0x48, 0x02, 0x41, 0x00, 0xa5, 0x44, 0x8f, 0x3d, 0xa2, 0x0b, + 0x20, 0xc6, 0xac, 0x10, 0xc1, 0x27, 0x11, 0xf0, 0x43, 0x5d, 0x05, + 0xb7, 0x0f, 0x80, 0x3b, 0x9b, 0x85, 0xf1, 0x7a, 0x0e, 0xbd, 0x72, + 0xed, 0x8a, 0xdc, 0xa1, 0xaa, 0xd4, 0x53, 0xcb, 0x65, 0x78, 0x4b, + 0x30, 0x6b, 0x52, 0x51, 0xee, 0xcd, 0x2f, 0x90, 0x7b, 0xd1, 0x9c, + 0xe9, 0x79, 0x98, 0x58, 0xe3, 0x47, 0x35, 0xa7, 0xcd, 0x6a, 0x71, + 0x38, 0xb5, 0x0d, 0x02, 0x03, 0x01, 0x00, 0x01}; + + bssl::UniquePtr rsa( + RSA_public_key_from_bytes(kRSA511Public, sizeof(kRSA511Public))); + EXPECT_FALSE(rsa); + rsa.reset(RSA_private_key_from_bytes(kRSA511Private, sizeof(kRSA511Private))); + EXPECT_FALSE(rsa); + + rsa.reset(RSA_public_key_from_bytes(kRSA512Public, sizeof(kRSA512Public))); + EXPECT_TRUE(rsa); + rsa.reset(RSA_private_key_from_bytes(kRSA512Private, sizeof(kRSA512Private))); + EXPECT_TRUE(rsa); +} + #if !defined(BORINGSSL_SHARED_LIBRARY) TEST(RSATest, SqrtTwo) { bssl::UniquePtr sqrt(BN_new()), pow2(BN_new()); @@ -1299,15 +1451,15 @@ TEST(RSATest, SqrtTwo) { #if defined(OPENSSL_THREADS) TEST(RSATest, Threads) { bssl::UniquePtr rsa_template( - RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1)); + RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); ASSERT_TRUE(rsa_template); const uint8_t kDummyHash[32] = {0}; - uint8_t sig[256]; - unsigned sig_len = sizeof(sig); - ASSERT_LE(RSA_size(rsa_template.get()), sizeof(sig)); - EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), sig, + std::vector sig(RSA_size(rsa_template.get())); + unsigned sig_len; + EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), sig.data(), &sig_len, rsa_template.get())); + sig.resize(sig_len); // RSA keys may be assembled piece-meal and then used in parallel between // threads, which requires internal locking to create some derived properties. @@ -1338,17 +1490,17 @@ TEST(RSATest, Threads) { EXPECT_EQ(0, BN_cmp(d, rsa_template->d)); }; auto sign = [&] { - uint8_t sig2[256]; - unsigned sig2_len = sizeof(sig2); - ASSERT_LE(RSA_size(rsa.get()), sizeof(sig2)); - EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), sig2, - &sig2_len, rsa.get())); + std::vector sig2(RSA_size(rsa.get())); + unsigned sig2_len; + EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), + sig2.data(), &sig2_len, rsa.get())); + sig2.resize(sig2_len); // RSASSA-PKCS1-v1_5 is deterministic. - EXPECT_EQ(Bytes(sig, sig_len), Bytes(sig2, sig2_len)); + EXPECT_EQ(Bytes(sig), Bytes(sig2)); }; auto verify = [&] { - EXPECT_TRUE(RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), sig, - sig_len, rsa.get())); + EXPECT_TRUE(RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), + sig.data(), sig.size(), rsa.get())); }; std::vector threads; @@ -1375,8 +1527,7 @@ TEST(RSATest, Threads) { #if defined(OPENSSL_TSAN) || \ (defined(OPENSSL_X86_64) && !defined(OPENSSL_FREEBSD)) TEST(RSATest, DISABLED_BlindingCacheConcurrency) { - bssl::UniquePtr rsa( - RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1)); + bssl::UniquePtr rsa(RSA_private_key_from_bytes(kKey1, sizeof(kKey1))); ASSERT_TRUE(rsa); #if defined(OPENSSL_TSAN) @@ -1389,13 +1540,11 @@ TEST(RSATest, DISABLED_BlindingCacheConcurrency) { const uint8_t kDummyHash[32] = {0}; auto worker = [&] { - uint8_t sig[256]; - ASSERT_LE(RSA_size(rsa.get()), sizeof(sig)); - + std::vector sig(RSA_size(rsa.get())); for (size_t i = 0; i < kSignaturesPerThread; i++) { - unsigned sig_len = sizeof(sig); - EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), sig, - &sig_len, rsa.get())); + unsigned sig_len = sig.size(); + EXPECT_TRUE(RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), + sig.data(), &sig_len, rsa.get())); } };