Add extra RSA private keys to unit tests

Merge from Widevine repo of http://go/wvgerrit/128047

There have been some failures with various RSA private keys. We add
them to the unit tests to make sure that OEMCrypto is able to load
these types of keys:
* Shorter: than normal private exponents. This seems to occur
  occasionally even with Euler totients. But it occurs more with
  Carmichael totients.
* 0-leading-byte: private exponents. This also occurs naturally for
  both Euler and Carmichael totients.
* Carmichael: vs Euler totients. I think we may already have tests for
  this. But just in case.

Bug: 190450051
Test: ran unit tests on bonito (and they passed!)
Change-Id: Id64ec738479eb8a0f77e253bace319cebe918d3f
This commit is contained in:
Fred Gylys-Colwell
2021-06-29 06:20:13 +00:00
parent 61218ec6cf
commit 052016eb57
2 changed files with 1130 additions and 35 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -50,6 +50,7 @@
#include "log.h"
#include "oec_decrypt_fallback_chain.h"
#include "oec_device_features.h"
#include "oec_extra_test_keys.h"
#include "oec_session_util.h"
#include "oec_test_data.h"
#include "oemcrypto_session_tests_helper.h"
@@ -4555,6 +4556,8 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange1_API16) {
provisioning_messages.PrepareSession(keybox_);
ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse());
// Encrypt and sign once, so that we can use the size of the response.
ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse());
provisioning_messages.core_response().enc_private_key.offset =
provisioning_messages.encrypted_response_buffer().size() + 1;
ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse());
@@ -4570,6 +4573,8 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange2_API16) {
provisioning_messages.PrepareSession(keybox_);
ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse());
// Encrypt and sign once, so that we can use the size of the response.
ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse());
provisioning_messages.core_response().enc_private_key_iv.offset =
provisioning_messages.encrypted_response_buffer().size() + 1;
ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse());
@@ -4585,6 +4590,8 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange3_API16) {
provisioning_messages.PrepareSession(keybox_);
ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse());
// Encrypt and sign once, so that we can use the size of the response.
ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse());
// If the offset is before the end, but the offset+length is bigger, then
// the message should be rejected.
provisioning_messages.core_response().enc_private_key.offset =
@@ -4602,6 +4609,8 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange4_API16) {
provisioning_messages.PrepareSession(keybox_);
ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse());
// Encrypt and sign once, so that we can use the size of the response.
ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse());
// If the offset is before the end, but the offset+length is bigger, then
// the message should be rejected.
provisioning_messages.core_response().enc_private_key_iv.offset =
@@ -4619,6 +4628,8 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRange5Prov30_API16) {
provisioning_messages.PrepareSession(keybox_);
ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse());
// Encrypt and sign once, so that we can use the size of the response.
ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse());
// If the offset is before the end, but the offset+length is bigger, then
// the message should be rejected.
provisioning_messages.core_response().encrypted_message_key.offset =
@@ -4974,11 +4985,10 @@ TEST_F(
TestHugeLengthDoesNotCrashAPI(oemcrypto_function, !kCheckStatus);
}
// Test a 3072 bit RSA key certificate.
TEST_F(OEMCryptoLoadsCertificate, TestLargeRSAKey3072) {
encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeyInfo3_3072,
kTestRSAPKCS8PrivateKeyInfo3_3072 +
sizeof(kTestRSAPKCS8PrivateKeyInfo3_3072));
class OEMCryptoLoadsCertVariousKeys : public OEMCryptoLoadsCertificate {
public:
void TestKey(const uint8_t* key, size_t key_length) {
encoded_rsa_key_.assign(key, key + key_length);
ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey());
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
@@ -4993,28 +5003,59 @@ TEST_F(OEMCryptoLoadsCertificate, TestLargeRSAKey3072) {
ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse());
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR());
}
};
// Test a 3072 bit RSA key certificate.
TEST_F(OEMCryptoLoadsCertVariousKeys, TestLargeRSAKey3072) {
TestKey(kTestRSAPKCS8PrivateKeyInfo3_3072,
sizeof(kTestRSAPKCS8PrivateKeyInfo3_3072));
}
// Test an RSA key certificate which has a private key generated using the
// Carmichael totient.
TEST_F(OEMCryptoLoadsCertificate, TestCarmichaelRSAKey) {
encoded_rsa_key_.assign(
kTestKeyRSACarmichael_2048,
kTestKeyRSACarmichael_2048 + sizeof(kTestKeyRSACarmichael_2048));
ASSERT_NO_FATAL_FAILURE(CreateWrappedRSAKey());
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(
s.PreparePublicKey(encoded_rsa_key_.data(), encoded_rsa_key_.size()));
ASSERT_NO_FATAL_FAILURE(s.InstallRSASessionTestKey(wrapped_rsa_key_));
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelRSAKey) {
TestKey(kTestKeyRSACarmichael_2048, sizeof(kTestKeyRSACarmichael_2048));
}
LicenseRoundTrip license_messages(&s);
ASSERT_NO_FATAL_FAILURE(s.GenerateNonce());
ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse());
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR());
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelNonZeroNormalDer) {
TestKey(kCarmichaelNonZeroNormalDer, kCarmichaelNonZeroNormalDerLen);
}
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelNonZeroShortDer) {
TestKey(kCarmichaelNonZeroShortDer, kCarmichaelNonZeroShortDerLen);
}
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelZeroNormalDer) {
TestKey(kCarmichaelZeroNormalDer, kCarmichaelZeroNormalDerLen);
}
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelZeroShortDer) {
TestKey(kCarmichaelZeroShortDer, kCarmichaelZeroShortDerLen);
}
TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualNonZeroNormalDer) {
TestKey(kDualNonZeroNormalDer, kDualNonZeroNormalDerLen);
}
TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualNonZeroShortDer) {
TestKey(kDualNonZeroShortDer, kDualNonZeroShortDerLen);
}
TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualZeroNormalDer) {
TestKey(kDualZeroNormalDer, kDualZeroNormalDerLen);
}
TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualZeroShortDer) {
TestKey(kDualZeroShortDer, kDualZeroShortDerLen);
}
TEST_F(OEMCryptoLoadsCertVariousKeys, TestEulerNonZeroNormalDer) {
TestKey(kEulerNonZeroNormalDer, kEulerNonZeroNormalDerLen);
}
TEST_F(OEMCryptoLoadsCertVariousKeys, TestEulerZeroNormalDer) {
TestKey(kEulerZeroNormalDer, kEulerZeroNormalDerLen);
}
// This tests that two sessions can use different RSA keys simultaneously.