diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp index 1473d3ea..8697860f 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.cpp @@ -187,6 +187,7 @@ bool AuthenticationRoot::Initialize(OEMCrypto_ProvisioningMethod method) { // If provisioning method is something other than ProvisioningError // indicates it has already been initialized before. Must // existing data. + rsa_key_set_ = false; rsa_key_.reset(); test_rsa_key_.reset(); keybox_.reset(); @@ -195,11 +196,8 @@ bool AuthenticationRoot::Initialize(OEMCrypto_ProvisioningMethod method) { prov_method_ = method; switch (method) { case OEMCrypto_DrmCertificate: { - std::unique_ptr key = - RsaPrivateKey::Load(kPrivateKey, kPrivateKeySize); - if (key) { - rsa_key_ = std::move(key); - } else { + rsa_key_set_ = rsa_key_.LoadPkcs8RsaKey(kPrivateKey, kPrivateKeySize); + if (!rsa_key_set_) { // This error message is OK in unit tests which use test certificate. LOGE( "FATAL ERROR: Platform uses a baked-in certificate instead of a " @@ -224,7 +222,7 @@ bool AuthenticationRoot::Initialize(OEMCrypto_ProvisioningMethod method) { bool AuthenticationRoot::IsValid() const { switch (prov_method_) { case OEMCrypto_DrmCertificate: { - return HasDrmCertKey() && HasDeviceKey(); + return rsa_key_set_ && HasDeviceKey(); } case OEMCrypto_Keybox: { return HasDeviceKey(); @@ -326,18 +324,17 @@ OEMCryptoResult AuthenticationRoot::LoadTestRsaKey() { LOGE("System does not support DRM certificates"); return OEMCrypto_ERROR_NOT_IMPLEMENTED; } - if (test_rsa_key_) { + if (test_rsa_key_.get() != nullptr) { LOGE("Test RSA key is already loaded"); return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES; } - std::unique_ptr key = - RsaPrivateKey::Load(kTestRSAPKCS8PrivateKeyInfo2_2048, - sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048)); - if (!key) { + if (!test_rsa_key_.LoadPkcs8RsaKey( + kTestRSAPKCS8PrivateKeyInfo2_2048, + sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048))) { LOGE("Failed to load test RSA key"); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } - test_rsa_key_ = std::move(key); + rsa_key_set_ = true; return OEMCrypto_SUCCESS; } diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h index aa898886..3269613b 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_auth_ref.h @@ -8,14 +8,17 @@ #define OEMCRYPTO_AUTH_REF_H_ #include - #include #include +#include + #include "OEMCryptoCENC.h" // Needed for enums only. #include "disallow_copy_and_assign.h" +#include "oemcrypto_key_ref.h" #include "oemcrypto_keybox_ref.h" -#include "oemcrypto_rsa_key.h" +#include "oemcrypto_rsa_key_shared.h" +#include "oemcrypto_types.h" namespace wvoec_ref { // The AuthenticationRoot class contains the OEMCrypto information @@ -66,13 +69,13 @@ class AuthenticationRoot { // Returns the shared RSA private key from the built-in DRM // Certificate. - std::shared_ptr ShareDrmCertKey() { - return test_rsa_key_ ? test_rsa_key_ : rsa_key_; + RSA_shared_ptr& SharedRsaKey() { + return test_rsa_key_.get() != nullptr ? test_rsa_key_ : rsa_key_; } - RsaPrivateKey* DrmCertKey() const { - return test_rsa_key_ ? test_rsa_key_.get() : rsa_key_.get(); + RSA* rsa_key() { + return test_rsa_key_.get() != nullptr ? test_rsa_key_.get() + : rsa_key_.get(); } - bool HasDrmCertKey() const { return test_rsa_key_ || rsa_key_; } // Loads the system's built-in RSA key. Only implemented for // devices that are that pre-provisioned with a built-in DRM @@ -141,10 +144,11 @@ class AuthenticationRoot { OEMCrypto_ProvisioningMethod prov_method_ = OEMCrypto_ProvisioningError; // DRM certificate. - // If no keybox, this is the private key of the baked-in DRM - // Certificate. - std::shared_ptr rsa_key_; - std::shared_ptr test_rsa_key_; + // TODO(b/168544740): Remove |rsa_key_set_| when RSA_shared_ptr has + // been replaced with scoped RsaPrivateKey. + bool rsa_key_set_ = false; + RSA_shared_ptr rsa_key_; // If no keybox, this is baked in certificate. + RSA_shared_ptr test_rsa_key_; // Keybox data. std::unique_ptr keybox_; diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp index 0a2fc0dc..7e3c2eb2 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_device_properties_prov30.cpp @@ -65,7 +65,7 @@ class Prov30CryptoEngine : public CryptoEngine { return OEMCrypto_ERROR_SHORT_BUFFER; } memcpy(public_cert, kOEMPublicCert, kOEMPublicCertSize); - if (!session->LoadRsaDrmKey(kOEMPrivateKey, kOEMPrivateKeySize)) { + if (!session->LoadRSAKey(kOEMPrivateKey, kOEMPrivateKeySize)) { LOGE("Private RSA Key did not load correctly."); return OEMCrypto_ERROR_INVALID_RSA_KEY; } diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.cpp index d0f5f581..d999fe6c 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.cpp @@ -20,6 +20,7 @@ #include "keys.h" #include "log.h" #include "oemcrypto_key_ref.h" +#include "oemcrypto_rsa_key_shared.h" #include "string_conversions.h" namespace { @@ -80,10 +81,7 @@ SessionId CryptoEngine::OpenSession() { } SessionContext* CryptoEngine::MakeSession(SessionId sid) { - if (root_of_trust_.HasDrmCertKey()) { - return new SessionContext(this, sid, root_of_trust_.ShareDrmCertKey()); - } - return new SessionContext(this, sid); + return new SessionContext(this, sid, root_of_trust_.SharedRsaKey()); } UsageTable* CryptoEngine::MakeUsageTable() { return new UsageTable(this); } diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h index 150fdf96..6ccf13c4 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_engine_ref.h @@ -8,16 +8,19 @@ #define REF_OEMCRYPTO_ENGINE_REF_H_ #include - +#include #include #include #include #include +#include + #include "OEMCryptoCENC.h" #include "file_store.h" #include "oemcrypto_auth_ref.h" #include "oemcrypto_key_ref.h" +#include "oemcrypto_rsa_key_shared.h" #include "oemcrypto_session.h" #include "oemcrypto_types.h" #include "oemcrypto_usage_table_ref.h" diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp index b2f3b63c..aeca0675 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_ref.cpp @@ -172,8 +172,11 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateDerivedKeys( enc_key_context, enc_key_context + enc_key_context_length); // Generate mac and encryption keys for current session context - return session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), mac_ctx_str, - enc_ctx_str); + if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), mac_ctx_str, + enc_ctx_str)) { + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + return OEMCrypto_SUCCESS; } OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session, @@ -890,10 +893,8 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( return OEMCrypto_ERROR_INVALID_NONCE; } - const std::vector enc_encryption_key( - encrypted_message_key, - encrypted_message_key + encrypted_message_key_length); - if (!session_ctx->InstallRSAEncryptedKey(enc_encryption_key)) { + if (!session_ctx->InstallRSAEncryptedKey(encrypted_message_key, + encrypted_message_key_length)) { LOGE( "OEMCrypto_RewrapDeviceRSAKey30: " "Error loading encrypted_message_key."); @@ -903,11 +904,11 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( // Decrypt RSA key. std::vector 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.data())) { + enc_rsa_key_iv, &pkcs8_rsa_key[0])) { return OEMCrypto_ERROR_INVALID_RSA_KEY; } - if (!session_ctx->LoadRsaDrmKey(pkcs8_rsa_key.data(), enc_rsa_key_length)) { - LOGE("Failed to load RSA DRM key"); + if (!session_ctx->LoadRSAKey(&pkcs8_rsa_key[0], enc_rsa_key_length)) { + LOGE("[OEMCrypto_RewrapDeviceRSAKey30(): Failed to LoadRSAKey."); return OEMCrypto_ERROR_INVALID_RSA_KEY; } @@ -925,24 +926,23 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30( const std::vector context( wrapped->context, wrapped->context + sizeof(wrapped->context)); // Generate mac and encryption keys for encrypting the signature. - const OEMCryptoResult derive_key_result = - session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context); - if (derive_key_result != OEMCrypto_SUCCESS) { + if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, + context)) { LOGE("[_RewrapDeviceRSAKey30(): DeriveKeys failed."); - return derive_key_result; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } // Encrypt rsa key with keybox. - if (!session_ctx->EncryptRSAKey(pkcs8_rsa_key.data(), enc_rsa_key_length, + if (!session_ctx->EncryptRSAKey(&pkcs8_rsa_key[0], 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. - // Reference implementation uses the server key. + // 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. unsigned int sig_length = sizeof(wrapped->signature); - if (!HMAC(EVP_sha256(), session_ctx->mac_key_server().data(), + if (!HMAC(EVP_sha256(), &session_ctx->mac_key_server()[0], 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 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.data())) { + enc_rsa_key_iv, &pkcs8_rsa_key[0])) { return OEMCrypto_ERROR_INVALID_RSA_KEY; } - if (!session_ctx->LoadRsaDrmKey(pkcs8_rsa_key.data(), enc_rsa_key_length)) { + if (!session_ctx->LoadRSAKey(&pkcs8_rsa_key[0], enc_rsa_key_length)) { return OEMCrypto_ERROR_INVALID_RSA_KEY; } @@ -1025,22 +1025,21 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey( const std::vector context( wrapped->context, wrapped->context + sizeof(wrapped->context)); // Generate mac and encryption keys for encrypting the signature. - const OEMCryptoResult derive_key_result = - session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context); - if (derive_key_result != OEMCrypto_SUCCESS) { - return derive_key_result; + if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, + context)) { + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } // Encrypt rsa key with keybox. - if (!session_ctx->EncryptRSAKey(pkcs8_rsa_key.data(), enc_rsa_key_length, + if (!session_ctx->EncryptRSAKey(&pkcs8_rsa_key[0], 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. - // Reference implementation uses the server key. + // 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. unsigned int sig_length = sizeof(wrapped->signature); - if (!HMAC(EVP_sha256(), session_ctx->mac_key_server().data(), + if (!HMAC(EVP_sha256(), &session_ctx->mac_key_server()[0], session_ctx->mac_key_server().size(), wrapped->context, buffer_size - sizeof(wrapped->signature), wrapped->signature, &sig_length)) { @@ -1174,10 +1173,9 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDRMPrivateKey( const std::vector context( wrapped->context, wrapped->context + sizeof(wrapped->context)); // Generate mac and encryption keys for encrypting the signature. - const OEMCryptoResult derive_key_result = - session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context); - if (derive_key_result != OEMCrypto_SUCCESS) { - return derive_key_result; + if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, + context)) { + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } // verify signature. if (!session_ctx->ValidateMessage( @@ -1191,7 +1189,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.data())) { + wrapped->iv, &pkcs8_rsa_key[0])) { return OEMCrypto_ERROR_INVALID_RSA_KEY; } size_t padding = pkcs8_rsa_key[enc_rsa_key_length - 1]; @@ -1200,7 +1198,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDRMPrivateKey( padding = 0; } size_t rsa_key_length = enc_rsa_key_length - padding; - if (!session_ctx->LoadRsaDrmKey(pkcs8_rsa_key.data(), rsa_key_length)) { + if (!session_ctx->LoadRSAKey(&pkcs8_rsa_key[0], rsa_key_length)) { return OEMCrypto_ERROR_INVALID_RSA_KEY; } return OEMCrypto_SUCCESS; @@ -1233,8 +1231,22 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateRSASignature( LOGE("[OEMCrypto_GenerateRSASignature(): ERROR_INVALID_SESSION]"); return OEMCrypto_ERROR_INVALID_SESSION; } - return session_ctx->GenerateRSASignature(message, message_length, signature, - signature_length, padding_scheme); + + 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; } OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey( @@ -1247,22 +1259,27 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey( return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (!crypto_engine->ValidRootOfTrust()) { - LOGE("[OEMCrypto_DeriveKeysFromSessionKey(): ERROR_KEYBOX_INVALID]"); + LOGE("[OEMCrypto_GenerateDerivedKeys(): 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_DeriveKeysFromSessionKey(): ERROR_BUFFER_TOO_LARGE]"); + LOGE("[OEMCrypto_GenerateDerivedKeys(): 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_DeriveKeysFromSessionKey(): ERROR_INVALID_SESSION]"); + LOGE("[OEMCrypto_GenerateDerivedKeys(): 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 ssn_key_str( enc_session_key, enc_session_key + enc_session_key_length); const std::vector mac_ctx_str( @@ -1271,7 +1288,10 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey( enc_key_context, enc_key_context + enc_key_context_length); // Generate mac and encryption keys for current session context - return session_ctx->RSADeriveKeys(ssn_key_str, mac_ctx_str, enc_ctx_str); + if (!session_ctx->RSADeriveKeys(ssn_key_str, mac_ctx_str, enc_ctx_str)) { + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + return OEMCrypto_SUCCESS; } OEMCRYPTO_API uint32_t OEMCrypto_APIVersion() { diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key.cpp index 6a9c2af2..71aea9b4 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key.cpp @@ -993,6 +993,7 @@ bool RsaPrivateKey::InitFromBuffer(const uint8_t* buffer, size_t length) { } // Step 3: Verify field width. const int bits = RSA_bits(key.get()); + LOGD("Loaded RSA private key size: bits = %d", bits); field_size_ = RealBitSizeToFieldSize(bits); if (field_size_ == kRsaFieldUnknown) { LOGE("Unsupported RSA key size: bits = %d", bits); diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.cpp new file mode 100644 index 00000000..6c73ad81 --- /dev/null +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.cpp @@ -0,0 +1,101 @@ +// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine Master +// License Agreement. +// +// Reference implementation of OEMCrypto APIs +// +#include "oemcrypto_rsa_key_shared.h" + +#include + +#include +#include +#include +#include +#include + +#include "log.h" + +namespace wvoec_ref { + +void dump_boringssl_error() { + int count = 0; + while (unsigned long err = ERR_get_error()) { + count++; + char buffer[120]; + ERR_error_string_n(err, buffer, sizeof(buffer)); + LOGE("BoringSSL Error %d -- %lu -- %s", count, err, buffer); + } + LOGE("Reported %d BoringSSL Errors", count); +} + +void RSA_shared_ptr::reset() { + if (rsa_key_ && key_owned_) { + RSA_free(rsa_key_); + } + key_owned_ = false; + rsa_key_ = nullptr; +} + +bool RSA_shared_ptr::LoadPkcs8RsaKey(const uint8_t* buffer, size_t length) { + assert(buffer != nullptr); + reset(); + uint8_t* pkcs8_rsa_key = const_cast(buffer); + BIO* bio = BIO_new_mem_buf(pkcs8_rsa_key, length); + if (bio == nullptr) { + LOGE("[LoadPkcs8RsaKey(): Could not allocate bio buffer]"); + return false; + } + bool success = true; + PKCS8_PRIV_KEY_INFO* pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, nullptr); + if (pkcs8_pki == nullptr) { + BIO_reset(bio); + pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, nullptr); + if (pkcs8_pki == nullptr) { + LOGE("[LoadPkcs8RsaKey(): d2i_PKCS8_PRIV_KEY_INFO_bio returned nullptr]"); + dump_boringssl_error(); + success = false; + } + } + EVP_PKEY* evp = nullptr; + if (success) { + evp = EVP_PKCS82PKEY(pkcs8_pki); + if (evp == nullptr) { + LOGE("[LoadPkcs8RsaKey(): EVP_PKCS82PKEY returned nullptr]"); + dump_boringssl_error(); + success = false; + } + } + if (success) { + rsa_key_ = EVP_PKEY_get1_RSA(evp); + if (rsa_key_ == nullptr) { + LOGE("[LoadPkcs8RsaKey(): PrivateKeyInfo did not contain an RSA key]"); + success = false; + } + key_owned_ = true; + } + if (evp != nullptr) { + EVP_PKEY_free(evp); + } + if (pkcs8_pki != nullptr) { + PKCS8_PRIV_KEY_INFO_free(pkcs8_pki); + } + BIO_free(bio); + if (!success) { + return false; + } + switch (RSA_check_key(rsa_key_)) { + case 1: // valid. + return true; + case 0: // not valid. + LOGE("[LoadPkcs8RsaKey(): rsa key not valid]"); + dump_boringssl_error(); + return false; + default: // -1 == check failed. + LOGE("[LoadPkcs8RsaKey(): error checking rsa key]"); + dump_boringssl_error(); + return false; + } +} + +} // namespace wvoec_ref diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.h new file mode 100644 index 00000000..98ea154e --- /dev/null +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.h @@ -0,0 +1,42 @@ +// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine Master +// License Agreement. +// +// Reference implementation of OEMCrypto APIs +// +#ifndef OEMCRYPTO_RSA_KEY_SHARED_H_ +#define OEMCRYPTO_RSA_KEY_SHARED_H_ + +#include + +#include + +namespace wvoec_ref { + +// Shared pointer with specialized destructor. This pointer is only shared +// from a CryptoEngine to a Session -- so we don't have to use full reference +// counting. +class RSA_shared_ptr { + public: + RSA_shared_ptr() : rsa_key_(nullptr), key_owned_(false) {} + ~RSA_shared_ptr() { reset(); }; + // Explicitly allow copy as share. + explicit RSA_shared_ptr(const RSA_shared_ptr& other) : + rsa_key_(other.rsa_key_), key_owned_(false) {} + RSA* get() { return rsa_key_; } + void reset(); + bool LoadPkcs8RsaKey(const uint8_t* buffer, size_t length); + + private: + void operator=(const RSA_shared_ptr); // disallow assign. + + RSA* rsa_key_; + bool key_owned_; +}; + +// Log errors from BoringSSL. +void dump_boringssl_error(); + +} // namespace wvoec_ref + +#endif // OEMCRYPTO_RSA_KEY_SHARED_H_ diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp index 4ca614b9..51bf560e 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.cpp @@ -25,17 +25,20 @@ #include #include "advance_iv_ctr.h" +#include "disallow_copy_and_assign.h" #include "keys.h" #include "log.h" #include "odk.h" #include "oemcrypto_engine_ref.h" #include "oemcrypto_key_ref.h" +#include "oemcrypto_rsa_key_shared.h" #include "oemcrypto_types.h" #include "platform.h" #include "string_conversions.h" #include "wvcrc32.h" -namespace wvoec_ref { +static const int kPssSaltLength = 20; + namespace { // Increment counter for AES-CTR. The CENC spec specifies we increment only @@ -63,8 +66,11 @@ void advance_dest_buffer(OEMCrypto_DestBufferDesc* dest_buffer, size_t bytes) { break; } } + } // namespace +namespace wvoec_ref { + /***************************************/ class ContentKeysContext : public SessionContextKeys { @@ -175,17 +181,31 @@ EntitlementKey* EntitlementKeysContext::GetEntitlementKey( /***************************************/ -SessionContext::SessionContext(CryptoEngine* ce, SessionId sid) - : valid_(ce != nullptr), ce_(ce), id_(sid) { +SessionContext::SessionContext(CryptoEngine* ce, SessionId sid, + const RSA_shared_ptr& rsa_key) + : valid_(true), + ce_(ce), + id_(sid), + current_content_key_(nullptr), + session_keys_(nullptr), + license_request_hash_(), + rsa_key_(rsa_key), + allowed_schemes_(kSign_RSASSA_PSS), + decrypt_started_(false), + timer_limits_(), + clock_values_(), + usage_entry_(nullptr), + srm_requirements_status_(NoSRMVersion), + usage_entry_status_(kNoUsageEntry), + compute_hash_(false), + current_hash_(0), + bad_frame_number_(0), + hash_error_(OEMCrypto_SUCCESS), + state_nonce_created_(false), + state_request_signed_(false), + state_response_loaded_(false) { ODK_InitializeSessionValues(&timer_limits_, &clock_values_, &nonce_values_, CryptoEngine::kApiVersion, sid); - memset(license_request_hash_, 0, sizeof(license_request_hash_)); -} - -SessionContext::SessionContext(CryptoEngine* ce, SessionId sid, - std::shared_ptr&& rsa_key) - : SessionContext(ce, sid) { - rsa_key_ = std::move(rsa_key); } SessionContext::~SessionContext() {} @@ -238,28 +258,27 @@ bool SessionContext::DeriveKey(const std::vector& key, return true; } -OEMCryptoResult SessionContext::DeriveKeys( - const std::vector& master_key, - const std::vector& mac_key_context, - const std::vector& enc_key_context) { +bool SessionContext::DeriveKeys(const std::vector& master_key, + const std::vector& mac_key_context, + const std::vector& enc_key_context) { // Generate derived key for mac key std::vector mac_key_server; std::vector mac_key_client; std::vector mac_key_part2; if (!DeriveKey(master_key, mac_key_context, 1, &mac_key_server)) { - return OEMCrypto_ERROR_UNKNOWN_FAILURE; + return false; } if (!DeriveKey(master_key, mac_key_context, 2, &mac_key_part2)) { - return OEMCrypto_ERROR_UNKNOWN_FAILURE; + return false; } mac_key_server.insert(mac_key_server.end(), mac_key_part2.begin(), mac_key_part2.end()); if (!DeriveKey(master_key, mac_key_context, 3, &mac_key_client)) { - return OEMCrypto_ERROR_UNKNOWN_FAILURE; + return false; } if (!DeriveKey(master_key, mac_key_context, 4, &mac_key_part2)) { - return OEMCrypto_ERROR_UNKNOWN_FAILURE; + return false; } mac_key_client.insert(mac_key_client.end(), mac_key_part2.begin(), mac_key_part2.end()); @@ -267,31 +286,48 @@ OEMCryptoResult SessionContext::DeriveKeys( // Generate derived key for encryption key std::vector enc_key; if (!DeriveKey(master_key, enc_key_context, 1, &enc_key)) { - return OEMCrypto_ERROR_UNKNOWN_FAILURE; + return false; } set_mac_key_server(mac_key_server); set_mac_key_client(mac_key_client); set_encryption_key(enc_key); - return OEMCrypto_SUCCESS; + return true; } -OEMCryptoResult SessionContext::RSADeriveKeys( +bool SessionContext::RSADeriveKeys( const std::vector& enc_session_key, const std::vector& mac_key_context, const std::vector& enc_key_context) { - if (!rsa_key_) { - LOGE("No RSA key set"); - return OEMCrypto_ERROR_DEVICE_NOT_RSA_PROVISIONED; + if (!rsa_key()) { + LOGE("[RSADeriveKeys(): no RSA key set]"); + return false; } - if (!(rsa_key_->allowed_schemes() & kSign_RSASSA_PSS)) { - LOGE("Key cannot be used for session key decryption"); - return OEMCrypto_ERROR_INVALID_RSA_KEY; + const size_t actual_key_size = static_cast(RSA_size(rsa_key())); + if (enc_session_key.size() != actual_key_size) { + LOGE( + "[RSADeriveKeys(): encrypted session key wrong size: %zu, expected " + "%zu]", + enc_session_key.size(), actual_key_size); + dump_boringssl_error(); + return false; } - session_key_ = rsa_key_->DecryptSessionKey(enc_session_key); - if (session_key_.empty()) { - LOGE("Failed decrypt session key"); - return OEMCrypto_ERROR_UNKNOWN_FAILURE; + session_key_.resize(RSA_size(rsa_key())); + const int decrypted_size = + RSA_private_decrypt(enc_session_key.size(), &enc_session_key[0], + &session_key_[0], rsa_key(), RSA_PKCS1_OAEP_PADDING); + if (-1 == decrypted_size) { + LOGE("[RSADeriveKeys(): error decrypting session key.]"); + dump_boringssl_error(); + return false; + } + session_key_.resize(decrypted_size); + if (decrypted_size != static_cast(wvoec::KEY_SIZE)) { + LOGE("[RSADeriveKeys(): error. Session key is wrong size: %d.]", + decrypted_size); + dump_boringssl_error(); + session_key_.clear(); + return false; } return DeriveKeys(session_key_, mac_key_context, enc_key_context); } @@ -300,13 +336,8 @@ OEMCryptoResult SessionContext::PrepAndSignLicenseRequest( uint8_t* message, size_t message_length, size_t* core_message_length, uint8_t* signature, size_t* signature_length) { if (signature_length == nullptr || core_message_length == nullptr) { - LOGE("Output length parameters are null"); return OEMCrypto_ERROR_INVALID_CONTEXT; } - if (!rsa_key_) { - LOGE("No DRM key available for signature"); - return OEMCrypto_ERROR_UNKNOWN_FAILURE; - } const size_t required_signature_size = CertSignatureSize(); OEMCryptoResult result = ODK_PrepareCoreLicenseRequest( message, message_length, core_message_length, &nonce_values_); @@ -393,10 +424,6 @@ OEMCryptoResult SessionContext::PrepAndSignProvisioningRequest( if (signature_length == nullptr || core_message_length == nullptr) { return OEMCrypto_ERROR_INVALID_CONTEXT; } - if (!rsa_key_ && mac_key_client_.empty()) { - LOGE("Session cannot sign request"); - return OEMCrypto_ERROR_UNKNOWN_FAILURE; - } if (state_request_signed_) { LOGE("Attempt to sign prov request after license request"); return OEMCrypto_ERROR_UNKNOWN_FAILURE; @@ -461,20 +488,29 @@ OEMCryptoResult SessionContext::GenerateSignature(const uint8_t* message, return OEMCrypto_ERROR_UNKNOWN_FAILURE; } -size_t SessionContext::CertSignatureSize() const { - if (!rsa_key_) { - LOGE("No RSA key set"); +// This is ussd when the device is a cast receiver. +size_t SessionContext::RSASignatureSize() { + if (!rsa_key()) { + LOGE("no RSA key set"); return 0; } - return rsa_key_->SignatureSize(); + return static_cast(RSA_size(rsa_key())); } -size_t SessionContext::ROTSignatureSize() const { +size_t SessionContext::CertSignatureSize() { + // TODO(b/67735947): Add ECC cert support. + if (!rsa_key()) { + LOGE("No private key set"); + return 0; + } + return static_cast(RSA_size(rsa_key())); +} + +size_t SessionContext::ROTSignatureSize() { if (ce_->config_provisioning_method() == OEMCrypto_Keybox) return SHA256_DIGEST_LENGTH; - if (ce_->config_provisioning_method() == OEMCrypto_OEMCertificate) { + if (ce_->config_provisioning_method() == OEMCrypto_OEMCertificate) return CertSignatureSize(); - } LOGE("Bad prov method = %d", static_cast(ce_->config_provisioning_method())); return 0; @@ -483,27 +519,92 @@ size_t SessionContext::ROTSignatureSize() const { OEMCryptoResult SessionContext::GenerateCertSignature( const uint8_t* message, size_t message_length, uint8_t* signature, size_t* signature_length) { - if (!rsa_key_) { + // TODO(b/67735947): Add ECC cert support. + if (message == nullptr || message_length == 0 || signature == nullptr || + signature_length == 0) { + LOGE("OEMCrypto_ERROR_INVALID_CONTEXT"); + return OEMCrypto_ERROR_INVALID_CONTEXT; + } + if (!rsa_key()) { LOGE("No RSA key set"); return OEMCrypto_ERROR_INVALID_RSA_KEY; } - return rsa_key_->GenerateSignature(message, message_length, kRsaPssDefault, - signature, signature_length); + if (*signature_length < static_cast(RSA_size(rsa_key()))) { + *signature_length = CertSignatureSize(); + return OEMCrypto_ERROR_SHORT_BUFFER; + } + if (allowed_schemes_ != kSign_RSASSA_PSS) { + LOGE("Message signing not allowed"); + return OEMCrypto_ERROR_INVALID_RSA_KEY; + } + + // Hash the message using SHA1. + uint8_t hash[SHA_DIGEST_LENGTH]; + if (!SHA1(message, message_length, hash)) { + LOGE("Error creating signature hash"); + dump_boringssl_error(); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + // Add PSS padding. + std::vector padded_digest(*signature_length); + int status = RSA_padding_add_PKCS1_PSS_mgf1( + rsa_key(), &padded_digest[0], hash, EVP_sha1(), nullptr, kPssSaltLength); + if (status == -1) { + LOGE("Error padding hash"); + dump_boringssl_error(); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + + // Encrypt PSS padded digest. + status = RSA_private_encrypt(*signature_length, &padded_digest[0], signature, + rsa_key(), RSA_NO_PADDING); + if (status == -1) { + LOGE("Error in private encrypt"); + dump_boringssl_error(); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + return OEMCrypto_SUCCESS; } OEMCryptoResult SessionContext::GenerateRSASignature( const uint8_t* message, size_t message_length, uint8_t* signature, size_t* signature_length, RSA_Padding_Scheme padding_scheme) { - if (padding_scheme != kSign_PKCS1_Block1) { - LOGE("Only PKCS1 block1 padding scheme allowed"); + if (message == nullptr || message_length == 0 || signature == nullptr || + signature_length == 0) { + LOGE("OEMCrypto_ERROR_INVALID_CONTEXT"); return OEMCrypto_ERROR_INVALID_CONTEXT; } - if (!rsa_key_) { + if (!rsa_key()) { LOGE("No RSA key set"); return OEMCrypto_ERROR_INVALID_RSA_KEY; } - return rsa_key_->GenerateSignature(message, message_length, kRsaPkcs1Cast, - signature, signature_length); + if (*signature_length < static_cast(RSA_size(rsa_key()))) { + *signature_length = RSA_size(rsa_key()); + return OEMCrypto_ERROR_SHORT_BUFFER; + } + if (((padding_scheme & allowed_schemes_) != padding_scheme) || + (padding_scheme != kSign_PKCS1_Block1)) { + LOGE("padding_scheme not allowed"); + return OEMCrypto_ERROR_INVALID_RSA_KEY; + } + // This is the maximum digest size possible for PKCS1 block type 1, + // as used for a CAST receiver. + const size_t max_digest_size = 83u; + if (message_length > max_digest_size) { + LOGE("RSA digest too large"); + return OEMCrypto_ERROR_SIGNATURE_FAILURE; + } + // Pad the message with PKCS1 padding, and then encrypt. + const int status = RSA_private_encrypt(message_length, message, signature, + rsa_key(), RSA_PKCS1_PADDING); + if (status < 0) { + LOGE("Error in RSA private encrypt. status = %d", status); + dump_boringssl_error(); + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + *signature_length = static_cast(RSA_size(rsa_key())); + return OEMCrypto_SUCCESS; } // Validate message signature @@ -933,19 +1034,24 @@ OEMCryptoResult SessionContext::InstallKey( } bool SessionContext::InstallRSAEncryptedKey( - const std::vector& enc_encryption_key) { - if (!rsa_key_) { - LOGE("Session does not have an OEM cert key"); + const uint8_t* encrypted_message_key, size_t encrypted_message_key_length) { + encryption_key_.resize(RSA_size(rsa_key())); + const int decrypted_size = RSA_private_decrypt( + encrypted_message_key_length, encrypted_message_key, &encryption_key_[0], + rsa_key(), RSA_PKCS1_OAEP_PADDING); + if (-1 == decrypted_size) { + LOGE("[RSADeriveKeys(): error decrypting session key.]"); + dump_boringssl_error(); return false; } - - std::vector encryption_key = - rsa_key_->DecryptEncryptionKey(enc_encryption_key); - if (encryption_key.empty()) { - LOGE("Failed to decrypt session encryption key"); + encryption_key_.resize(decrypted_size); + if (decrypted_size != static_cast(wvoec::KEY_SIZE)) { + LOGE("[RSADeriveKeys(): error. Session key is wrong size: %d.]", + decrypted_size); + dump_boringssl_error(); + encryption_key_.clear(); return false; } - encryption_key_ = std::move(encryption_key); return true; } @@ -1056,23 +1162,23 @@ bool SessionContext::EncryptRSAKey(const uint8_t* pkcs8_rsa_key, return true; } -bool SessionContext::LoadRsaDrmKey(const uint8_t* pkcs8_rsa_key, - size_t rsa_key_length) { - std::unique_ptr key = - RsaPrivateKey::Load(pkcs8_rsa_key, rsa_key_length); - if (!key) { - LOGE("Failed to parse RSA key"); +bool SessionContext::LoadRSAKey(const uint8_t* pkcs8_rsa_key, + size_t rsa_key_length) { + rsa_key_.reset(); + if (rsa_key_length < 8) { + LOGE("[LoadRSAKey(): Very Short Buffer]"); return false; } - constexpr uint8_t kAllSchemes = kSign_RSASSA_PSS | kSign_PKCS1_Block1; - if (key->allowed_schemes() == 0 || - (key->allowed_schemes() & kAllSchemes) == kAllSchemes) { - LOGE("RSA DRM key has an invalid set of schemes: allowed_schemes = 0x%08x", - key->allowed_schemes()); - return false; + if ((memcmp(pkcs8_rsa_key, "SIGN", 4) == 0)) { + uint32_t schemes_n; + memcpy((uint8_t*)&schemes_n, pkcs8_rsa_key + 4, sizeof(uint32_t)); + allowed_schemes_ = htonl(schemes_n); + pkcs8_rsa_key += 8; + rsa_key_length -= 8; + } else { + allowed_schemes_ = kSign_RSASSA_PSS; } - rsa_key_ = std::move(key); - return true; + return rsa_key_.LoadPkcs8RsaKey(pkcs8_rsa_key, rsa_key_length); } OEMCryptoResult SessionContext::CheckKeyUse(const std::string& log_string, @@ -1255,6 +1361,7 @@ OEMCryptoResult SessionContext::Generic_Sign(const uint8_t* in_buffer, return OEMCrypto_SUCCESS; } LOGE("[Generic_Sign(): hmac failed"); + dump_boringssl_error(); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } @@ -1295,6 +1402,7 @@ OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer, } } LOGE("[Generic_Verify(): HMAC failed"); + dump_boringssl_error(); return OEMCrypto_ERROR_UNKNOWN_FAILURE; } diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h index 4ed6846e..cd768b96 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h @@ -18,7 +18,7 @@ #include "odk_structs.h" #include "oemcrypto_auth_ref.h" #include "oemcrypto_key_ref.h" -#include "oemcrypto_rsa_key.h" +#include "oemcrypto_rsa_key_shared.h" #include "oemcrypto_session_key_table.h" #include "oemcrypto_types.h" #include "oemcrypto_usage_table_ref.h" @@ -59,22 +59,21 @@ class SessionContextKeys { }; class SessionContext { + public: - SessionContext(CryptoEngine* ce, SessionId sid); SessionContext(CryptoEngine* ce, SessionId sid, - std::shared_ptr&& rsa_key); + const RSA_shared_ptr& rsa_key); SessionContext() = delete; virtual ~SessionContext(); - bool isValid() const { return valid_; } + bool isValid() { return valid_; } - virtual OEMCryptoResult DeriveKeys(const std::vector& master_key, - const std::vector& mac_context, - const std::vector& enc_context); - virtual OEMCryptoResult RSADeriveKeys( - const std::vector& enc_session_key, - const std::vector& mac_context, - const std::vector& enc_context); + virtual bool DeriveKeys(const std::vector& master_key, + const std::vector& mac_context, + const std::vector& enc_context); + virtual bool RSADeriveKeys(const std::vector& enc_session_key, + const std::vector& mac_context, + const std::vector& enc_context); virtual OEMCryptoResult PrepAndSignLicenseRequest(uint8_t* message, size_t message_length, size_t* core_message_length, @@ -88,7 +87,9 @@ class SessionContext { virtual OEMCryptoResult PrepAndSignProvisioningRequest( uint8_t* message, size_t message_length, size_t* core_message_length, uint8_t* signature, size_t* signature_length); - // Restricted to CAST receivers using PKCS1 block padding only. + // The size of an RSA signature. This is used when signing as a CAST + // receiver. + size_t RSASignatureSize(); virtual OEMCryptoResult GenerateRSASignature( const uint8_t* message, size_t message_length, uint8_t* signature, size_t* signature_length, RSA_Padding_Scheme padding_scheme); @@ -140,12 +141,13 @@ class SessionContext { const std::vector& key_data_iv, const std::vector& key_control, const std::vector& key_control_iv); - bool InstallRSAEncryptedKey(const std::vector& enc_encryption_key); + bool InstallRSAEncryptedKey(const uint8_t* encrypted_message_key, + size_t encrypted_message_key_length); bool DecryptRSAKey(const uint8_t* enc_rsa_key, size_t enc_rsa_key_length, const uint8_t* wrapped_rsa_key_iv, uint8_t* pkcs8_rsa_key); bool EncryptRSAKey(const uint8_t* pkcs8_rsa_key, size_t enc_rsa_key_length, const uint8_t* enc_rsa_key_iv, uint8_t* enc_rsa_key); - bool LoadRsaDrmKey(const uint8_t* pkcs8_rsa_key, size_t rsa_key_length); + bool LoadRSAKey(const uint8_t* pkcs8_rsa_key, size_t rsa_key_length); virtual OEMCryptoResult LoadRenewal(const uint8_t* message, size_t message_length, size_t core_message_length, @@ -177,6 +179,7 @@ class SessionContext { encryption_key_ = enc_key; } const std::vector& encryption_key() { return encryption_key_; } + uint32_t allowed_schemes() const { return allowed_schemes_; } // Return true if nonce was set. bool set_nonce(uint32_t nonce); @@ -202,9 +205,9 @@ class SessionContext { protected: // Signature size of the currently loaded private key. - size_t CertSignatureSize() const; + size_t CertSignatureSize(); // Signature size when using a keybox or OEM Cert's private key. - size_t ROTSignatureSize() const; + size_t ROTSignatureSize(); virtual OEMCryptoResult GenerateCertSignature(const uint8_t* message, size_t message_length, uint8_t* signature, @@ -254,52 +257,46 @@ class SessionContext { // entry, it also checks the usage entry. OEMCryptoResult CheckKeyUse(const std::string& log_string, uint32_t use_type, OEMCryptoBufferType buffer_type); + RSA* rsa_key() { return rsa_key_.get(); } - bool valid_ = false; - CryptoEngine* ce_ = nullptr; + bool valid_; + CryptoEngine* ce_; SessionId id_; - - // Message keys. - std::shared_ptr rsa_key_; std::vector mac_key_server_; std::vector mac_key_client_; std::vector encryption_key_; std::vector session_key_; - + const Key* current_content_key_; + std::unique_ptr session_keys_; ODK_NonceValues nonce_values_; uint8_t license_request_hash_[ODK_SHA256_HASH_SIZE]; - - // Content/entitlement keys. - const Key* current_content_key_ = nullptr; - std::unique_ptr session_keys_; - - bool decrypt_started_ = - false; // If the license has been used in this session. + RSA_shared_ptr rsa_key_; + uint32_t allowed_schemes_; // for RSA signatures. + bool decrypt_started_; // If the license has been used in this session. ODK_TimerLimits timer_limits_; ODK_ClockValues clock_values_; std::unique_ptr usage_entry_; - SRMVersionStatus srm_requirements_status_ = NoSRMVersion; + SRMVersionStatus srm_requirements_status_; enum UsageEntryStatus { kNoUsageEntry, // No entry loaded for this session. kUsageEntryNew, // After entry was created. kUsageEntryLoaded, // After loading entry or loading keys. }; - UsageEntryStatus usage_entry_status_ = kNoUsageEntry; + UsageEntryStatus usage_entry_status_; // These are used when doing full decrypt path testing. - bool compute_hash_ = false; // True if the current frame needs a hash. - uint32_t current_hash_ = 0; // Running CRC hash of frame. - uint32_t given_hash_ = 0; // True CRC hash of frame. - uint32_t current_frame_number_ = 0; // Current frame for CRC hash. - uint32_t bad_frame_number_ = 0; // Frame number with bad hash. - OEMCryptoResult hash_error_ = - OEMCrypto_SUCCESS; // Error code for first bad frame. + bool compute_hash_; // True if the current frame needs a hash. + uint32_t current_hash_; // Running CRC hash of frame. + uint32_t given_hash_; // True CRC hash of frame. + uint32_t current_frame_number_; // Current frame for CRC hash. + uint32_t bad_frame_number_; // Frame number with bad hash. + OEMCryptoResult hash_error_; // Error code for first bad frame. // The bare minimum state machine is to only call each of these function // categories at most once. - bool state_nonce_created_ = false; - bool state_request_signed_ = false; - bool state_response_loaded_ = false; + bool state_nonce_created_; + bool state_request_signed_; + bool state_response_loaded_; CORE_DISALLOW_COPY_AND_ASSIGN(SessionContext); };