Restructed reference root of trust (2/3 DRM Cert)

[ Merge of http://go/wvgerrit/115551 ]

This change is the second part of a three part change for restructing
the root of trust used by the reference implementation.

The use of RSA_shared_ptr has been replaced with the standard library
std::shared_ptr using the RsaPrivateKey wrapper class.  The
AuthenticationRoot class now uses this for the built-in DRM cert key.

RSA decryption and signature operations within the session context are
now performed the RsaPrivateKey class.  This has reduced the code size
and complexity within the reference and testbed, focusing their
implementation on key policy and less on mechanics.

Bug: 168544740
Bug: 135283522
Test: oemcrypto_unittests ce_cdm_tests
Change-Id: Ic743a529a9858f3182290d8bcf5e1633737b005b
This commit is contained in:
Alex Dale
2021-02-18 19:53:12 -08:00
parent e4ee4eb404
commit f6f5099604
11 changed files with 187 additions and 458 deletions

View File

@@ -172,11 +172,8 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateDerivedKeys(
enc_key_context, enc_key_context + enc_key_context_length);
// Generate mac and encryption keys for current session context
if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), mac_ctx_str,
enc_ctx_str)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
return OEMCrypto_SUCCESS;
return session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), mac_ctx_str,
enc_ctx_str);
}
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
@@ -893,8 +890,10 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
return OEMCrypto_ERROR_INVALID_NONCE;
}
if (!session_ctx->InstallRSAEncryptedKey(encrypted_message_key,
encrypted_message_key_length)) {
const std::vector<uint8_t> enc_encryption_key(
encrypted_message_key,
encrypted_message_key + encrypted_message_key_length);
if (!session_ctx->InstallRSAEncryptedKey(enc_encryption_key)) {
LOGE(
"OEMCrypto_RewrapDeviceRSAKey30: "
"Error loading encrypted_message_key.");
@@ -904,11 +903,11 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
// Decrypt RSA key.
std::vector<uint8_t> pkcs8_rsa_key(enc_rsa_key_length);
if (!session_ctx->DecryptRSAKey(enc_rsa_key, enc_rsa_key_length,
enc_rsa_key_iv, &pkcs8_rsa_key[0])) {
enc_rsa_key_iv, pkcs8_rsa_key.data())) {
return OEMCrypto_ERROR_INVALID_RSA_KEY;
}
if (!session_ctx->LoadRSAKey(&pkcs8_rsa_key[0], enc_rsa_key_length)) {
LOGE("[OEMCrypto_RewrapDeviceRSAKey30(): Failed to LoadRSAKey.");
if (!session_ctx->LoadRsaDrmKey(pkcs8_rsa_key.data(), enc_rsa_key_length)) {
LOGE("Failed to load RSA DRM key");
return OEMCrypto_ERROR_INVALID_RSA_KEY;
}
@@ -926,23 +925,24 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
const std::vector<uint8_t> context(
wrapped->context, wrapped->context + sizeof(wrapped->context));
// Generate mac and encryption keys for encrypting the signature.
if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context,
context)) {
const OEMCryptoResult derive_key_result =
session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context);
if (derive_key_result != OEMCrypto_SUCCESS) {
LOGE("[_RewrapDeviceRSAKey30(): DeriveKeys failed.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
return derive_key_result;
}
// Encrypt rsa key with keybox.
if (!session_ctx->EncryptRSAKey(&pkcs8_rsa_key[0], enc_rsa_key_length,
if (!session_ctx->EncryptRSAKey(pkcs8_rsa_key.data(), enc_rsa_key_length,
wrapped->iv, wrapped->enc_rsa_key)) {
LOGE("[_RewrapDeviceRSAKey30(): EncrypteRSAKey failed.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
const size_t buffer_size = enc_rsa_key_length + sizeof(WrappedRSAKey);
// The wrapped keybox must be signed with the same key we verify with. I'll
// pick the server key, so I don't have to modify LoadRSAKey.
// The wrapped keybox must be signed with the same key we verify with.
// Reference implementation uses the server key.
unsigned int sig_length = sizeof(wrapped->signature);
if (!HMAC(EVP_sha256(), &session_ctx->mac_key_server()[0],
if (!HMAC(EVP_sha256(), session_ctx->mac_key_server().data(),
session_ctx->mac_key_server().size(), wrapped->context,
buffer_size - sizeof(wrapped->signature), wrapped->signature,
&sig_length)) {
@@ -1006,10 +1006,10 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
// Decrypt RSA key and verify it.
std::vector<uint8_t> pkcs8_rsa_key(enc_rsa_key_length);
if (!session_ctx->DecryptRSAKey(enc_rsa_key, enc_rsa_key_length,
enc_rsa_key_iv, &pkcs8_rsa_key[0])) {
enc_rsa_key_iv, pkcs8_rsa_key.data())) {
return OEMCrypto_ERROR_INVALID_RSA_KEY;
}
if (!session_ctx->LoadRSAKey(&pkcs8_rsa_key[0], enc_rsa_key_length)) {
if (!session_ctx->LoadRsaDrmKey(pkcs8_rsa_key.data(), enc_rsa_key_length)) {
return OEMCrypto_ERROR_INVALID_RSA_KEY;
}
@@ -1025,21 +1025,22 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
const std::vector<uint8_t> context(
wrapped->context, wrapped->context + sizeof(wrapped->context));
// Generate mac and encryption keys for encrypting the signature.
if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context,
context)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const OEMCryptoResult derive_key_result =
session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context);
if (derive_key_result != OEMCrypto_SUCCESS) {
return derive_key_result;
}
// Encrypt rsa key with keybox.
if (!session_ctx->EncryptRSAKey(&pkcs8_rsa_key[0], enc_rsa_key_length,
if (!session_ctx->EncryptRSAKey(pkcs8_rsa_key.data(), enc_rsa_key_length,
wrapped->iv, wrapped->enc_rsa_key)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
const size_t buffer_size = enc_rsa_key_length + sizeof(WrappedRSAKey);
// The wrapped keybox must be signed with the same key we verify with. I'll
// pick the server key, so I don't have to modify LoadRSAKey.
// The wrapped keybox must be signed with the same key we verify with.
// Reference implementation uses the server key.
unsigned int sig_length = sizeof(wrapped->signature);
if (!HMAC(EVP_sha256(), &session_ctx->mac_key_server()[0],
if (!HMAC(EVP_sha256(), session_ctx->mac_key_server().data(),
session_ctx->mac_key_server().size(), wrapped->context,
buffer_size - sizeof(wrapped->signature), wrapped->signature,
&sig_length)) {
@@ -1173,9 +1174,10 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDRMPrivateKey(
const std::vector<uint8_t> context(
wrapped->context, wrapped->context + sizeof(wrapped->context));
// Generate mac and encryption keys for encrypting the signature.
if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context,
context)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
const OEMCryptoResult derive_key_result =
session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context);
if (derive_key_result != OEMCrypto_SUCCESS) {
return derive_key_result;
}
// verify signature.
if (!session_ctx->ValidateMessage(
@@ -1189,7 +1191,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDRMPrivateKey(
sizeof(wrapped->signature));
size_t enc_rsa_key_length = wrapped_rsa_key_length - sizeof(WrappedRSAKey);
if (!session_ctx->DecryptRSAKey(wrapped->enc_rsa_key, enc_rsa_key_length,
wrapped->iv, &pkcs8_rsa_key[0])) {
wrapped->iv, pkcs8_rsa_key.data())) {
return OEMCrypto_ERROR_INVALID_RSA_KEY;
}
size_t padding = pkcs8_rsa_key[enc_rsa_key_length - 1];
@@ -1198,7 +1200,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDRMPrivateKey(
padding = 0;
}
size_t rsa_key_length = enc_rsa_key_length - padding;
if (!session_ctx->LoadRSAKey(&pkcs8_rsa_key[0], rsa_key_length)) {
if (!session_ctx->LoadRsaDrmKey(pkcs8_rsa_key.data(), rsa_key_length)) {
return OEMCrypto_ERROR_INVALID_RSA_KEY;
}
return OEMCrypto_SUCCESS;
@@ -1231,22 +1233,8 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateRSASignature(
LOGE("[OEMCrypto_GenerateRSASignature(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
size_t required_size = session_ctx->RSASignatureSize();
if (*signature_length < required_size) {
*signature_length = required_size;
return OEMCrypto_ERROR_SHORT_BUFFER;
}
if (message == nullptr || message_length == 0 || signature == nullptr ||
signature_length == 0) {
LOGE("[OEMCrypto_GenerateRSASignature(): OEMCrypto_ERROR_INVALID_CONTEXT]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
OEMCryptoResult sts = session_ctx->GenerateRSASignature(
message, message_length, signature, signature_length, padding_scheme);
return sts;
return session_ctx->GenerateRSASignature(message, message_length, signature,
signature_length, padding_scheme);
}
OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
@@ -1259,27 +1247,22 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!crypto_engine->ValidRootOfTrust()) {
LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_KEYBOX_INVALID]");
LOGE("[OEMCrypto_DeriveKeysFromSessionKey(): ERROR_KEYBOX_INVALID]");
return OEMCrypto_ERROR_KEYBOX_INVALID;
}
if (mac_key_context_length > kMaxContextKeyLength ||
enc_key_context_length > kMaxContextKeyLength ||
enc_session_key_length > kMaxContextKeyLength) {
LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_BUFFER_TOO_LARGE]");
LOGE("[OEMCrypto_DeriveKeysFromSessionKey(): ERROR_BUFFER_TOO_LARGE]");
return OEMCrypto_ERROR_BUFFER_TOO_LARGE;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (session_ctx == nullptr || !session_ctx->isValid()) {
LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_INVALID_SESSION]");
LOGE("[OEMCrypto_DeriveKeysFromSessionKey(): ERROR_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
if (session_ctx->allowed_schemes() != kSign_RSASSA_PSS) {
LOGE("[OEMCrypto_GenerateDerivedKeys(): x509 key used to derive keys]");
return OEMCrypto_ERROR_INVALID_RSA_KEY;
}
const std::vector<uint8_t> ssn_key_str(
enc_session_key, enc_session_key + enc_session_key_length);
const std::vector<uint8_t> mac_ctx_str(
@@ -1288,10 +1271,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
enc_key_context, enc_key_context + enc_key_context_length);
// Generate mac and encryption keys for current session context
if (!session_ctx->RSADeriveKeys(ssn_key_str, mac_ctx_str, enc_ctx_str)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
return OEMCrypto_SUCCESS;
return session_ctx->RSADeriveKeys(ssn_key_str, mac_ctx_str, enc_ctx_str);
}
OEMCRYPTO_API uint32_t OEMCrypto_APIVersion() {