OEMCrypto rewrap rsa key 3.0 unit tests

Merge from widevine repo of http://go/wvgerrit/21683

This CL adds unit tests for OEMCrypto_RewrapDeviceRSAKey30 for devices
that use provisioning 3.0.

Change-Id: Ib1a5566de343365b2ae3531f375ac2cc6d86ee53
This commit is contained in:
Fred Gylys-Colwell
2016-11-29 15:18:19 -08:00
parent 053ff5bd3c
commit 3e525dfdd3
3 changed files with 139 additions and 6 deletions

View File

@@ -630,6 +630,30 @@ void Session::RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted,
wrapped_key->clear();
}
}
void Session::RewrapRSAKey30(const struct RSAPrivateKeyMessage& encrypted,
size_t message_size,
const std::vector<uint8_t>& encrypted_message_key,
vector<uint8_t>* wrapped_key, bool force) {
size_t wrapped_key_length = 0;
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
OEMCrypto_RewrapDeviceRSAKey30(
session_id(), &nonce_, &encrypted_message_key[0],
encrypted_message_key.size(), encrypted.rsa_key,
encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL,
&wrapped_key_length));
wrapped_key->clear();
wrapped_key->assign(wrapped_key_length, 0);
OEMCryptoResult sts = OEMCrypto_RewrapDeviceRSAKey30(
session_id(), &nonce_, &encrypted_message_key[0],
encrypted_message_key.size(), encrypted.rsa_key, encrypted.rsa_key_length,
encrypted.rsa_key_iv, &(wrapped_key->front()), &wrapped_key_length);
if (force) {
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
}
if (OEMCrypto_SUCCESS != sts) {
wrapped_key->clear();
}
}
void Session::PreparePublicKey(const uint8_t* rsa_key, size_t rsa_key_length) {
if (rsa_key == NULL) {

View File

@@ -215,7 +215,7 @@ class Session {
const vector<uint8_t>& rsa_key,
const vector<uint8_t>* encryption_key = NULL);
// Calls OEMCrypto_RewrapDeviceRSAKey with the given provisioning response
// message.
// message. If force is true, we assert that the key loads successfully.
void RewrapRSAKey(const struct RSAPrivateKeyMessage& encrypted,
size_t message_size, const std::vector<uint8_t>& signature,
vector<uint8_t>* wrapped_key, bool force);
@@ -238,6 +238,12 @@ class Session {
// The unencrypted session key is stored in session_key.
bool GenerateRSASessionKey(vector<uint8_t>* session_key,
vector<uint8_t>* enc_session_key);
// Calls OEMCrypto_RewrapDeviceRSAKey30 with the given provisioning response
// message. If force is true, we assert that the key loads successfully.
void RewrapRSAKey30(const struct RSAPrivateKeyMessage& encrypted,
size_t message_size,
const std::vector<uint8_t>& encrypted_message_key,
vector<uint8_t>* wrapped_key, bool force);
// Loads the specified wrapped_rsa_key into OEMCrypto, and then runs
// GenerateDerivedKeysFromSessionKey to install known encryption and mac keys.
void InstallRSASessionTestKey(const vector<uint8_t>& wrapped_rsa_key);

View File

@@ -609,6 +609,9 @@ class OEMCryptoSessionTests : public OEMCryptoClientTest {
case DeviceFeatures::FORCE_TEST_KEYBOX:
InstallKeybox(kTestKeybox, true);
break;
case DeviceFeatures::TEST_PROVISION_30:
// Can use oem certificate to install test rsa key.
break;
default:
FAIL() << "Cannot run test without test keybox or RSA key installed.";
}
@@ -655,8 +658,24 @@ class OEMCryptoSessionTests : public OEMCryptoClientTest {
}
}
// TODO(fredgc): CreateWrappedRSAKeyFromOEMCert in next CL.
// If force is true, we assert that the key loads successfully.
void CreateWrappedRSAKey(uint32_t allowed_schemes, bool force) {
switch (global_features.provisioning_method) {
case OEMCrypto_OEMCertificate:
CreateWrappedRSAKeyFromOEMCert(allowed_schemes, force);
break;
case OEMCrypto_Keybox:
CreateWrappedRSAKeyFromKeybox(allowed_schemes, force);
break;
default:
FAIL() << "Cannot generate wrapped RSA key if provision method = "
<< wvoec::ProvisioningMethodName(
global_features.provisioning_method);
}
}
// If force is true, we assert that the key loads successfully.
void CreateWrappedRSAKeyFromKeybox(uint32_t allowed_schemes, bool force) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(s.GenerateDerivedKeysFromKeybox());
@@ -668,8 +687,30 @@ class OEMCryptoSessionTests : public OEMCryptoClientTest {
ASSERT_NO_FATAL_FAILURE(s.MakeRSACertificate(&encrypted, sizeof(encrypted),
&signature, allowed_schemes,
encoded_rsa_key_));
ASSERT_NO_FATAL_FAILURE(s.RewrapRSAKey(encrypted, sizeof(encrypted),
signature, &wrapped_rsa_key_, force));
ASSERT_NO_FATAL_FAILURE(s.RewrapRSAKey(
encrypted, sizeof(encrypted), signature, &wrapped_rsa_key_, force));
// Verify that the clear key is not contained in the wrapped key.
// It should be encrypted.
ASSERT_EQ(NULL, find(wrapped_rsa_key_, encoded_rsa_key_));
}
// If force is true, we assert that the key loads successfully.
void CreateWrappedRSAKeyFromOEMCert(uint32_t allowed_schemes, bool force) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(s.LoadOEMCert());
s.GenerateNonce();
struct RSAPrivateKeyMessage encrypted;
std::vector<uint8_t> signature;
std::vector<uint8_t> message_key;
std::vector<uint8_t> encrypted_message_key;
s.GenerateRSASessionKey(&message_key, &encrypted_message_key);
ASSERT_NO_FATAL_FAILURE(
s.MakeRSACertificate(&encrypted, sizeof(encrypted), &signature,
allowed_schemes, encoded_rsa_key_, &message_key));
ASSERT_NO_FATAL_FAILURE(s.RewrapRSAKey30(encrypted, sizeof(encrypted),
encrypted_message_key,
&wrapped_rsa_key_, force));
// Verify that the clear key is not contained in the wrapped key.
// It should be encrypted.
ASSERT_EQ(NULL, find(wrapped_rsa_key_, encoded_rsa_key_));
@@ -1691,7 +1732,7 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, SingleLargeSubsample) {
TEST_P(OEMCryptoSessionTestsDecryptTests, PatternPlusOneBlock) {
// When the pattern length is 10 blocks, there is a discrepancy between the
// HLS and the CENC standards for samples of size 160*N+16, for N = 1, 2, 3 ...
// HLS and the CENC standards for samples of size 160*N+16, for N = 1, 2, 3...
// We require the CENC standard for OEMCrypto, and let a layer above us break
// samples into pieces if they wish to use the HLS standard.
subsample_size_.push_back(SampleSize(0, 160 + 16));
@@ -2201,7 +2242,7 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadNonceKeyboxTest) {
wrapped_key.clear();
wrapped_key.assign(wrapped_key_length, 0);
encrypted.nonce ^= 42; // Almost surely a bad nonce.
ASSERT_NE(OEMCrypto_SUCCESS,
ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE,
OEMCrypto_RewrapDeviceRSAKey(
s.session_id(), message_ptr, sizeof(encrypted), &signature[0],
signature.size(), &encrypted.nonce, encrypted.rsa_key,
@@ -2260,6 +2301,67 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionLargeBufferKeyboxTest) {
ASSERT_EQ(NULL, find(wrapped_key, encoded_rsa_key_));
}
TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadNonceProv30Test) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(s.LoadOEMCert());
s.GenerateNonce();
uint32_t bad_nonce = s.get_nonce() ^ 42;
struct RSAPrivateKeyMessage encrypted;
std::vector<uint8_t> signature;
std::vector<uint8_t> message_key;
std::vector<uint8_t> encrypted_message_key;
s.GenerateRSASessionKey(&message_key, &encrypted_message_key);
ASSERT_NO_FATAL_FAILURE(s.MakeRSACertificate(&encrypted, sizeof(encrypted),
&signature, kSign_RSASSA_PSS,
encoded_rsa_key_, &message_key));
size_t wrapped_key_length = 0;
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
OEMCrypto_RewrapDeviceRSAKey30(
s.session_id(), &bad_nonce, &encrypted_message_key[0],
encrypted_message_key.size(), encrypted.rsa_key,
encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL,
&wrapped_key_length));
vector<uint8_t> wrapped_key(wrapped_key_length, 0);
ASSERT_EQ(OEMCrypto_ERROR_INVALID_NONCE,
OEMCrypto_RewrapDeviceRSAKey30(
s.session_id(), &bad_nonce, &encrypted_message_key[0],
encrypted_message_key.size(), encrypted.rsa_key,
encrypted.rsa_key_length, encrypted.rsa_key_iv, &wrapped_key[0],
&wrapped_key_length));
}
TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionBadRSAKeyProv30Test) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(s.LoadOEMCert());
s.GenerateNonce();
struct RSAPrivateKeyMessage encrypted;
std::vector<uint8_t> signature;
std::vector<uint8_t> message_key;
std::vector<uint8_t> encrypted_message_key;
s.GenerateRSASessionKey(&message_key, &encrypted_message_key);
ASSERT_NO_FATAL_FAILURE(s.MakeRSACertificate(&encrypted, sizeof(encrypted),
&signature, kSign_RSASSA_PSS,
encoded_rsa_key_, &message_key));
size_t wrapped_key_length = 0;
uint32_t nonce = s.get_nonce();
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
OEMCrypto_RewrapDeviceRSAKey30(
s.session_id(), &nonce, &encrypted_message_key[0],
encrypted_message_key.size(), encrypted.rsa_key,
encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL,
&wrapped_key_length));
vector<uint8_t> wrapped_key(wrapped_key_length, 0);
encrypted.rsa_key[1] ^= 42; // Almost surely a bad key.
ASSERT_EQ(OEMCrypto_ERROR_INVALID_RSA_KEY,
OEMCrypto_RewrapDeviceRSAKey30(
s.session_id(), &nonce, &encrypted_message_key[0],
encrypted_message_key.size(), encrypted.rsa_key,
encrypted.rsa_key_length, encrypted.rsa_key_iv, &wrapped_key[0],
&wrapped_key_length));
}
TEST_F(OEMCryptoLoadsCertificate, LoadWrappedRSAKey) {
OEMCryptoResult sts;
CreateWrappedRSAKey(kSign_RSASSA_PSS, true);
@@ -2581,6 +2683,7 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate {
enc_context.size()));
}
// If force is true, we assert that the key loads successfully.
void LoadWithAllowedSchemes(uint32_t schemes, bool force) {
CreateWrappedRSAKey(schemes, force);
key_loaded_ = (wrapped_rsa_key_.size() > 0);