From e95eebf326fc90a7fd011bd2c15d18c352c3775c Mon Sep 17 00:00:00 2001 From: Fred Gylys-Colwell Date: Thu, 10 Apr 2014 17:34:51 -0700 Subject: [PATCH] Refactor OEMCrypto mock and its unit tests This is a copy of the Widevine CL: https://widevine-internal-review.googlesource.com/#/c/9708/ This CL refactors some of code in oemcrypto/mock and oemcrypto/test in preparation for adding usage table code. Change-Id: I7e58c8ecd6d92b3e177cb915733212fcad645485 --- .../mock/src/oemcrypto_engine_mock.cpp | 376 ++- .../mock/src/oemcrypto_engine_mock.h | 64 +- .../oemcrypto/mock/src/oemcrypto_key_mock.cpp | 140 +- .../oemcrypto/mock/src/oemcrypto_key_mock.h | 55 +- .../mock/src/oemcrypto_keybox_mock.cpp | 7 +- .../mock/src/oemcrypto_keybox_mock.h | 4 +- .../oemcrypto/mock/src/oemcrypto_mock.cpp | 129 +- libwvdrmengine/oemcrypto/test/Android.mk | 1 + .../oemcrypto/test/oemcrypto_test.cpp | 2852 ++++++----------- 9 files changed, 1343 insertions(+), 2285 deletions(-) diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp index f4740ad9..3ba09608 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp @@ -79,19 +79,13 @@ void SessionKeyTable::Remove(const KeyId key_id) { } } -bool SessionKeyTable::UpdateDuration(const KeyControlBlock& control) { +void SessionKeyTable::UpdateDuration(const KeyControlBlock& control) { for(KeyMap::iterator it = keys_.begin(); it != keys_.end(); ++it) { - if (!it->second->UpdateDuration(control)) { - return false; - } + it->second->UpdateDuration(control); } - return true; } -void SessionContext::Open() { -} - -void SessionContext::Close() { +SessionContext::~SessionContext() { } // Internal utility function to derive key using CMAC-128 @@ -235,7 +229,7 @@ bool SessionContext::GenerateSignature(const uint8_t* message, } unsigned int md_len = *signature_length; - if (HMAC(EVP_sha256(), &mac_key_client_[0], SHA256_DIGEST_LENGTH, + if (HMAC(EVP_sha256(), &mac_key_client_[0], mac_key_client_.size(), message, message_length, signature, &md_len)) { *signature_length = md_len; return true; @@ -331,7 +325,7 @@ bool SessionContext::ValidateMessage(const uint8_t* given_message, } uint8_t computed_signature[SHA256_DIGEST_LENGTH]; unsigned int md_len = SHA256_DIGEST_LENGTH; - if (!HMAC(EVP_sha256(), &mac_key_server_[0], SHA256_DIGEST_LENGTH, + if (!HMAC(EVP_sha256(), &mac_key_server_[0], mac_key_server_.size(), given_message, message_length, computed_signature, &md_len)) { LOGE("ValidateMessage: Could not compute signature."); return false; @@ -346,75 +340,14 @@ bool SessionContext::ValidateMessage(const uint8_t* given_message, return true; } -bool SessionContext::ParseKeyControl( - const std::vector& key_control_string, - KeyControlBlock& key_control_block) { - - key_control_block.Invalidate(); - - if (key_control_string.size() < wvcdm::KEY_CONTROL_SIZE) { - LOGD("ParseKeyControl: wrong size."); - return false; - } - if (!key_control_block.SetFromString(key_control_string)) { - LOGE("KCB: BAD Size or Structure"); - return false; - } - - LOGD("KCB:"); - LOGD(" valid: %d", key_control_block.valid()); - LOGD(" duration: %d", key_control_block.duration()); - LOGD(" nonce: %08X", key_control_block.nonce()); - LOGD(" magic: %08X", key_control_block.verification()); - LOGD(" bits: %08X", key_control_block.control_bits()); - switch(key_control_block.control_bits() & kControlReplayMask) { - case kControlNonceRequired: - LOGD(" bits kControlReplay kControlNonceRequired."); - break; - case kControlNonceOrEntry: - LOGD(" bits kControlReplay kControlNonceOrEntry."); - break; - default: - LOGD(" bits kControlReplay unset."); - break; - } - LOGD(" bits kControlKDCPVersion 0x%02x.", - (key_control_block.control_bits() & kControlHDCPVersionMask) - >> kControlHDCPVersionShift); - LOGD(" bit kControlAllowEncrypt %s.", - (key_control_block.control_bits() & kControlAllowEncrypt) ? "set" : "unset"); - LOGD(" bit kControlAllowDecrypt %s.", - (key_control_block.control_bits() & kControlAllowDecrypt) ? "set" : "unset"); - LOGD(" bit kControlAllowSign %s.", - (key_control_block.control_bits() & kControlAllowSign) ? "set" : "unset"); - LOGD(" bit kControlAllowVerify %s.", - (key_control_block.control_bits() & kControlAllowVerify) ? "set" : "unset"); - LOGD(" bit kControlObserveDataPath %s.", - (key_control_block.control_bits() & kControlObserveDataPath) ? "set" : "unset"); - LOGD(" bit kControlObserveHDCP %s.", - (key_control_block.control_bits() & kControlObserveHDCP) ? "set" : "unset"); - LOGD(" bit kControlObserveCGMS %s.", - (key_control_block.control_bits() & kControlObserveCGMS) ? "set" : "unset"); - LOGD(" bit kControlDataPathSecure %s.", - (key_control_block.control_bits() & kControlDataPathSecure) ? "set" : "unset"); - LOGD(" bit kControlNonceEnabled %s.", - (key_control_block.control_bits() & kControlNonceEnabled) ? "set" : "unset"); - LOGD(" bit kControlHDCPRequired %s.", - (key_control_block.control_bits() & kControlHDCPRequired) ? "set" : "unset"); - uint32_t cgms_bits = key_control_block.control_bits() & 0x3; - const char* cgms_values[4] = {"free", "BAD", "once", "never"}; - LOGD(" CGMS = %s", cgms_values[cgms_bits]); - - if (!key_control_block.Validate()) { - LOGE("KCB: BAD Signature"); - return false; - } - if ((key_control_block.control_bits() & kControlNonceEnabled) - && (!CheckNonce(key_control_block.nonce()))) { +bool SessionContext::CheckNonceOrPST(KeyControlBlock& key_control_block, + const std::vector& pst) { + // TODO(fredgc): look at replay control bits, too. + if ((key_control_block.control_bits() & kControlNonceEnabled) && + (!CheckNonce(key_control_block.nonce()))) { LOGE("KCB: BAD Nonce"); return false; } - return true; } @@ -427,19 +360,79 @@ uint32_t SessionContext::CurrentTimer() { return now - timer_start_; } +OEMCryptoResult SessionContext::LoadKeys( + OEMCrypto_SESSION session, const uint8_t* message, size_t message_length, + const uint8_t* signature, size_t signature_length, + const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_keys, size_t num_keys, + const OEMCrypto_KeyObject* key_array, const uint8_t* pst, + size_t pst_length) { + // Validate message signature + if (!ValidateMessage(message, message_length, signature, signature_length)) { + return OEMCrypto_ERROR_SIGNATURE_FAILURE; + } + + StartTimer(); + + // Decrypt and install keys in key object + // Each key will have a key control block. They will all have the same nonce. + bool status = true; + std::vector key_id; + std::vector enc_key_data; + std::vector key_data_iv; + std::vector key_control; + std::vector key_control_iv; + std::vector pstv(pst, pst + pst_length); + for (unsigned int i = 0; i < num_keys; i++) { + key_id.assign(key_array[i].key_id, + key_array[i].key_id + key_array[i].key_id_length); + enc_key_data.assign(key_array[i].key_data, + key_array[i].key_data + key_array[i].key_data_length); + key_data_iv.assign(key_array[i].key_data_iv, + key_array[i].key_data_iv + wvcdm::KEY_IV_SIZE); + if (key_array[i].key_control == NULL) { + status = false; + break; + } + key_control.assign(key_array[i].key_control, + key_array[i].key_control + wvcdm::KEY_CONTROL_SIZE); + key_control_iv.assign(key_array[i].key_control_iv, + key_array[i].key_control_iv + wvcdm::KEY_IV_SIZE); + + if (!InstallKey(key_id, enc_key_data, key_data_iv, key_control, + key_control_iv, pstv)) { + status = false; + break; + } + } + FlushNonces(); + if (!status) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + + // enc_mac_key can be NULL if license renewal is not supported + if (enc_mac_keys != NULL) { + // V2.1 license protocol: update mac keys after processing license response + const std::vector enc_mac_keys_str = std::vector( + enc_mac_keys, enc_mac_keys + 2 * wvcdm::MAC_KEY_SIZE); + const std::vector enc_mac_key_iv_str = std::vector( + enc_mac_key_iv, enc_mac_key_iv + wvcdm::KEY_IV_SIZE); + + if (!UpdateMacKeys(enc_mac_keys_str, enc_mac_key_iv_str)) { + return OEMCrypto_ERROR_UNKNOWN_FAILURE; + } + } + return OEMCrypto_SUCCESS; +} + bool SessionContext::InstallKey(const KeyId& key_id, const std::vector& key_data, const std::vector& key_data_iv, const std::vector& key_control, - const std::vector& key_control_iv) { - + const std::vector& key_control_iv, + const std::vector& pst) { // Decrypt encrypted key_data using derived encryption key and offered iv std::vector content_key; std::vector key_control_str; - KeyControlBlock key_control_block; - if (!ce_->DecryptMessage(this, encryption_key_, key_data_iv, - key_data, &content_key)) { + if (!DecryptMessage(encryption_key_, key_data_iv, key_data, &content_key)) { LOGE("[Installkey(): Could not decrypt key data]"); return false; } @@ -456,27 +449,94 @@ bool SessionContext::InstallKey(const KeyId& key_id, // Key control must be supplied by license server if (key_control.empty()) { LOGE("[Installkey(): WARNING: No Key Control]"); - key_control_block.Invalidate(); return false; - } else { - if (key_control_iv.empty()) { - LOGE("[Installkey(): ERROR: No Key Control IV]"); - return false; - } - if (!ce_->DecryptMessage(this, content_key, key_control_iv, - key_control, &key_control_str)) { - LOGE("[Installkey(): ERROR: Could not decrypt content key]"); - return false; - } + } + if (key_control_iv.empty()) { + LOGE("[Installkey(): ERROR: No Key Control IV]"); + return false; + } + if (!DecryptMessage(content_key, key_control_iv, key_control, + &key_control_str)) { + LOGE("[Installkey(): ERROR: Could not decrypt content key]"); + return false; + } - if (!ParseKeyControl(key_control_str, key_control_block)) { - LOGE("Error parsing key control."); + KeyControlBlock key_control_block(key_control_str); + if (!key_control_block.valid()) { + LOGE("Error parsing key control."); + return false; + } + if (!CheckNonceOrPST(key_control_block, pst)) { + LOGE("Failed Nonce or PST check."); + return false; + } + + Key key(content_key, key_control_block); + session_keys_.Insert(key_id, key); + return true; +} + +bool SessionContext::RefreshKey(const KeyId& key_id, + const std::vector& key_control, + const std::vector& key_control_iv) { + if (key_id.empty()) { + // Key control is not encrypted if key id is NULL + KeyControlBlock key_control_block(key_control); + if (!key_control_block.valid()) { + LOGD("Parse key control error."); + return false; + } + if ((key_control_block.control_bits() & kControlNonceEnabled) && + (!CheckNonce(key_control_block.nonce()))) { + LOGE("KCB: BAD Nonce"); + return false; + } + // Apply duration to all keys in this session + session_keys_.UpdateDuration(key_control_block); + return true; + } + + Key* content_key = session_keys_.Find(key_id); + + if (NULL == content_key) { + LOGD("Error: no matching content key."); + return false; + } + + if (key_control.empty()) { + LOGD("Error: no key_control."); + return false; + } + + const std::vector content_key_value = content_key->value(); + + // Decrypt encrypted key control block + std::vector control; + if (key_control_iv.empty()) { + // TODO(fredg): get confirmation from server team this is valid. + LOGD("Key control block is NOT encrypted."); + control = key_control; + } else { + // TODO(fredg): get confirmation from server team this is valid, too. + LOGD("Key control block is encrypted."); + if (!DecryptMessage(content_key_value, key_control_iv, key_control, + &control)) { + LOGD("Error decrypting key control block."); return false; } } - Key key(KEYTYPE_CONTENT, content_key, key_control_block); - session_keys_.Insert(key_id, key); + KeyControlBlock key_control_block(control); + if (!key_control_block.valid()) { + LOGD("Parse key control error."); + return false; + } + if ((key_control_block.control_bits() & kControlNonceEnabled) && + (!CheckNonce(key_control_block.nonce()))) { + LOGE("KCB: BAD Nonce"); + return false; + } + content_key->UpdateDuration(key_control_block); return true; } @@ -720,7 +780,7 @@ OEMCryptoResult SessionContext::Generic_Sign(const uint8_t* in_buffer, return OEMCrypto_ERROR_UNKNOWN_FAILURE; } unsigned int md_len = *signature_length; - if (HMAC(EVP_sha256(), &key[0], SHA256_DIGEST_LENGTH, + if (HMAC(EVP_sha256(), &key[0], key.size(), in_buffer, buffer_length, signature, &md_len)) { *signature_length = md_len; return OEMCrypto_SUCCESS; @@ -765,7 +825,7 @@ OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer, } unsigned int md_len = signature_length; uint8_t computed_signature[SHA256_DIGEST_LENGTH]; - if (HMAC(EVP_sha256(), &key[0], SHA256_DIGEST_LENGTH, + if (HMAC(EVP_sha256(), &key[0], key.size(), in_buffer, buffer_length, computed_signature, &md_len)) { if (0 == memcmp(signature, computed_signature, SHA256_DIGEST_LENGTH)) { return OEMCrypto_SUCCESS; @@ -778,71 +838,12 @@ OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer, return OEMCrypto_ERROR_UNKNOWN_FAILURE; } -bool SessionContext::RefreshKey(const KeyId& key_id, - const std::vector& key_control, - const std::vector& key_control_iv) { - if (key_id.empty()) { - // Key control is not encrypted if key id is NULL - KeyControlBlock key_control_block(true); - if (!ParseKeyControl(key_control, key_control_block)) { - LOGD("Parse key control error."); - return false; - } - // Apply duration to all keys in this session - return session_keys_.UpdateDuration(key_control_block); - } - - Key* content_key = session_keys_.Find(key_id); - - if (NULL == content_key) { - LOGD("Error: no matching content key."); - return false; - } - - if (key_control.empty()) { - LOGD("Error: no key_control."); - return false; - } - - const std::vector content_key_value = content_key->value(); - - // Decrypt encrypted key control block - std::vector control; - if (key_control_iv.empty()) { - // TODO(fredg): get confirmation from server team this is valid. - LOGD("Key control block is NOT encrypted."); - control = key_control; - } else { - // TODO(fredg): get confirmation from server team this is valid, too. - LOGD("Key control block is encrypted."); - if (!ce_->DecryptMessage(this, content_key_value, key_control_iv, - key_control, &control)) { - LOGD("Error decrypting key control block."); - return false; - } - } - - KeyControlBlock key_control_block(true); - if (!ParseKeyControl(control, key_control_block)) { - LOGD("Error parsing key control."); - return false; - } - - if (!content_key->UpdateDuration(key_control_block)) { - LOGD("Error updating duration."); - return false; - } - - return true; -} - bool SessionContext::UpdateMacKeys(const std::vector& enc_mac_keys, const std::vector& iv) { // Decrypt mac key from enc_mac_key using device_keya std::vector mac_keys; - if (!ce_->DecryptMessage(this, encryption_key_, iv, - enc_mac_keys, &mac_keys)) { + if (!DecryptMessage(encryption_key_, iv, enc_mac_keys, &mac_keys)) { return false; } mac_key_server_ = std::vector(mac_keys.begin(), @@ -933,11 +934,10 @@ SessionContext* CryptoEngine::FindSession(SessionId sid) { } // Internal utility function to decrypt the message -bool CryptoEngine::DecryptMessage(SessionContext* session, - const std::vector& key, - const std::vector& iv, - const std::vector& message, - std::vector* decrypted) { +bool SessionContext::DecryptMessage(const std::vector& key, + const std::vector& iv, + const std::vector& message, + std::vector* decrypted) { if (key.empty() || iv.empty() || message.empty() || !decrypted) { LOGE("[DecryptMessage(): OEMCrypto_ERROR_INVALID_CONTEXT]"); return false; @@ -952,13 +952,10 @@ bool CryptoEngine::DecryptMessage(SessionContext* session, return true; } -OEMCryptoResult CryptoEngine::DecryptCTR(SessionContext* session, - const uint8_t* iv, size_t block_offset, - const uint8_t* cipher_data, - size_t cipher_data_length, - bool is_encrypted, uint8_t* clear_data, - BufferType buffer_type) { - +OEMCryptoResult SessionContext::DecryptCTR( + const uint8_t* iv, size_t block_offset, const uint8_t* cipher_data, + size_t cipher_data_length, bool is_encrypted, uint8_t* clear_data, + BufferType buffer_type) { // If the data is clear, we do not need a current key selected. if (!is_encrypted && buffer_type != kBufferTypeDirect) { memcpy(reinterpret_cast(clear_data), @@ -967,39 +964,38 @@ OEMCryptoResult CryptoEngine::DecryptCTR(SessionContext* session, } // Check there is a content key - if (session->current_content_key() == NULL) { + if (current_content_key() == NULL) { LOGE("[DecryptCTR(): OEMCrypto_ERROR_NO_CONTENT_KEY]"); return OEMCrypto_ERROR_DECRYPT_FAILED; } - const KeyControlBlock& control = session->current_content_key()->control(); + const KeyControlBlock& control = current_content_key()->control(); if (control.control_bits() & kControlDataPathSecure) { if (buffer_type == kBufferTypeClear) { LOGE("[DecryptCTR(): Secure key with insecure buffer]"); return OEMCrypto_ERROR_DECRYPT_FAILED; } } - if (!local_display_) { // Only look at HDCP if the display is not local. - if (control.control_bits() & kControlHDCPRequired) { - uint8_t required_hdcp - = (control.control_bits() & kControlHDCPVersionMask) - >> kControlHDCPVersionShift; - // For reference implementation, we pretend we can handle the current - // HDCP version. - if (required_hdcp > current_hdcp_capability() - || current_hdcp_capability() == 0) { - return OEMCrypto_ERROR_INSUFFICIENT_HDCP; - } - } - } - if (control.duration() > 0) { - if (control.duration() < session->CurrentTimer()) { + if (control.duration() < CurrentTimer()) { LOGE("[DecryptCTR(): KEY_EXPIRED]"); return OEMCrypto_ERROR_KEY_EXPIRED; } } - - const std::vector& content_key = session->current_content_key()->value(); + if (!ce_->local_display()) { // Only look at HDCP if the display is not + // local. + if (control.control_bits() & kControlHDCPRequired) { + uint8_t required_hdcp = + (control.control_bits() & kControlHDCPVersionMask) >> + kControlHDCPVersionShift; + // For reference implementation, we pretend we can handle the current + // HDCP version. + if (required_hdcp > ce_->current_hdcp_capability() || + ce_->current_hdcp_capability() == 0) { + return OEMCrypto_ERROR_INSUFFICIENT_HDCP; + } + } + } + const std::vector& content_key = current_content_key()->value(); // Set the AES key. if (static_cast(content_key.size()) != AES_BLOCK_SIZE) { diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h index c0d42b1f..9a31c5df 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h @@ -50,7 +50,7 @@ class SessionKeyTable { bool Insert(const KeyId key_id, const Key& key_data); Key* Find(const KeyId key_id); void Remove(const KeyId key_id); - bool UpdateDuration(const KeyControlBlock& control); + void UpdateDuration(const KeyControlBlock& control); private: KeyMap keys_; @@ -87,12 +87,13 @@ class SessionContext { public: explicit SessionContext(CryptoEngine* ce, SessionId sid) - : valid_(true), ce_(ce), id_(sid), current_content_key_(NULL), - rsa_key_(NULL), allowed_schemes_(kSign_RSASSA_PSS) {} - ~SessionContext() {} - - void Open(); - void Close(); + : valid_(true), + ce_(ce), + id_(sid), + current_content_key_(NULL), + rsa_key_(NULL), + allowed_schemes_(kSign_RSASSA_PSS) {} + ~SessionContext(); bool isValid() { return valid_; } @@ -116,6 +117,11 @@ class SessionContext { size_t message_length, const uint8_t* signature, size_t signature_length); + OEMCryptoResult DecryptCTR(const uint8_t* iv, size_t block_offset, + const uint8_t* cipher_data, + size_t cipher_data_length, bool is_encrypted, + uint8_t* clear_data, BufferType buffer_type); + OEMCryptoResult Generic_Encrypt(const uint8_t* in_buffer, size_t buffer_length, const uint8_t* iv, OEMCrypto_Algorithm algorithm, @@ -133,11 +139,23 @@ class SessionContext { size_t signature_length); void StartTimer(); uint32_t CurrentTimer(); // (seconds). + OEMCryptoResult LoadKeys(OEMCrypto_SESSION session, + const uint8_t* message, + size_t message_length, + const uint8_t* signature, + size_t signature_length, + const uint8_t* enc_mac_key_iv, + const uint8_t* enc_mac_keys, + size_t num_keys, + const OEMCrypto_KeyObject* key_array, + const uint8_t* pst, + size_t pst_length); bool InstallKey(const KeyId& key_id, const std::vector& key_data, const std::vector& key_data_iv, const std::vector& key_control, - const std::vector& key_control_iv); + const std::vector& key_control_iv, + const std::vector& pst); bool DecryptRSAKey(const uint8_t* enc_rsa_key, size_t enc_rsa_key_length, const uint8_t* wrapped_rsa_key_iv, @@ -152,8 +170,6 @@ class SessionContext { size_t message_length, const uint8_t* signature, size_t signature_length); - bool ParseKeyControl(const std::vector& key_control_string, - KeyControlBlock& key_control_block); bool RefreshKey(const KeyId& key_id, const std::vector& key_control, const std::vector& key_control_iv); @@ -166,14 +182,15 @@ class SessionContext { } const std::vector& mac_key_server() { return mac_key_server_; } void set_mac_key_client(const std::vector& mac_key_client) { - mac_key_client_ = mac_key_client; } + mac_key_client_ = mac_key_client; + } const std::vector& mac_key_client() { return mac_key_client_; } void set_encryption_key(const std::vector& enc_key) { encryption_key_ = enc_key; } const std::vector& encryption_key() { return encryption_key_; } - const uint32_t allowed_schemes() { return allowed_schemes_; } + uint32_t allowed_schemes() const { return allowed_schemes_; } void AddNonce(uint32_t nonce); bool CheckNonce(uint32_t nonce); @@ -183,6 +200,12 @@ class SessionContext { bool DeriveKey(const std::vector& key, const std::vector& context, int counter, std::vector* out); + bool DecryptMessage(const std::vector& key, + const std::vector& iv, + const std::vector& message, + std::vector* decrypted); + bool CheckNonceOrPST(KeyControlBlock& key_control_block, + const std::vector& pst); bool valid_; CryptoEngine* ce_; @@ -237,25 +260,16 @@ class CryptoEngine { current_session_ = current; } - bool DecryptMessage(SessionContext* session, - const std::vector& key, - const std::vector& iv, - const std::vector& message, - std::vector* decrypted); - - OEMCryptoResult DecryptCTR(SessionContext* session, const uint8_t* iv, - size_t block_offset, const uint8_t* cipher_data, - size_t cipher_data_length, bool is_encrypted, - uint8_t* clear_data, BufferType buffer_type); - - const OEMCrypto_HDCP_Capability current_hdcp_capability() { + OEMCrypto_HDCP_Capability current_hdcp_capability() const { return local_display_ ? 0xFF : current_hdcp_capability_; } - const OEMCrypto_HDCP_Capability maximum_hdcp_capability() { + OEMCrypto_HDCP_Capability maximum_hdcp_capability() const { return maximum_hdcp_capability_; } + bool local_display() { return local_display_; } + private: bool valid_; diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_key_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_key_mock.cpp index 3cd72d52..2f5bb631 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_key_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_key_mock.cpp @@ -15,25 +15,15 @@ namespace wvoec_mock { -bool KeyControlBlock::Validate() { - valid_ = false; - if ((0x6b63746c != verification_) && // kctl. - (0x6b633039 != verification_)) { // kc09. - LOGE("KCB: BAD verification string: %08X (not %08X or %08X)", - verification_, 0x6b63746c, 0x6b633039); - return false; - } +#define FOURCC(c1, c2, c3, c4) \ + (c1 << 24 | c2 << 16 | c3 << 8 | c4) - if (refresh_) { - if (control_bits_ & kControlObserveDataPath) { - LOGW("KCB: data_path_type set for refresh."); - } - if (control_bits_ & kControlObserveHDCP) { - LOGW("KCB: HDCP setting set for refresh."); - } - if (control_bits_ & kControlObserveCGMS) { - LOGW("KCB: CGMS setting set for refresh."); - } +bool KeyControlBlock::Validate() { + if ((FOURCC('k', 'c', 't', 'l') != verification_) && // original verification + (FOURCC('k', 'c', '0', '9') != verification_)) { // add in version 9 api. + LOGE("KCB: BAD verification string: %08X (not %08X or %08X)", verification_, + 0x6b63746c, 0x6b633039); + return false; } valid_ = true; return valid_; @@ -50,11 +40,12 @@ uint32_t KeyControlBlock::ExtractField(const std::vector& str, int idx) return t; } -bool KeyControlBlock::SetFromString(const std::vector& key_control_string) { +KeyControlBlock::KeyControlBlock( + const std::vector& key_control_string) { if (key_control_string.size() < wvcdm::KEY_CONTROL_SIZE) { LOGE("KCB: BAD Size: %d (not %d)",key_control_string.size(), wvcdm::KEY_CONTROL_SIZE); - return false; + return; } verification_ = ExtractField(key_control_string, 0); @@ -62,73 +53,56 @@ bool KeyControlBlock::SetFromString(const std::vector& key_control_stri nonce_ = ExtractField(key_control_string, 2); control_bits_ = ExtractField(key_control_string, 3); - return Validate(); + LOGD("KCB:"); + LOGD(" valid: %d", valid()); + LOGD(" duration: %d", duration()); + LOGD(" nonce: %08X", nonce()); + LOGD(" magic: %08X", verification()); + LOGD(" bits: %08X", control_bits()); + switch (control_bits() & kControlReplayMask) { + case kControlNonceRequired: + LOGD(" bits kControlReplay kControlNonceRequired."); + break; + case kControlNonceOrEntry: + LOGD(" bits kControlReplay kControlNonceOrEntry."); + break; + default: + LOGD(" bits kControlReplay unset."); + break; + } + LOGD(" bits kControlKDCPVersion 0x%02x.", + (control_bits() & kControlHDCPVersionMask) >> kControlHDCPVersionShift); + LOGD(" bit kControlAllowEncrypt %s.", + (control_bits() & kControlAllowEncrypt) ? "set" : "unset"); + LOGD(" bit kControlAllowDecrypt %s.", + (control_bits() & kControlAllowDecrypt) ? "set" : "unset"); + LOGD(" bit kControlAllowSign %s.", + (control_bits() & kControlAllowSign) ? "set" : "unset"); + LOGD(" bit kControlAllowVerify %s.", + (control_bits() & kControlAllowVerify) ? "set" : "unset"); + LOGD(" bit kControlObserveDataPath %s.", + (control_bits() & kControlObserveDataPath) ? "set" : "unset"); + LOGD(" bit kControlObserveHDCP %s.", + (control_bits() & kControlObserveHDCP) ? "set" : "unset"); + LOGD(" bit kControlObserveCGMS %s.", + (control_bits() & kControlObserveCGMS) ? "set" : "unset"); + LOGD(" bit kControlDataPathSecure %s.", + (control_bits() & kControlDataPathSecure) ? "set" : "unset"); + LOGD(" bit kControlNonceEnabled %s.", + (control_bits() & kControlNonceEnabled) ? "set" : "unset"); + LOGD(" bit kControlHDCPRequired %s.", + (control_bits() & kControlHDCPRequired) ? "set" : "unset"); + uint32_t cgms_bits = control_bits() & 0x3; + const char* cgms_values[4] = {"free", "BAD", "once", "never"}; + LOGD(" CGMS = %s", cgms_values[cgms_bits]); + Validate(); } -Key::Key(KeyType ktype, const std::vector& key_string, - const KeyControlBlock& control) : - valid_(true), type_(ktype), - value_(key_string), has_control_(true), - control_(control) { -} - -bool Key::setValue(const char* key_string, size_t key_string_length) { - valid_ = false; - if (!key_string || key_string_length == 0) { - return false; - } - - value_.assign(key_string, key_string + key_string_length); - - if (isValidType() && has_control_) { - valid_ = true; - } - return valid_; -} - -bool Key::setType(KeyType ktype) { - valid_ = false; - type_ = ktype; - if (value_.empty()) { - return false; - } - - if (isValidType() && has_control_) { - valid_ = true; - } - return valid_; -} - -bool Key::setControl(const KeyControlBlock& control) { - valid_ = false; - if (!control.valid()) { - return false; - } - - control_ = control; - has_control_ = true; - - if (isValidType() && !value_.empty()) { - valid_ = true; - } - return valid_; -} - -bool Key::UpdateDuration(const KeyControlBlock& control) { - valid_ = false; - if (!control.valid() || !has_control_) { - LOGE("UpdateDuration: control block not valid."); - return false; - } +Key::Key(const std::vector& key_string, const KeyControlBlock& control) + : value_(key_string), control_(control) {} +void Key::UpdateDuration(const KeyControlBlock& control) { control_.set_duration(control.duration()); - - if (isValidType() && !value_.empty()) { - valid_ = true; - } else { - LOGE("UpdateDuration: value or type bad."); - } - return valid_; } }; // namespace wvoec_eng diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_key_mock.h b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_key_mock.h index 70aefa07..cc5dcc60 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_key_mock.h +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_key_mock.h @@ -15,17 +15,6 @@ namespace wvoec_mock { -enum KeyType { - KEYTYPE_UNKNOWN, - KEYTYPE_PREPROV, - KEYTYPE_ROOT, - KEYTYPE_DEVICE, - KEYTYPE_CONTENT, - KEYTYPE_CONTENT_AUDIO, - KEYTYPE_CONTENT_VIDEO, - KEYTYPE_MAX -}; - const uint32_t kControlObserveDataPath = (1<<31); const uint32_t kControlObserveHDCP = (1<<30); const uint32_t kControlObserveCGMS = (1<<29); @@ -48,11 +37,9 @@ const uint32_t kControlCGMSCopyNever = (0x03); class KeyControlBlock { public: - KeyControlBlock() : valid_(false) {} - KeyControlBlock(bool refresh) : valid_(false), refresh_(refresh) {} + KeyControlBlock(const std::vector& key_control_string); ~KeyControlBlock() {} - bool SetFromString(const std::vector& key_control_string); bool Validate(); void Invalidate() { valid_ = false; } @@ -68,57 +55,25 @@ class KeyControlBlock { uint32_t ExtractField(const std::vector& str, int idx); bool valid_; - bool refresh_; uint32_t verification_; uint32_t duration_; uint32_t nonce_; uint32_t control_bits_; }; -// AES-128 crypto key +// AES-128 crypto key, or HMAC signing key. class Key { public: - Key() : valid_(false), type_(KEYTYPE_UNKNOWN), has_control_(false) {} - Key(const Key& key) : valid_(key.valid_), type_(key.type_), - value_(key.value_), - has_control_(key.has_control_), - control_(key.control_) {} - Key(KeyType type, const std::vector& key_string, - const KeyControlBlock& control); + Key(const Key& key) : value_(key.value_), control_(key.control_) {} + Key(const std::vector& key_string, const KeyControlBlock& control); virtual ~Key() {}; - - // Key is valid iff setValue(), setType(), and setControl() have been called - bool setValue(const char* key_string, size_t key_string_length); - bool setType(KeyType ktype); - bool setControl(const KeyControlBlock& control); - bool UpdateDuration(const KeyControlBlock& control); - - KeyType keyType() { return type_; } + void UpdateDuration(const KeyControlBlock& control); const std::vector& value() const { return value_; } const KeyControlBlock& control() const { return control_; } - bool isDeviceKey() { return (KEYTYPE_DEVICE == type_); } - bool isRootKey() { return (KEYTYPE_ROOT == type_); } - bool isPreprovKey() { return (KEYTYPE_PREPROV == type_); } - bool isContentKey() { - bool ctypes = (KEYTYPE_CONTENT == type_) || - (KEYTYPE_CONTENT_AUDIO == type_) || - (KEYTYPE_CONTENT_VIDEO == type_); - return ctypes; - } - bool isValidType() { - return ((KEYTYPE_UNKNOWN < type_) && (KEYTYPE_MAX > type_)); - } - bool isValid() { return valid_; } - - void clear() { value_.clear(); valid_ = false; } - private: - bool valid_; - KeyType type_; std::vector value_; - bool has_control_; KeyControlBlock control_; }; diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_keybox_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_keybox_mock.cpp index 25327583..55e5afc5 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_keybox_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_keybox_mock.cpp @@ -74,7 +74,7 @@ KeyboxError WvKeybox::Validate() { WidevineKeybox keybox; memset(&keybox, 0, sizeof(keybox)); memcpy(keybox.device_id_, &device_id_[0], device_id_.size()); - memcpy(keybox.device_key_, &device_key_.value()[0], sizeof(keybox.device_key_)); + memcpy(keybox.device_key_, &device_key_[0], sizeof(keybox.device_key_)); memcpy(keybox.data_, key_data_, sizeof(keybox.data_)); memcpy(keybox.magic_, magic_, sizeof(keybox.magic_)); @@ -99,9 +99,8 @@ bool WvKeybox::InstallKeybox(const uint8_t* buffer, size_t keyBoxLength) { = strnlen(reinterpret_cast(keybox->device_id_), 32); device_id_.assign(keybox->device_id_, keybox->device_id_ + device_id_length); - device_key_.setValue(reinterpret_cast(keybox->device_key_), - sizeof(keybox->device_key_)); - device_key_.setType(KEYTYPE_DEVICE); + device_key_.assign(keybox->device_key_, + keybox->device_key_ + sizeof(keybox->device_key_)); memcpy(key_data_, keybox->data_, sizeof(keybox->data_)); memcpy(magic_, keybox->magic_, sizeof(keybox->magic_)); memcpy(crc_, keybox->crc_, sizeof(keybox->crc_)); diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_keybox_mock.h b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_keybox_mock.h index b6ea72a4..060d4ba1 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_keybox_mock.h +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_keybox_mock.h @@ -29,7 +29,7 @@ class WvKeybox { KeyboxError Validate(); const std::vector& device_id() { return device_id_; } - Key& device_key() { return device_key_; } + std::vector& device_key() { return device_key_; } const WvKeyboxKeyData& key_data() { return key_data_; } size_t key_data_length() { return KEY_DATA_LENGTH; } bool InstallKeybox(const uint8_t* keybox, size_t keyBoxLength); @@ -40,7 +40,7 @@ class WvKeybox { bool valid_; std::vector device_id_; - Key device_key_; + std::vector device_key_; WvKeyboxKeyData key_data_; uint8_t magic_[4]; uint8_t crc_[4]; diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp index 1cc947d7..fbab94c8 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp @@ -199,7 +199,7 @@ OEMCryptoResult OEMCrypto_GenerateDerivedKeys(OEMCrypto_SESSION session, enc_key_context + enc_key_context_length); // Generate mac and encryption keys for current session context - if (!session_ctx->DeriveKeys(crypto_engine->keybox().device_key().value(), + if (!session_ctx->DeriveKeys(crypto_engine->keybox().device_key(), mac_ctx_str, enc_ctx_str)) { return OEMCrypto_ERROR_UNKNOWN_FAILURE; } @@ -289,6 +289,7 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session, dump_hex("signature", signature, signature_length); dump_hex("enc_mac_key_iv", enc_mac_key_iv, wvcdm::KEY_IV_SIZE); dump_hex("enc_mac_keys", enc_mac_keys, 2*wvcdm::MAC_KEY_SIZE); + dump_hex("pst", pst, pst_length); for (size_t i = 0; i < num_keys; i++) { printf("key_array[%zu].key_id_length=%zu;\n", i, key_array[i].key_id_length); dump_array_part("key_array", i, "key_id", @@ -347,60 +348,9 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session, } } - // Validate message signature - if (!session_ctx->ValidateMessage(message, message_length, signature, signature_length)) { - return OEMCrypto_ERROR_SIGNATURE_FAILURE; - } - - session_ctx->StartTimer(); - - // Decrypt and install keys in key object - // Each key will have a key control block. They will all have the same nonce. - bool status = true; - std::vector key_id; - std::vector enc_key_data; - std::vector key_data_iv; - std::vector key_control; - std::vector key_control_iv; - for (unsigned int i = 0; i < num_keys; i++) { - key_id.assign(key_array[i].key_id, - key_array[i].key_id + key_array[i].key_id_length); - enc_key_data.assign(key_array[i].key_data, - key_array[i].key_data + key_array[i].key_data_length); - key_data_iv.assign(key_array[i].key_data_iv, - key_array[i].key_data_iv + wvcdm::KEY_IV_SIZE); - if (key_array[i].key_control == NULL) { - status = false; - break; - } - key_control.assign(key_array[i].key_control, - key_array[i].key_control + wvcdm::KEY_CONTROL_SIZE); - key_control_iv.assign(key_array[i].key_control_iv, - key_array[i].key_control_iv + wvcdm::KEY_IV_SIZE); - - if (!session_ctx->InstallKey(key_id, enc_key_data, key_data_iv, key_control, - key_control_iv)) { - status = false; - break; - } - } - - session_ctx->FlushNonces(); - if (!status) return OEMCrypto_ERROR_UNKNOWN_FAILURE; - - // enc_mac_key can be NULL if license renewal is not supported - if (enc_mac_keys == NULL) return OEMCrypto_SUCCESS; - - // V2.1 license protocol: update mac keys after processing license response - const std::vector enc_mac_keys_str = std::vector( - enc_mac_keys, enc_mac_keys + 2*wvcdm::MAC_KEY_SIZE); - const std::vector enc_mac_key_iv_str = std::vector( - enc_mac_key_iv, enc_mac_key_iv + wvcdm::KEY_IV_SIZE); - - if (!session_ctx->UpdateMacKeys(enc_mac_keys_str, enc_mac_key_iv_str)) { - return OEMCrypto_ERROR_UNKNOWN_FAILURE; - } - return OEMCrypto_SUCCESS; + return session_ctx->LoadKeys( + session, message, message_length, signature, signature_length, + enc_mac_key_iv, enc_mac_keys, num_keys, key_array, pst, pst_length); } extern "C" @@ -582,9 +532,8 @@ OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session, return OEMCrypto_ERROR_INVALID_CONTEXT; } - return crypto_engine->DecryptCTR(session_ctx, iv, block_offset, data_addr, - data_length, is_encrypted, destination, - buffer_type); + return session_ctx->DecryptCTR(iv, block_offset, data_addr, data_length, + is_encrypted, destination, buffer_type); } extern "C" @@ -800,8 +749,8 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session, wrapped->context + sizeof(wrapped->context)); // Generate mac and encryption keys for encrypting the signature. if (result == OEMCrypto_SUCCESS) { - if (!session_ctx->DeriveKeys(crypto_engine->keybox().device_key().value(), - context, context)) { + if (!session_ctx->DeriveKeys(crypto_engine->keybox().device_key(), context, + context)) { result = OEMCrypto_ERROR_UNKNOWN_FAILURE; } } @@ -820,7 +769,7 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session, if (result == OEMCrypto_SUCCESS) { unsigned int sig_length = sizeof(wrapped->signature); if (!HMAC(EVP_sha256(), &session_ctx->mac_key_server()[0], - SHA256_DIGEST_LENGTH, wrapped->context, + session_ctx->mac_key_server().size(), wrapped->context, buffer_size - sizeof(wrapped->signature), wrapped->signature, &sig_length)) { result = OEMCrypto_ERROR_UNKNOWN_FAILURE; @@ -865,8 +814,8 @@ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session, const std::vector context(wrapped->context, wrapped->context + sizeof(wrapped->context)); // Generate mac and encryption keys for encrypting the signature. - if (!session_ctx->DeriveKeys(crypto_engine->keybox().device_key().value(), - context, context)) { + if (!session_ctx->DeriveKeys(crypto_engine->keybox().device_key(), context, + context)) { return OEMCrypto_ERROR_UNKNOWN_FAILURE; } // Decrypt RSA key. @@ -1019,6 +968,10 @@ const char* OEMCrypto_SecurityLevel() { extern "C" OEMCryptoResult OEMCrypto_GetHDCPCapability(OEMCrypto_HDCP_Capability *current, OEMCrypto_HDCP_Capability *maximum) { + if (trace_all_calls) { + printf("-- OEMCryptoResult OEMCrypto_GetHDCPCapability(%p, %p)\n", + current, maximum); + } if (current == NULL) return OEMCrypto_ERROR_UNKNOWN_FAILURE; if (maximum == NULL) return OEMCrypto_ERROR_UNKNOWN_FAILURE; *current = crypto_engine->current_hdcp_capability(); @@ -1034,6 +987,12 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt(OEMCrypto_SESSION session, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer) { + if (trace_all_calls) { + printf("-- OEMCryptoResult OEMCrypto_Generic_Encrypt( algorithm=%d\n", + algorithm); + dump_hex("in_buffer", in_buffer, buffer_length); + dump_hex("iv", iv, wvcdm::KEY_IV_SIZE); + } if (NO_ERROR != crypto_engine->ValidateKeybox()) { LOGE("[OEMCrypto_Generic_Enrypt(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; @@ -1048,8 +1007,13 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt(OEMCrypto_SESSION session, LOGE("[OEMCrypto_Generic_Enrypt(): OEMCrypto_ERROR_INVALID_CONTEXT]"); return OEMCrypto_ERROR_INVALID_CONTEXT; } - return session_ctx->Generic_Encrypt(in_buffer, buffer_length, iv, algorithm, - out_buffer); + OEMCryptoResult sts = + session_ctx->Generic_Encrypt(in_buffer, buffer_length, iv, algorithm, + out_buffer); + if (trace_all_calls) { + dump_hex("out_buffer", out_buffer, buffer_length); + } + return sts; } extern "C" @@ -1059,6 +1023,12 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt(OEMCrypto_SESSION session, const uint8_t* iv, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer) { + if (trace_all_calls) { + printf("-- OEMCryptoResult OEMCrypto_Generic_Decrypt( algorithm=%d\n", + algorithm); + dump_hex("in_buffer", in_buffer, buffer_length); + dump_hex("iv", iv, wvcdm::KEY_IV_SIZE); + } if (NO_ERROR != crypto_engine->ValidateKeybox()) { LOGE("[OEMCrypto_Generic_Decrypt(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; @@ -1073,8 +1043,13 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt(OEMCrypto_SESSION session, LOGE("[OEMCrypto_Generic_Decrypt(): OEMCrypto_ERROR_INVALID_CONTEXT]"); return OEMCrypto_ERROR_INVALID_CONTEXT; } - return session_ctx->Generic_Decrypt(in_buffer, buffer_length, iv, algorithm, - out_buffer); + OEMCryptoResult sts = + session_ctx->Generic_Decrypt(in_buffer, buffer_length, iv, algorithm, + out_buffer); + if (trace_all_calls) { + dump_hex("out_buffer", out_buffer, buffer_length); + } + return sts; } extern "C" @@ -1084,6 +1059,11 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session, OEMCrypto_Algorithm algorithm, uint8_t* signature, size_t* signature_length) { + if (trace_all_calls) { + printf("-- OEMCryptoResult OEMCrypto_Generic_Sign( algorithm=%d\n", + algorithm); + dump_hex("in_buffer", in_buffer, buffer_length); + } if (NO_ERROR != crypto_engine->ValidateKeybox()) { LOGE("[OEMCrypto_Generic_Sign(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; @@ -1101,8 +1081,13 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session, LOGE("[OEMCrypto_Generic_Sign(): OEMCrypto_ERROR_INVALID_CONTEXT]"); return OEMCrypto_ERROR_INVALID_CONTEXT; } - return session_ctx->Generic_Sign(in_buffer, buffer_length, algorithm, - signature, signature_length); + OEMCryptoResult sts = + session_ctx->Generic_Sign(in_buffer, buffer_length, algorithm, + signature, signature_length); + if (trace_all_calls) { + dump_hex("signature", signature, *signature_length); + } + return sts; } extern "C" @@ -1112,6 +1097,12 @@ OEMCryptoResult OEMCrypto_Generic_Verify(OEMCrypto_SESSION session, OEMCrypto_Algorithm algorithm, const uint8_t* signature, size_t signature_length) { + if (trace_all_calls) { + printf("-- OEMCryptoResult OEMCrypto_Generic_Verify( algorithm=%d\n", + algorithm); + dump_hex("in_buffer", in_buffer, buffer_length); + dump_hex("signature", signature, signature_length); + } if (NO_ERROR != crypto_engine->ValidateKeybox()) { LOGE("[OEMCrypto_Generic_Verify(): ERROR_KEYBOX_INVALID]"); return OEMCrypto_ERROR_KEYBOX_INVALID; diff --git a/libwvdrmengine/oemcrypto/test/Android.mk b/libwvdrmengine/oemcrypto/test/Android.mk index be56d7e2..da379b22 100644 --- a/libwvdrmengine/oemcrypto/test/Android.mk +++ b/libwvdrmengine/oemcrypto/test/Android.mk @@ -20,6 +20,7 @@ LOCAL_C_INCLUDES += \ LOCAL_STATIC_LIBRARIES := \ libcdm \ + libcdm_utils \ libgtest \ libgtest_main \ libwvlevel3 \ diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index 289d86cd..02552ac9 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -19,21 +19,26 @@ #include #include #include +#include #include +#include #include #include #include "OEMCryptoCENC.h" #include "oemcrypto_key_mock.h" +#include "properties.h" #include "string_conversions.h" #include "wv_cdm_constants.h" #include "wv_keybox.h" using namespace std; +using ::testing::WithParamInterface; +using ::testing::Range; +using ::testing::Values; namespace { const size_t kNumKeys = 4; -const size_t kBufferMaxLength = 256; #if defined(TEST_SPEED_MULTIPLIER) // Can slow test time limits when // debugging is slowing everything. const int kSpeedMultiplier = TEST_SPEED_MULTIPLIER; @@ -53,7 +58,7 @@ typedef struct { uint32_t duration; uint32_t nonce; uint32_t control_bits; -} KeyControlBlock; +} KeyControlBlock; const size_t kTestKeyIdLength = 12; // pick a length. any length. typedef struct { @@ -68,7 +73,8 @@ typedef struct { struct MessageData { MessageKeyData keys[kNumKeys]; uint8_t mac_key_iv[wvcdm::KEY_IV_SIZE]; - uint8_t mac_keys[2*wvcdm::MAC_KEY_SIZE]; + uint8_t mac_keys[2 * wvcdm::MAC_KEY_SIZE]; + uint8_t pst[kTestKeyIdLength]; }; const size_t kMaxTestRSAKeyLength = 2000; // Rough estimate. @@ -872,16 +878,19 @@ static void dump_openssl_error() { class Session { public: - Session() : valid_(false), open_(false) {} + Session() + : open_(false), + mac_key_server_(wvcdm::MAC_KEY_SIZE), + mac_key_client_(wvcdm::MAC_KEY_SIZE), + enc_key_(wvcdm::KEY_SIZE), + public_rsa_(0) {} - Session(string sname) : valid_(true), open_(false), sname_(sname), - mac_key_server_(wvcdm::MAC_KEY_SIZE), - mac_key_client_(wvcdm::MAC_KEY_SIZE), - enc_key_(wvcdm::KEY_SIZE), public_rsa_(0) {} + ~Session() { + if (open_) close(); + if (public_rsa_) RSA_free(public_rsa_); + } - bool isValid() { return valid_; } bool isOpen() { return open_; } - bool successStatus() { return (OEMCrypto_SUCCESS == session_status_); } OEMCryptoResult getStatus() { return session_status_; } uint32_t get_nonce() { return nonce_; } @@ -891,7 +900,6 @@ class Session { } void open() { - EXPECT_TRUE(valid_); EXPECT_TRUE(!open_); session_status_ = OEMCrypto_OpenSession(&session_id_); if (OEMCrypto_SUCCESS == session_status_) { @@ -900,7 +908,6 @@ class Session { } void close() { - EXPECT_TRUE(valid_); session_status_ = OEMCrypto_CloseSession(session_id_); if (OEMCrypto_SUCCESS == session_status_) { open_ = false; @@ -936,7 +943,6 @@ class Session { "e899b3e464189a14a87202fb02574e70640bd22ef44b2d7e3912250a230a1408" "0112100915007caa9b5931b76a3a85f046523e10011a09393837363534333231" "180120002a0c31383836373837343035000000000080"); - } void GenerateDerivedKeys() { @@ -945,10 +951,9 @@ class Session { vector enc_context; FillDefaultContext(&mac_context, &enc_context); ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_GenerateDerivedKeys( - session_id(), - &mac_context[0], mac_context.size(), - &enc_context[0], enc_context.size())); + OEMCrypto_GenerateDerivedKeys(session_id(), &mac_context[0], + mac_context.size(), &enc_context[0], + enc_context.size())); mac_key_server_ = wvcdm::a2b_hex( "3CFD60254786AF350B353B4FBB700AB382558400356866BA16C256BCD8C502BF"); mac_key_client_ = wvcdm::a2b_hex( @@ -956,54 +961,203 @@ class Session { enc_key_ = wvcdm::a2b_hex("D0BFC35DA9E33436E81C4229E78CB9F4"); } - void LoadTestKeys(uint32_t duration, uint32_t control, uint32_t nonce) { - MessageData data; - FillSimpleMessage(&data, duration, control, nonce); - MessageData encrypted; - EncryptMessage(data, &encrypted); - std::vector signature; - ServerSignMessage(encrypted, &signature); - OEMCrypto_KeyObject key_array[kNumKeys]; - - const uint8_t* message_ptr = reinterpret_cast(&encrypted); - FillKeyArray(encrypted, key_array); - ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_LoadKeys(session_id(), message_ptr, sizeof(encrypted), - &signature[0], signature.size(), - encrypted.mac_key_iv, encrypted.mac_keys, - kNumKeys, key_array, NULL, 0)); - // Update new generated keys. - memcpy(&mac_key_server_[0], data.mac_keys, wvcdm::MAC_KEY_SIZE); - memcpy(&mac_key_client_[0], data.mac_keys+wvcdm::MAC_KEY_SIZE, - wvcdm::MAC_KEY_SIZE); + void LoadTestKeys(const std::string& pst = "", bool new_mac_keys = true) { + uint8_t* pst_ptr = NULL; + if (pst.length() > 0) { + pst_ptr = encrypted_license_.pst; + } + if (new_mac_keys) { + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_LoadKeys( + session_id(), message_ptr(), sizeof(MessageData), + &signature_[0], signature_.size(), + encrypted_license_.mac_key_iv, encrypted_license_.mac_keys, + kNumKeys, key_array_, pst_ptr, pst.length())); + // Update new generated keys. + memcpy(&mac_key_server_[0], license_.mac_keys, wvcdm::MAC_KEY_SIZE); + memcpy(&mac_key_client_[0], license_.mac_keys + wvcdm::MAC_KEY_SIZE, + wvcdm::MAC_KEY_SIZE); + } else { + ASSERT_EQ( + OEMCrypto_SUCCESS, + OEMCrypto_LoadKeys(session_id(), message_ptr(), sizeof(MessageData), + &signature_[0], signature_.size(), NULL, NULL, + kNumKeys, key_array_, pst_ptr, pst.length())); + } } - void RefreshTestKeys(const int key_count, uint32_t control_bits, uint32_t nonce, - bool expect_good) { - MessageData data; - - FillRefreshMessage(&data, key_count, control_bits, nonce); - - std::vector signature; - ServerSignMessage(data, &signature); + void RefreshTestKeys(const size_t key_count, uint32_t control_bits, + uint32_t nonce, bool expect_good) { + // Note: we store the message in encrypted_license_, but the refresh key + // message is not actually encrypted. It is, however, signed. + FillRefreshMessage(key_count, control_bits, nonce); + ServerSignMessage(encrypted_license_, &signature_); OEMCrypto_KeyRefreshObject key_array[key_count]; - - const uint8_t* message_ptr = reinterpret_cast(&data); - FillRefreshArray(data, key_array, key_count); - OEMCryptoResult sts = OEMCrypto_RefreshKeys(session_id(), message_ptr, sizeof(data), - &signature[0], signature.size(), - key_count, key_array); - if( expect_good ) { - ASSERT_EQ(OEMCrypto_SUCCESS,sts); + FillRefreshArray(key_array, key_count); + OEMCryptoResult sts = OEMCrypto_RefreshKeys( + session_id(), message_ptr(), sizeof(MessageData), &signature_[0], + signature_.size(), key_count, key_array); + if (expect_good) { + ASSERT_EQ(OEMCrypto_SUCCESS, sts); } else { - ASSERT_NE(OEMCrypto_SUCCESS,sts); + ASSERT_NE(OEMCrypto_SUCCESS, sts); } // TODO(fredgc): make sure duration is reset. - // Select the key (from FillSimpleMessage) - vector keyId = wvcdm::a2b_hex("000000000000000000000000"); - sts = OEMCrypto_SelectKey(session_id(), &keyId[0], keyId.size()); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); + TestDecryptCTR(); + sleep(kShortSleep); // Should still be valid key. + TestDecryptCTR(false); + sleep(kShortSleep + kLongSleep); // Should be after first expiration. + if (expect_good) { + TestDecryptCTR(false, OEMCrypto_SUCCESS); + } else { + TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE); + } + } + + void FillSimpleMessage(uint32_t duration, uint32_t control, uint32_t nonce, + const std::string& pst = "") { + OEMCrypto_GetRandom(license_.mac_key_iv, sizeof(license_.mac_key_iv)); + OEMCrypto_GetRandom(license_.mac_keys, sizeof(license_.mac_keys)); + for (unsigned int i = 0; i < kNumKeys; i++) { + memset(license_.keys[i].key_id, i, kTestKeyIdLength); + OEMCrypto_GetRandom(license_.keys[i].key_data, + sizeof(license_.keys[i].key_data)); + license_.keys[i].key_data_length = wvcdm::KEY_SIZE; + OEMCrypto_GetRandom(license_.keys[i].key_iv, + sizeof(license_.keys[i].key_iv)); + OEMCrypto_GetRandom(license_.keys[i].control_iv, + sizeof(license_.keys[i].control_iv)); + if (control & (wvoec_mock::kControlHDCPVersionMask | + wvoec_mock::kControlReplayMask)) { + memcpy(license_.keys[i].control.verification, "kc09", 4); + } else { + memcpy(license_.keys[i].control.verification, "kctl", 4); + } + license_.keys[i].control.duration = htonl(duration); + license_.keys[i].control.nonce = htonl(nonce); + license_.keys[i].control.control_bits = htonl(control); + } + memcpy(license_.pst, pst.c_str(), min(sizeof(license_.pst), pst.length())); + // For the canned decryption content, The first key is: + vector key = wvcdm::a2b_hex("39AD33E5719656069F9EDE9EBBA7A77D"); + memcpy(license_.keys[0].key_data, &key[0], key.size()); + } + + void FillRefreshMessage(size_t key_count, uint32_t control_bits, + uint32_t nonce) { + for (unsigned int i = 0; i < kNumKeys; i++) { + memset(encrypted_license_.keys[i].key_id, i, kTestKeyIdLength); + memcpy(encrypted_license_.keys[i].control.verification, "kctl", 4); + encrypted_license_.keys[i].control.duration = htonl(kLongDuration); + encrypted_license_.keys[i].control.nonce = htonl(nonce); + encrypted_license_.keys[i].control.control_bits = htonl(control_bits); + } + } + + void EncryptAndSign() { + encrypted_license_ = license_; + + uint8_t iv_buffer[16]; + memcpy(iv_buffer, &license_.mac_key_iv[0], wvcdm::KEY_IV_SIZE); + AES_KEY aes_key; + AES_set_encrypt_key(&enc_key_[0], 128, &aes_key); + AES_cbc_encrypt(&license_.mac_keys[0], &encrypted_license_.mac_keys[0], + 2 * wvcdm::MAC_KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT); + + for (unsigned int i = 0; i < kNumKeys; i++) { + memcpy(iv_buffer, &license_.keys[i].control_iv[0], wvcdm::KEY_IV_SIZE); + AES_set_encrypt_key(&license_.keys[i].key_data[0], 128, &aes_key); + AES_cbc_encrypt( + reinterpret_cast(&license_.keys[i].control), + reinterpret_cast(&encrypted_license_.keys[i].control), + wvcdm::KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT); + + memcpy(iv_buffer, &license_.keys[i].key_iv[0], wvcdm::KEY_IV_SIZE); + AES_set_encrypt_key(&enc_key_[0], 128, &aes_key); + AES_cbc_encrypt(&license_.keys[i].key_data[0], + &encrypted_license_.keys[i].key_data[0], + license_.keys[i].key_data_length, &aes_key, iv_buffer, + AES_ENCRYPT); + } + memcpy(encrypted_license_.pst, license_.pst, sizeof(license_.pst)); + ServerSignMessage(encrypted_license_, &signature_); + FillKeyArray(encrypted_license_, key_array_); + } + + void EncryptMessage(RSAPrivateKeyMessage* data, + RSAPrivateKeyMessage* encrypted) { + *encrypted = *data; + size_t padding = wvcdm::KEY_SIZE - (data->rsa_key_length % wvcdm::KEY_SIZE); + memset(data->rsa_key + data->rsa_key_length, static_cast(padding), + padding); + encrypted->rsa_key_length = data->rsa_key_length + padding; + uint8_t iv_buffer[16]; + memcpy(iv_buffer, &data->rsa_key_iv[0], wvcdm::KEY_IV_SIZE); + AES_KEY aes_key; + AES_set_encrypt_key(&enc_key_[0], 128, &aes_key); + AES_cbc_encrypt(&data->rsa_key[0], &encrypted->rsa_key[0], + encrypted->rsa_key_length, &aes_key, iv_buffer, + AES_ENCRYPT); + } + + template + void ServerSignMessage(const T& data, std::vector* signature) { + signature->resize(SHA256_DIGEST_LENGTH); + unsigned int md_len = SHA256_DIGEST_LENGTH; + HMAC(EVP_sha256(), &mac_key_server_[0], mac_key_server_.size(), + reinterpret_cast(&data), sizeof(data), + &(signature->front()), &md_len); + } + + void ClientSignMessage(const vector& data, + std::vector* signature) { + signature->resize(SHA256_DIGEST_LENGTH); + unsigned int md_len = SHA256_DIGEST_LENGTH; + HMAC(EVP_sha256(), &mac_key_client_[0], mac_key_client_.size(), + &(data.front()), data.size(), &(signature->front()), &md_len); + } + + void FillKeyArray(const MessageData& data, OEMCrypto_KeyObject* key_array) { + for (unsigned int i = 0; i < kNumKeys; i++) { + key_array[i].key_id = data.keys[i].key_id; + key_array[i].key_id_length = kTestKeyIdLength; + key_array[i].key_data_iv = data.keys[i].key_iv; + key_array[i].key_data = data.keys[i].key_data; + key_array[i].key_data_length = data.keys[i].key_data_length; + key_array[i].key_control_iv = data.keys[i].control_iv; + key_array[i].key_control = + reinterpret_cast(&data.keys[i].control); + } + } + + void FillRefreshArray(OEMCrypto_KeyRefreshObject* key_array, + size_t key_count) { + for (size_t i = 0; i < key_count; i++) { + if (key_count > 1) { + key_array[i].key_id = encrypted_license_.keys[i].key_id; + key_array[i].key_id_length = kTestKeyIdLength; + } else { + key_array[i].key_id = NULL; + key_array[i].key_id_length = 0; + } + // TODO(fredgc): Is this valid? Is key control encrypted on renewal? + // key_array[i].key_control_iv = encrypted_license_.keys[i].control_iv; + key_array[i].key_control_iv = NULL; + key_array[i].key_control = + reinterpret_cast(&encrypted_license_.keys[i].control); + } + } + + void TestDecryptCTR(bool select_key_first = true, + OEMCryptoResult expected_result = OEMCrypto_SUCCESS) { + OEMCryptoResult sts; + if (select_key_first) { + // Select the key (from FillSimpleMessage) + vector keyId = wvcdm::a2b_hex("000000000000000000000000"); + sts = OEMCrypto_SelectKey(session_id(), &keyId[0], keyId.size()); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + } // Set up our expected input and output vector encryptedData = wvcdm::a2b_hex( @@ -1015,8 +1169,8 @@ class Session { "cffc724790af635c959e2644e51ba7f23bae710eb55a1f2f4e060c3c1dd1387c" "74415dc880492dd1d5b9ecf3f01de48a44baeb4d3ea5cc4f8d561d0865afcabb" "fc14a9ab9647e6e31adabb72d792f0c9ba99dc3e9205657d28fc7771d64e6d4b"); - vector encryptionIv = wvcdm::a2b_hex( - "719dbcb253b2ec702bb8c1b1bc2f3bc6"); + vector encryptionIv = + wvcdm::a2b_hex("719dbcb253b2ec702bb8c1b1bc2f3bc6"); vector unencryptedData = wvcdm::a2b_hex( "19ef4361e16e6825b336e2012ad8ffc9ce176ab2256e1b98aa15b7877bd8c626" "fa40b2e88373457cbcf4f1b4b9793434a8ac03a708f85974cff01bddcbdd7a8e" @@ -1034,188 +1188,38 @@ class Session { destBuffer.buffer.clear.address = outputBuffer; destBuffer.buffer.clear.max_length = sizeof(outputBuffer); // Decrypt the data - sts = OEMCrypto_DecryptCTR(session_id(), &encryptedData[0], - encryptedData.size(), true, &encryptionIv[0], 0, - &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer, - unencryptedData.size())); - - sleep(kShortSleep); // Should still be valid key. - - memset(outputBuffer, 0, sizeof(outputBuffer)); - destBuffer.type = OEMCrypto_BufferType_Clear; - destBuffer.buffer.clear.address = outputBuffer; - destBuffer.buffer.clear.max_length = sizeof(outputBuffer); - - // Decrypt the data - sts = OEMCrypto_DecryptCTR(session_id(), &encryptedData[0], - encryptedData.size(), true, &encryptionIv[0], 0, - &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer, - unencryptedData.size())); - - sleep(kShortSleep + kLongSleep); // Should be after first expiration. - - memset(outputBuffer, 0, sizeof(outputBuffer)); - destBuffer.type = OEMCrypto_BufferType_Clear; - destBuffer.buffer.clear.address = outputBuffer; - destBuffer.buffer.clear.max_length = sizeof(outputBuffer); - - // Decrypt the data - sts = OEMCrypto_DecryptCTR(session_id(), &encryptedData[0], - encryptedData.size(), true, &encryptionIv[0], 0, - &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - if( expect_good) { + sts = OEMCrypto_DecryptCTR( + session_id(), &encryptedData[0], encryptedData.size(), true, + &encryptionIv[0], 0, &destBuffer, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); + // We only have a few errors that we test are reported. + if (expected_result == OEMCrypto_SUCCESS) { // No error. ASSERT_EQ(OEMCrypto_SUCCESS, sts); - ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer, - unencryptedData.size())); + ASSERT_EQ( + 0, memcmp(&unencryptedData[0], outputBuffer, unencryptedData.size())); + } else if (expected_result == OEMCrypto_ERROR_KEY_EXPIRED) { + // Report stale keys. + ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, sts); + ASSERT_NE( + 0, memcmp(&unencryptedData[0], outputBuffer, unencryptedData.size())); + } else if (expected_result == OEMCrypto_ERROR_INSUFFICIENT_HDCP) { + // Report HDCP errors. + ASSERT_EQ(OEMCrypto_ERROR_INSUFFICIENT_HDCP, sts); + ASSERT_NE( + 0, memcmp(&unencryptedData[0], outputBuffer, unencryptedData.size())); } else { + // OEM's can fine tune other error codes for debugging. ASSERT_NE(OEMCrypto_SUCCESS, sts); - ASSERT_NE(0, memcmp(&unencryptedData[0], outputBuffer, - unencryptedData.size())); - } - } - - void FillSimpleMessage(MessageData* data, uint32_t duration, uint32_t control, - uint32_t nonce) { - OEMCrypto_GetRandom(data->mac_key_iv, sizeof(data->mac_key_iv)); - OEMCrypto_GetRandom(data->mac_keys, sizeof(data->mac_keys)); - for (unsigned int i = 0; i < kNumKeys; i++) { - memset(data->keys[i].key_id, i, kTestKeyIdLength); - OEMCrypto_GetRandom(data->keys[i].key_data, - sizeof(data->keys[i].key_data)); - data->keys[i].key_data_length = wvcdm::KEY_SIZE; - OEMCrypto_GetRandom(data->keys[i].key_iv, sizeof(data->keys[i].key_iv)); - OEMCrypto_GetRandom(data->keys[i].control_iv, - sizeof(data->keys[i].control_iv)); - if (control & (wvoec_mock::kControlHDCPVersionMask - | wvoec_mock::kControlReplayMask)) { - memcpy(data->keys[i].control.verification, "kc09", 4); - } else { - memcpy(data->keys[i].control.verification, "kctl", 4); - } - data->keys[i].control.duration = htonl(duration); - data->keys[i].control.nonce = htonl(nonce); - data->keys[i].control.control_bits = htonl(control); - } - // For the canned decryption content, The first key is: - vector key = wvcdm::a2b_hex("39AD33E5719656069F9EDE9EBBA7A77D"); - memcpy(data->keys[0].key_data, &key[0], key.size()); - } - - void FillRefreshMessage(MessageData* data, int key_count, - uint32_t control_bits, uint32_t nonce) { - for (unsigned int i = 0; i < kNumKeys; i++) { - memset(data->keys[i].key_id, i, kTestKeyIdLength); - memcpy(data->keys[i].control.verification, "kctl", 4); - data->keys[i].control.duration = htonl(kLongDuration); - data->keys[i].control.nonce = htonl(nonce); - data->keys[i].control.control_bits = htonl(control_bits); - } - } - - void EncryptMessage(const MessageData& data, - MessageData* encrypted) { - *encrypted = data; - - uint8_t iv_buffer[16]; - memcpy(iv_buffer, &data.mac_key_iv[0], wvcdm::KEY_IV_SIZE); - AES_KEY aes_key; - AES_set_encrypt_key(&enc_key_[0], 128, &aes_key); - AES_cbc_encrypt(&data.mac_keys[0], &encrypted->mac_keys[0], - 2*wvcdm::MAC_KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT); - - for (unsigned int i = 0; i < kNumKeys; i++) { - memcpy(iv_buffer, &data.keys[i].control_iv[0], wvcdm::KEY_IV_SIZE); - AES_set_encrypt_key(&data.keys[i].key_data[0], 128, &aes_key); - AES_cbc_encrypt(reinterpret_cast(&data.keys[i].control), - reinterpret_cast(&encrypted->keys[i].control), - wvcdm::KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT); - - memcpy(iv_buffer, &data.keys[i].key_iv[0], wvcdm::KEY_IV_SIZE); - AES_set_encrypt_key(&enc_key_[0], 128, &aes_key); - AES_cbc_encrypt(&data.keys[i].key_data[0], - &encrypted->keys[i].key_data[0], data.keys[i].key_data_length, - &aes_key, iv_buffer, AES_ENCRYPT); - } - } - - void EncryptMessage(RSAPrivateKeyMessage* data, - RSAPrivateKeyMessage* encrypted) { - *encrypted = *data; - size_t padding = wvcdm::KEY_SIZE-(data->rsa_key_length % wvcdm::KEY_SIZE); - memset(data->rsa_key + data->rsa_key_length, - static_cast(padding), padding); - encrypted->rsa_key_length = data->rsa_key_length + padding; - uint8_t iv_buffer[16]; - memcpy(iv_buffer, &data->rsa_key_iv[0], wvcdm::KEY_IV_SIZE); - AES_KEY aes_key; - AES_set_encrypt_key(&enc_key_[0], 128, &aes_key); - AES_cbc_encrypt(&data->rsa_key[0], &encrypted->rsa_key[0], - encrypted->rsa_key_length, &aes_key, iv_buffer, - AES_ENCRYPT); - } - - template - void ServerSignMessage(const T& data, std::vector* signature) { - signature->resize(SHA256_DIGEST_LENGTH); - unsigned int md_len = SHA256_DIGEST_LENGTH; - HMAC(EVP_sha256(), &mac_key_server_[0], SHA256_DIGEST_LENGTH, - reinterpret_cast(&data), sizeof(data), - &(signature->front()), &md_len); - } - - void ClientSignMessage(const vector &data, - std::vector* signature) { - signature->resize(SHA256_DIGEST_LENGTH); - unsigned int md_len = SHA256_DIGEST_LENGTH; - HMAC(EVP_sha256(), &mac_key_client_[0], SHA256_DIGEST_LENGTH, - &(data.front()), data.size(), &(signature->front()), &md_len); - } - - void FillKeyArray(const MessageData& data, - OEMCrypto_KeyObject* key_array) { - for (unsigned int i = 0; i < kNumKeys; i++) { - key_array[i].key_id = data.keys[i].key_id; - key_array[i].key_id_length = kTestKeyIdLength; - key_array[i].key_data_iv = data.keys[i].key_iv; - key_array[i].key_data = data.keys[i].key_data; - key_array[i].key_data_length = data.keys[i].key_data_length; - key_array[i].key_control_iv = data.keys[i].control_iv; - key_array[i].key_control - = reinterpret_cast(&data.keys[i].control); - } - } - - void FillRefreshArray(const MessageData& data, - OEMCrypto_KeyRefreshObject* key_array, const int key_count) { - for (int i = 0; i < key_count; i++) { - if( key_count > 1 ) { - key_array[i].key_id = data.keys[i].key_id; - key_array[i].key_id_length = kTestKeyIdLength; - } else { - key_array[i].key_id = NULL; - key_array[i].key_id_length = 0; - } - // TODO(fredgc): Is this valid? Is key control encrypted on renewal? - // key_array[i].key_control_iv = data.keys[i].control_iv; - key_array[i].key_control_iv = NULL; - key_array[i].key_control - = reinterpret_cast(&data.keys[i].control); + ASSERT_NE( + 0, memcmp(&unencryptedData[0], outputBuffer, unencryptedData.size())); } } void MakeRSACertificate(struct RSAPrivateKeyMessage* encrypted, std::vector* signature, uint32_t allowed_schemes, - const uint8_t *rsa_key = NULL, + const uint8_t* rsa_key = NULL, size_t rsa_key_length = 0) { - if (rsa_key == NULL) { rsa_key = kTestRSAPKCS8PrivateKeyInfo2_2048; rsa_key_length = sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048); @@ -1232,16 +1236,14 @@ class Session { // Generate signature size_t gen_signature_length = 0; - sts = OEMCrypto_GenerateSignature(session_id(), &context[0], - context.size(), NULL, - &gen_signature_length); + sts = OEMCrypto_GenerateSignature(session_id(), &context[0], context.size(), + NULL, &gen_signature_length); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); ASSERT_EQ(static_cast(32), gen_signature_length); static const uint32_t SignatureBufferMaxLength = 256; uint8_t gen_signature[SignatureBufferMaxLength]; - sts = OEMCrypto_GenerateSignature(session_id(), &context[0], - context.size(), gen_signature, - &gen_signature_length); + sts = OEMCrypto_GenerateSignature(session_id(), &context[0], context.size(), + gen_signature, &gen_signature_length); ASSERT_EQ(OEMCrypto_SUCCESS, sts); std::vector expected_signature; ClientSignMessage(context, &expected_signature); @@ -1276,25 +1278,20 @@ class Session { vector* wrapped_key, bool force) { size_t wrapped_key_length = 0; const uint8_t* message_ptr = reinterpret_cast(&encrypted); + ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, - OEMCrypto_RewrapDeviceRSAKey(session_id(), message_ptr, - sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, - encrypted.rsa_key, - encrypted.rsa_key_length, - encrypted.rsa_key_iv, NULL, - &wrapped_key_length)); + OEMCrypto_RewrapDeviceRSAKey( + session_id(), message_ptr, sizeof(encrypted), &signature[0], + signature.size(), &encrypted.nonce, encrypted.rsa_key, + encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, + &wrapped_key_length)); wrapped_key->clear(); wrapped_key->resize(wrapped_key_length); - OEMCryptoResult sts = - OEMCrypto_RewrapDeviceRSAKey(session_id(), message_ptr, - sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, - encrypted.rsa_key, - encrypted.rsa_key_length, - encrypted.rsa_key_iv, - &(wrapped_key->front()), - &wrapped_key_length); + OEMCryptoResult sts = OEMCrypto_RewrapDeviceRSAKey( + session_id(), message_ptr, sizeof(encrypted), &signature[0], + signature.size(), &encrypted.nonce, encrypted.rsa_key, + encrypted.rsa_key_length, encrypted.rsa_key_iv, &(wrapped_key->front()), + &wrapped_key_length); if (force) { ASSERT_EQ(OEMCrypto_SUCCESS, sts); } @@ -1303,20 +1300,21 @@ class Session { } } - void PreparePublicKey(const uint8_t *rsa_key = NULL, + void PreparePublicKey(const uint8_t* rsa_key = NULL, size_t rsa_key_length = 0) { if (rsa_key == NULL) { rsa_key = kTestRSAPKCS8PrivateKeyInfo2_2048; rsa_key_length = sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048); } - uint8_t *p = const_cast(rsa_key); - BIO *bio = BIO_new_mem_buf(p, rsa_key_length); + uint8_t* p = const_cast(rsa_key); + BIO* bio = BIO_new_mem_buf(p, rsa_key_length); ASSERT_TRUE(NULL != bio); - PKCS8_PRIV_KEY_INFO *pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, NULL); + PKCS8_PRIV_KEY_INFO* pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, NULL); ASSERT_TRUE(NULL != pkcs8_pki); - EVP_PKEY *evp = NULL; + EVP_PKEY* evp = NULL; evp = EVP_PKCS82PKEY(pkcs8_pki); ASSERT_TRUE(NULL != evp); + if (public_rsa_) RSA_free(public_rsa_); public_rsa_ = EVP_PKEY_get1_RSA(evp); EVP_PKEY_free(evp); PKCS8_PRIV_KEY_INFO_free(pkcs8_pki); @@ -1341,16 +1339,14 @@ class Session { } } - void VerifyRSASignature(const uint8_t* message, - size_t message_length, - const uint8_t* signature, - size_t signature_length, + void VerifyRSASignature(const uint8_t* message, size_t message_length, + const uint8_t* signature, size_t signature_length, RSA_Padding_Scheme padding_scheme) { - EXPECT_TRUE(NULL !=public_rsa_) + EXPECT_TRUE(NULL != public_rsa_) << "No public RSA key loaded in test code.\n"; EXPECT_EQ(static_cast(RSA_size(public_rsa_)), signature_length) - << "Signature size is wrong. " << signature_length - << ", should be " << RSA_size(public_rsa_) << "\n"; + << "Signature size is wrong. " << signature_length << ", should be " + << RSA_size(public_rsa_) << "\n"; if (padding_scheme == kSign_RSASSA_PSS) { // Hash the message using SHA1. @@ -1393,13 +1389,12 @@ class Session { cout << "No public RSA key loaded in test code.\n"; return false; } - vector session_key = wvcdm::a2b_hex( - "6fa479c731d2770b6a61a5d1420bb9d1"); + vector session_key = + wvcdm::a2b_hex("6fa479c731d2770b6a61a5d1420bb9d1"); enc_session_key->assign(RSA_size(public_rsa_), 0); - int status = RSA_public_encrypt(session_key.size(), - &session_key[0], - &(enc_session_key->front()), - public_rsa_, RSA_PKCS1_OAEP_PADDING); + int status = RSA_public_encrypt(session_key.size(), &session_key[0], + &(enc_session_key->front()), public_rsa_, + RSA_PKCS1_OAEP_PADDING); if (status != RSA_size(public_rsa_)) { cout << "GenerateRSASessionKey error encrypting session key. "; dump_openssl_error(); @@ -1422,8 +1417,8 @@ class Session { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_DeriveKeysFromSessionKey( session_id(), &enc_session_key[0], enc_session_key.size(), - &mac_context[0], mac_context.size(), - &enc_context[0], enc_context.size())); + &mac_context[0], mac_context.size(), &enc_context[0], + enc_context.size())); mac_key_server_ = wvcdm::a2b_hex( "1E451E59CB663DA1646194DD28880788ED8ED2EFF913CBD6A0D535D1D5A90381"); @@ -1443,59 +1438,53 @@ class Session { ASSERT_EQ(OEMCrypto_ERROR_INVALID_RSA_KEY, OEMCrypto_DeriveKeysFromSessionKey( session_id(), &enc_session_key[0], enc_session_key.size(), - &mac_context[0], mac_context.size(), - &enc_context[0], enc_context.size())); + &mac_context[0], mac_context.size(), &enc_context[0], + enc_context.size())); } + MessageData& license() { return license_; } + MessageData& encrypted_license() { return encrypted_license_; } + const uint8_t* message_ptr() { + return reinterpret_cast(&encrypted_license_); + } + OEMCrypto_KeyObject* key_array() { return key_array_; } + std::vector& signature() { return signature_; } + private: - bool valid_; bool open_; - string sname_; OEMCrypto_SESSION session_id_; - OEMCryptoResult session_status_; + OEMCryptoResult session_status_; vector mac_key_server_; vector mac_key_client_; vector enc_key_; uint32_t nonce_; RSA* public_rsa_; + MessageData license_; + MessageData encrypted_license_; + OEMCrypto_KeyObject key_array_[kNumKeys]; + std::vector signature_; }; class OEMCryptoClientTest : public ::testing::Test { protected: + OEMCryptoClientTest() {} - OEMCryptoClientTest() : alive_(false) {} - - bool init() { - OEMCryptoResult result; - if (!alive_) { - result = OEMCrypto_Initialize(); - alive_ = (OEMCrypto_SUCCESS == result); - } - return alive_; + void SetUp() { + ::testing::Test::SetUp(); + wvcdm::Properties::Init(); + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize()); } - bool terminate() { - OEMCryptoResult result; - result = OEMCrypto_Terminate(); - if (OEMCrypto_SUCCESS == result) { - alive_ = false; - } - return !alive_; - } - - void testSetUp() { // TODO(fredgc): Wha... - // All these tests should be using Setup() and Teardown() so that you - // don't need to call them manually... - // https://code.google.com/p/googletest/wiki/Primer#Test_Fixtures: - // _Using_the_Same_Data_Configuration_for_Multiple_Te - init(); + void TearDown() { + OEMCrypto_Terminate(); + ::testing::Test::TearDown(); } void CreateWrappedRSAKey(vector* wrapped_key, uint32_t allowed_schemes, bool force, - const uint8_t *rsa_key = NULL, + const uint8_t* rsa_key = NULL, size_t rsa_key_length = 0) { - Session& s = createSession("RSA_Session"); + Session s; s.open(); s.GenerateDerivedKeys(); struct RSAPrivateKeyMessage encrypted; @@ -1503,65 +1492,19 @@ class OEMCryptoClientTest : public ::testing::Test { s.MakeRSACertificate(&encrypted, &signature, allowed_schemes, rsa_key, rsa_key_length); s.RewrapRSAKey(encrypted, signature, wrapped_key, force); - s.close(); - } - - void testTearDown() { - destroySessions(); - terminate(); - } - - void validateKeybox() { - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid()); - } - - static Session badSession; - - Session& findSession(string sname) { - map::iterator it = _sessions.find(sname); - if (it != _sessions.end()) { - return it->second; - } - return badSession; - } - - Session& createSession(string sname) { - Session temp(sname); - _sessions.insert(pair(sname, temp)); - return findSession(sname); - } - - bool destroySession(string sname) { - Session& temp = findSession(sname); - if (!temp.isValid()) { - return false; - } - _sessions.erase(sname); - return true; - } - - bool destroySessions() { - _sessions.clear(); - return true; } const uint8_t* find(const vector& message, const vector& substring) { - vector::const_iterator pos = search(message.begin(), message.end(), - substring.begin(), substring.end()); + vector::const_iterator pos = search( + message.begin(), message.end(), substring.begin(), substring.end()); if (pos == message.end()) { return NULL; } return &(*pos); } - - private: - bool alive_; - map _sessions; }; -Session OEMCryptoClientTest::badSession; - /////////////////////////////////////////////////// // Keybox Tests /////////////////////////////////////////////////// @@ -1569,23 +1512,17 @@ Session OEMCryptoClientTest::badSession; // These two tests are first, becuase it might give an idea why other // tests are failing when the device has the wrong keybox installed. TEST_F(OEMCryptoClientTest, VersionNumber) { - testSetUp(); - const char* level = OEMCrypto_SecurityLevel(); - ASSERT_NE((char *)NULL, level); + ASSERT_NE((char*)NULL, level); ASSERT_EQ('L', level[0]); - cout << " OEMCrypto Security Level is "<< level << endl; + cout << " OEMCrypto Security Level is " << level << endl; uint32_t version = OEMCrypto_APIVersion(); cout << " OEMCrypto API version is " << version << endl; ASSERT_LE(8, version); ASSERT_GE(9, version); - - testTearDown(); } TEST_F(OEMCryptoClientTest, NormalGetKeyData) { - testSetUp(); - OEMCryptoResult sts; uint8_t key_data[256]; size_t key_data_len = sizeof(key_data); @@ -1593,21 +1530,20 @@ TEST_F(OEMCryptoClientTest, NormalGetKeyData) { uint32_t* data = reinterpret_cast(key_data); printf(" NormalGetKeyData: system_id = %d = 0x%04X, version=%d\n", - htonl(data[1]), htonl(data[1]), htonl(data[0])); + htonl(data[1]), htonl(data[1]), htonl(data[0])); ASSERT_EQ(OEMCrypto_SUCCESS, sts); uint32_t system_id = htonl(data[1]); if (system_id == 0x1019) { - cout << "======================================================================\n" - << "If you run this as \"oemcrypto_test --gtest_also_run_disabled_tests\",\n" - << "then a test keybox will be installed, and all tests will be run. \n" - << "======================================================================\n"; + cout << "========================================================================\n" + << "= If you run this as \"oemcrypto_test --gtest_also_run_disabled_tests\", =\n" + << "= then a test keybox will be installed, and all tests will be run. =\n" + << "========================================================================\n"; } - testTearDown(); } const char* HDCPCapabilityAsString(OEMCrypto_HDCP_Capability value) { - switch(value) { + switch (value) { case 0x0: return "No HDCP supported, no secure data path"; case 0x1: @@ -1626,8 +1562,6 @@ const char* HDCPCapabilityAsString(OEMCrypto_HDCP_Capability value) { } TEST_F(OEMCryptoClientTest, CheckHDCPCapability) { - testSetUp(); - OEMCryptoResult sts; OEMCrypto_HDCP_Capability current, maximum; sts = OEMCrypto_GetHDCPCapability(¤t, &maximum); @@ -1636,22 +1570,13 @@ TEST_F(OEMCryptoClientTest, CheckHDCPCapability) { HDCPCapabilityAsString(current)); printf(" Maximum HDCP Capability: 0x%02x = %s.\n", maximum, HDCPCapabilityAsString(maximum)); - testTearDown(); } TEST_F(OEMCryptoClientTest, KeyboxValid) { - bool success; - success = init(); - EXPECT_TRUE(success); - validateKeybox(); - ASSERT_TRUE(success); - success = terminate(); - ASSERT_TRUE(success); + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid()); } TEST_F(OEMCryptoClientTest, NormalGetDeviceId) { - testSetUp(); - OEMCryptoResult sts; uint8_t dev_id[128] = {0}; size_t dev_id_len = 128; @@ -1659,13 +1584,9 @@ TEST_F(OEMCryptoClientTest, NormalGetDeviceId) { cout << " NormalGetDeviceId: dev_id = " << dev_id << " len = " << dev_id_len << endl; ASSERT_EQ(OEMCrypto_SUCCESS, sts); - - testTearDown(); } TEST_F(OEMCryptoClientTest, GetDeviceIdShortBuffer) { - testSetUp(); - OEMCryptoResult sts; uint8_t dev_id[128]; uint32_t req_len = 0; @@ -1684,7 +1605,10 @@ TEST_F(OEMCryptoClientTest, GetDeviceIdShortBuffer) { ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); // On short buffer error, function should return minimum buffer length ASSERT_TRUE(dev_id_len > req_len); - testTearDown(); +} + +TEST_F(OEMCryptoClientTest, DefaultKeybox) { + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid()); } /////////////////////////////////////////////////// @@ -1692,11 +1616,9 @@ TEST_F(OEMCryptoClientTest, GetDeviceIdShortBuffer) { /////////////////////////////////////////////////// TEST_F(OEMCryptoClientTest, NormalInitTermination) { - bool success; - success = init(); - EXPECT_TRUE(success); - success = terminate(); - ASSERT_TRUE(success); + // Should be able to terminate OEMCrypto, and then restart it. + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Terminate()); + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize()); } /////////////////////////////////////////////////// @@ -1704,138 +1626,59 @@ TEST_F(OEMCryptoClientTest, NormalInitTermination) { /////////////////////////////////////////////////// TEST_F(OEMCryptoClientTest, NormalSessionOpenClose) { - Session& s = createSession("ONE"); - testSetUp(); - + Session s; s.open(); - ASSERT_TRUE(s.successStatus()); + ASSERT_EQ(OEMCrypto_SUCCESS, s.getStatus()); ASSERT_TRUE(s.isOpen()); - s.close(); - ASSERT_TRUE(s.successStatus()); + ASSERT_EQ(OEMCrypto_SUCCESS, s.getStatus()); ASSERT_FALSE(s.isOpen()); - - testTearDown(); } TEST_F(OEMCryptoClientTest, TwoSessionsOpenClose) { - Session& s1 = createSession("ONE"); - Session& s2 = createSession("TWO"); - testSetUp(); + Session s1; + Session s2; s1.open(); - ASSERT_TRUE(s1.successStatus()); + ASSERT_EQ(OEMCrypto_SUCCESS, s1.getStatus()); ASSERT_TRUE(s1.isOpen()); s2.open(); - ASSERT_TRUE(s2.successStatus()); + ASSERT_EQ(OEMCrypto_SUCCESS, s2.getStatus()); ASSERT_TRUE(s2.isOpen()); s1.close(); - ASSERT_TRUE(s1.successStatus()); + ASSERT_EQ(OEMCrypto_SUCCESS, s1.getStatus()); ASSERT_FALSE(s1.isOpen()); s2.close(); - ASSERT_TRUE(s2.successStatus()); + ASSERT_EQ(OEMCrypto_SUCCESS, s2.getStatus()); ASSERT_FALSE(s2.isOpen()); - - testTearDown(); } TEST_F(OEMCryptoClientTest, EightSessionsOpenClose) { - Session& s1 = createSession("ONE"); - Session& s2 = createSession("TWO"); - Session& s3 = createSession("THREE"); - Session& s4 = createSession("FOUR"); - Session& s5 = createSession("FIVE"); - Session& s6 = createSession("SIX"); - Session& s7 = createSession("SEVEN"); - Session& s8 = createSession("EIGHT"); - testSetUp(); - - s1.open(); - ASSERT_TRUE(s1.successStatus()); - ASSERT_TRUE(s1.isOpen()); - - s2.open(); - ASSERT_TRUE(s2.successStatus()); - ASSERT_TRUE(s2.isOpen()); - - s3.open(); - ASSERT_TRUE(s3.successStatus()); - ASSERT_TRUE(s3.isOpen()); - - s4.open(); - ASSERT_TRUE(s4.successStatus()); - ASSERT_TRUE(s4.isOpen()); - - s5.open(); - ASSERT_TRUE(s5.successStatus()); - ASSERT_TRUE(s5.isOpen()); - - s6.open(); - ASSERT_TRUE(s6.successStatus()); - ASSERT_TRUE(s6.isOpen()); - - s7.open(); - ASSERT_TRUE(s7.successStatus()); - ASSERT_TRUE(s7.isOpen()); - - s8.open(); - ASSERT_TRUE(s8.successStatus()); - ASSERT_TRUE(s8.isOpen()); - - s1.close(); - ASSERT_TRUE(s1.successStatus()); - ASSERT_FALSE(s1.isOpen()); - - s8.close(); - ASSERT_TRUE(s8.successStatus()); - ASSERT_FALSE(s8.isOpen()); - - s3.close(); - ASSERT_TRUE(s3.successStatus()); - ASSERT_FALSE(s3.isOpen()); - - s6.close(); - ASSERT_TRUE(s6.successStatus()); - ASSERT_FALSE(s6.isOpen()); - - s5.close(); - ASSERT_TRUE(s5.successStatus()); - ASSERT_FALSE(s5.isOpen()); - - s4.close(); - ASSERT_TRUE(s4.successStatus()); - ASSERT_FALSE(s4.isOpen()); - - s7.close(); - ASSERT_TRUE(s7.successStatus()); - ASSERT_FALSE(s7.isOpen()); - - s2.close(); - ASSERT_TRUE(s2.successStatus()); - ASSERT_FALSE(s2.isOpen()); - - testTearDown(); + Session s[8]; + for (int i = 0; i < 8; i++) { + s[i].open(); + ASSERT_EQ(OEMCrypto_SUCCESS, s[i].getStatus()); + ASSERT_TRUE(s[i].isOpen()); + } + for (int i = 0; i < 8; i++) { + s[i].close(); + ASSERT_EQ(OEMCrypto_SUCCESS, s[i].getStatus()); + ASSERT_FALSE(s[i].isOpen()); + } } TEST_F(OEMCryptoClientTest, GenerateNonce) { - Session& s = createSession("ONE"); - testSetUp(); + Session s; s.open(); uint32_t nonce; - s.GenerateNonce(&nonce); - s.close(); - ASSERT_TRUE(s.successStatus()); - ASSERT_FALSE(s.isOpen()); - testTearDown(); } TEST_F(OEMCryptoClientTest, GenerateTwoNonces) { - Session& s = createSession("ONE"); - testSetUp(); + Session s; s.open(); uint32_t nonce1; uint32_t nonce2; @@ -1843,16 +1686,10 @@ TEST_F(OEMCryptoClientTest, GenerateTwoNonces) { s.GenerateNonce(&nonce1); s.GenerateNonce(&nonce2); ASSERT_TRUE(nonce1 != nonce2); - - s.close(); - ASSERT_TRUE(s.successStatus()); - ASSERT_FALSE(s.isOpen()); - testTearDown(); } TEST_F(OEMCryptoClientTest, PreventNonceFlood) { - Session& s = createSession("ONE"); - testSetUp(); + Session s; s.open(); int error_counter = 0; uint32_t nonce; @@ -1866,44 +1703,32 @@ TEST_F(OEMCryptoClientTest, PreventNonceFlood) { sleep(2); // After a pause, we should be able to regenerate nonces. s.GenerateNonce(&nonce, &error_counter); ASSERT_EQ(0, error_counter); - s.close(); - testTearDown(); } // Prevent a nonce flood even if each nonce is in a different session. TEST_F(OEMCryptoClientTest, PreventNonceFlood2) { - Session& s = createSession("ONE"); - testSetUp(); int error_counter = 0; uint32_t nonce; // More than 20 nonces should generate an error. // To allow for some slop, we actually test for more than 40. for (int i = 0; i < 60; i++) { + Session s; s.open(); s.GenerateNonce(&nonce, &error_counter); - s.close(); } ASSERT_LE(20, error_counter); error_counter = 0; sleep(2); // After a pause, we should be able to regenerate nonces. + Session s; s.open(); s.GenerateNonce(&nonce, &error_counter); - s.close(); ASSERT_EQ(0, error_counter); - testTearDown(); } TEST_F(OEMCryptoClientTest, GenerateDerivedKeys) { - Session& s = createSession("ONE"); - testSetUp(); + Session s; s.open(); - s.GenerateDerivedKeys(); - - s.close(); - ASSERT_TRUE(s.successStatus()); - ASSERT_FALSE(s.isOpen()); - testTearDown(); } /////////////////////////////////////////////////// @@ -1912,25 +1737,27 @@ TEST_F(OEMCryptoClientTest, GenerateDerivedKeys) { /* These tests will install a test keybox. Since this may be a problem on a production device, they are disabled by default. - Run this program with the command line argument "--gtest_also_run_disabled_tests" + Run this program with the command line argument + "--gtest_also_run_disabled_tests" to enable all of these tests. */ class DISABLED_TestKeybox : public OEMCryptoClientTest { protected: + void SetUp() { + OEMCryptoClientTest::SetUp(); + InstallKeybox(kDefaultKeybox, true); + } void InstallKeybox(const wvoec_mock::WidevineKeybox& keybox, bool good) { OEMCryptoResult sts; uint8_t wrapped[sizeof(wvoec_mock::WidevineKeybox)]; size_t length = sizeof(wvoec_mock::WidevineKeybox); sts = OEMCrypto_WrapKeybox(reinterpret_cast(&keybox), - sizeof(keybox), - wrapped, - &length, - NULL, 0); + sizeof(keybox), wrapped, &length, NULL, 0); ASSERT_EQ(OEMCrypto_SUCCESS, sts); sts = OEMCrypto_InstallKeybox(wrapped, sizeof(keybox)); - if( good ) { + if (good) { ASSERT_EQ(OEMCrypto_SUCCESS, sts); } else { // Can return error now, or return error on IsKeyboxValid. @@ -1939,8 +1766,6 @@ class DISABLED_TestKeybox : public OEMCryptoClientTest { }; TEST_F(DISABLED_TestKeybox, CheckSystemID) { - testSetUp(); - OEMCryptoResult sts; uint8_t key_data[256]; size_t key_data_len = sizeof(key_data); @@ -1950,7 +1775,6 @@ TEST_F(DISABLED_TestKeybox, CheckSystemID) { uint32_t* data = reinterpret_cast(key_data); uint32_t system_id = htonl(data[1]); if (system_id != 0x1019) { - cout << "================================================================\n" << "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" << "WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING \n" @@ -1966,12 +1790,9 @@ TEST_F(DISABLED_TestKeybox, CheckSystemID) { exit(1); } } - testTearDown(); } - TEST_F(DISABLED_TestKeybox, GoodKeybox) { - testSetUp(); wvoec_mock::WidevineKeybox keybox = kValidKeybox02; OEMCryptoResult sts; InstallKeybox(keybox, true); @@ -1984,17 +1805,7 @@ TEST_F(DISABLED_TestKeybox, GoodKeybox) { ASSERT_EQ(OEMCrypto_SUCCESS, sts); } -TEST_F(DISABLED_TestKeybox, DefaultKeybox) { - testSetUp(); - ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize()) - << "OEMCrypto_Initialize failed."; - OEMCryptoResult sts; - sts = OEMCrypto_IsKeyboxValid(); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); -} - TEST_F(DISABLED_TestKeybox, BadCRCKeybox) { - testSetUp(); wvoec_mock::WidevineKeybox keybox = kValidKeybox02; keybox.crc_[1] ^= 42; OEMCryptoResult sts; @@ -2004,7 +1815,6 @@ TEST_F(DISABLED_TestKeybox, BadCRCKeybox) { } TEST_F(DISABLED_TestKeybox, BadMagicKeybox) { - testSetUp(); wvoec_mock::WidevineKeybox keybox = kValidKeybox02; keybox.magic_[1] ^= 42; OEMCryptoResult sts; @@ -2014,7 +1824,6 @@ TEST_F(DISABLED_TestKeybox, BadMagicKeybox) { } TEST_F(DISABLED_TestKeybox, BadDataKeybox) { - testSetUp(); wvoec_mock::WidevineKeybox keybox = kValidKeybox02; keybox.data_[1] ^= 42; OEMCryptoResult sts; @@ -2024,9 +1833,8 @@ TEST_F(DISABLED_TestKeybox, BadDataKeybox) { } TEST_F(DISABLED_TestKeybox, GenerateSignature) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); @@ -2043,9 +1851,8 @@ TEST_F(DISABLED_TestKeybox, GenerateSignature) { size_t signature_length = SignatureBufferMaxLength; OEMCryptoResult sts; - sts = OEMCrypto_GenerateSignature( - s.session_id(), - &context[0], context.size(), signature, &signature_length); + sts = OEMCrypto_GenerateSignature(s.session_id(), &context[0], context.size(), + signature, &signature_length); ASSERT_EQ(OEMCrypto_SUCCESS, sts); @@ -2056,727 +1863,422 @@ TEST_F(DISABLED_TestKeybox, GenerateSignature) { s.ClientSignMessage(context, &expected_signature); ASSERT_EQ(0, memcmp(&expected_signature[0], signature, expected_signature.size())); - - s.close(); - ASSERT_TRUE(s.successStatus()); - ASSERT_FALSE(s.isOpen()); - testTearDown(); } TEST_F(DISABLED_TestKeybox, LoadKeyNoNonce) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); - s.LoadTestKeys(kDuration, 0, 42); - s.close(); - testTearDown(); + s.FillSimpleMessage(kDuration, 0, 42); + s.EncryptAndSign(); + s.LoadTestKeys(); } TEST_F(DISABLED_TestKeybox, LoadKeyWithNonce) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); - s.GenerateDerivedKeys(); - s.LoadTestKeys(0, wvoec_mock::kControlNonceEnabled, s.get_nonce()); - s.close(); - testTearDown(); + s.FillSimpleMessage(0, wvoec_mock::kControlNonceEnabled, s.get_nonce()); + s.EncryptAndSign(); + s.LoadTestKeys(); } TEST_F(DISABLED_TestKeybox, LoadKeyWithNoMAC) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); - s.GenerateDerivedKeys(); + s.FillSimpleMessage(0, 0, 0); + s.EncryptAndSign(); + s.LoadTestKeys("", false); - MessageData data; - s.FillSimpleMessage(&data, 0, 0, 0); + vector context = wvcdm::a2b_hex( + "0a4c08001248000000020000101907d9ffde13aa95c122678053362136bdf840" + "8f8276e4c2d87ec52b61aa1b9f646e58734930acebe899b3e464189a14a87202" + "fb02574e70640bd22ef44b2d7e3912250a230a14080112100915007caa9b5931" + "b76a3a85f046523e10011a09393837363534333231180120002a0c3138383637" + "38373430350000"); + + static const uint32_t SignatureBufferMaxLength = 256; + uint8_t signature[SignatureBufferMaxLength]; + size_t signature_length = SignatureBufferMaxLength; + + OEMCryptoResult sts; + sts = OEMCrypto_GenerateSignature(s.session_id(), &context[0], context.size(), + signature, &signature_length); - MessageData encrypted; - s.EncryptMessage(data, &encrypted); - std::vector signature; - s.ServerSignMessage(encrypted, &signature); - OEMCrypto_KeyObject key_array[kNumKeys]; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); - s.FillKeyArray(encrypted, key_array); - OEMCryptoResult sts = OEMCrypto_LoadKeys(s.session_id(), - message_ptr, sizeof(encrypted), - &signature[0], signature.size(), - NULL, NULL, - kNumKeys, key_array, NULL, 0); ASSERT_EQ(OEMCrypto_SUCCESS, sts); - s.close(); - testTearDown(); + + static const uint32_t SignatureExpectedLength = 32; + ASSERT_EQ(signature_length, SignatureExpectedLength); + + std::vector expected_signature; + s.ClientSignMessage(context, &expected_signature); + ASSERT_EQ( + 0, memcmp(&expected_signature[0], signature, expected_signature.size())); } /* The Bad Range tests verify that OEMCrypto_LoadKeys checks the range of all the pointers. It should reject a message if the pointer does not point into the message buffer */ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange1) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); - s.GenerateDerivedKeys(); - MessageData data; - s.FillSimpleMessage(&data, 0, 0, 0); + s.FillSimpleMessage(0, 0, 0); + s.EncryptAndSign(); + vector mac_keys( + s.encrypted_license().mac_keys, + s.encrypted_license().mac_keys + sizeof(s.encrypted_license().mac_keys)); - MessageData encrypted; - s.EncryptMessage(data, &encrypted); - std::vector signature; - s.ServerSignMessage(encrypted, &signature); - OEMCrypto_KeyObject key_array[kNumKeys]; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); - s.FillKeyArray(encrypted, key_array); - - vector mac_keys(encrypted.mac_keys, - encrypted.mac_keys+sizeof(encrypted.mac_keys)); - - OEMCryptoResult sts = OEMCrypto_LoadKeys(s.session_id(), - message_ptr, sizeof(encrypted), - &signature[0], signature.size(), - encrypted.mac_key_iv, - &mac_keys[0], // Not pointing into buffer. - kNumKeys, key_array, NULL, 0); + OEMCryptoResult sts = OEMCrypto_LoadKeys( + s.session_id(), s.message_ptr(), sizeof(MessageData), &s.signature()[0], + s.signature().size(), s.encrypted_license().mac_key_iv, + &mac_keys[0], // Not pointing into buffer. + kNumKeys, s.key_array(), NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange2) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); - s.GenerateDerivedKeys(); - MessageData data; - s.FillSimpleMessage(&data, 0, 0, 0); + s.FillSimpleMessage(0, 0, 0); + s.EncryptAndSign(); + vector mac_key_iv(s.encrypted_license().mac_key_iv, + s.encrypted_license().mac_key_iv + + sizeof(s.encrypted_license().mac_key_iv)); - MessageData encrypted; - s.EncryptMessage(data, &encrypted); - std::vector signature; - s.ServerSignMessage(encrypted, &signature); - OEMCrypto_KeyObject key_array[kNumKeys]; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); - s.FillKeyArray(encrypted, key_array); - - vector mac_key_iv(encrypted.mac_key_iv, - encrypted.mac_key_iv+sizeof(encrypted.mac_key_iv)); - - OEMCryptoResult sts = OEMCrypto_LoadKeys(s.session_id(), - message_ptr, sizeof(encrypted), - &signature[0], signature.size(), - &mac_key_iv[0], // bad. - encrypted.mac_keys, - kNumKeys, key_array, NULL, 0); + OEMCryptoResult sts = OEMCrypto_LoadKeys( + s.session_id(), s.message_ptr(), sizeof(MessageData), &s.signature()[0], + s.signature().size(), + &mac_key_iv[0], // bad. + s.encrypted_license().mac_keys, kNumKeys, s.key_array(), NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange3) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); - s.GenerateDerivedKeys(); + s.FillSimpleMessage(0, 0, 0); + s.EncryptAndSign(); + vector bad_buffer( + s.encrypted_license().keys[0].key_id, + s.encrypted_license().keys[0].key_id + kTestKeyIdLength); + s.key_array()[0].key_id = &bad_buffer[0]; - MessageData data; - s.FillSimpleMessage(&data, 0, 0, 0); - - MessageData encrypted; - s.EncryptMessage(data, &encrypted); - std::vector signature; - s.ServerSignMessage(encrypted, &signature); - OEMCrypto_KeyObject key_array[kNumKeys]; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); - s.FillKeyArray(encrypted, key_array); - - vector bad_buffer(encrypted.keys[0].key_id, - encrypted.keys[0].key_id+kTestKeyIdLength); - key_array[0].key_id = &bad_buffer[0]; - - OEMCryptoResult sts = OEMCrypto_LoadKeys(s.session_id(), - message_ptr, sizeof(encrypted), - &signature[0], signature.size(), - encrypted.mac_key_iv, - encrypted.mac_keys, - kNumKeys, key_array, NULL, 0); + OEMCryptoResult sts = OEMCrypto_LoadKeys( + s.session_id(), s.message_ptr(), sizeof(MessageData), &s.signature()[0], + s.signature().size(), s.encrypted_license().mac_key_iv, + s.encrypted_license().mac_keys, kNumKeys, s.key_array(), NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange4) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); - s.GenerateDerivedKeys(); + s.FillSimpleMessage(0, 0, 0); + s.EncryptAndSign(); - MessageData data; - s.FillSimpleMessage(&data, 0, 0, 0); + vector bad_buffer( + s.encrypted_license().keys[1].key_data, + s.encrypted_license().keys[1].key_data + wvcdm::KEY_SIZE); + s.key_array()[1].key_data = &bad_buffer[0]; - MessageData encrypted; - s.EncryptMessage(data, &encrypted); - std::vector signature; - s.ServerSignMessage(encrypted, &signature); - OEMCrypto_KeyObject key_array[kNumKeys]; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); - s.FillKeyArray(encrypted, key_array); - - vector bad_buffer(encrypted.keys[1].key_data, - encrypted.keys[1].key_data+wvcdm::KEY_SIZE); - key_array[1].key_data = &bad_buffer[0]; - - OEMCryptoResult sts = OEMCrypto_LoadKeys(s.session_id(), - message_ptr, sizeof(encrypted), - &signature[0], signature.size(), - encrypted.mac_key_iv, - encrypted.mac_keys, - kNumKeys, key_array, NULL, 0); + OEMCryptoResult sts = OEMCrypto_LoadKeys( + s.session_id(), s.message_ptr(), sizeof(MessageData), &s.signature()[0], + s.signature().size(), s.encrypted_license().mac_key_iv, + s.encrypted_license().mac_keys, kNumKeys, s.key_array(), NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange5) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); - s.GenerateDerivedKeys(); - - MessageData data; - s.FillSimpleMessage(&data, 0, 0, 0); - - MessageData encrypted; - s.EncryptMessage(data, &encrypted); - std::vector signature; - s.ServerSignMessage(encrypted, &signature); - OEMCrypto_KeyObject key_array[kNumKeys]; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); - s.FillKeyArray(encrypted, key_array); - - vector bad_buffer(encrypted.keys[1].key_iv, - encrypted.keys[1].key_iv+sizeof(encrypted.keys[1].key_iv)); - key_array[1].key_data_iv = &bad_buffer[0]; - - OEMCryptoResult sts = OEMCrypto_LoadKeys(s.session_id(), - message_ptr, sizeof(encrypted), - &signature[0], signature.size(), - encrypted.mac_key_iv, - encrypted.mac_keys, - kNumKeys, key_array, NULL, 0); + s.FillSimpleMessage(0, 0, 0); + s.EncryptAndSign(); + vector bad_buffer(s.encrypted_license().keys[1].key_iv, + s.encrypted_license().keys[1].key_iv + + sizeof(s.encrypted_license().keys[1].key_iv)); + s.key_array()[1].key_data_iv = &bad_buffer[0]; + OEMCryptoResult sts = OEMCrypto_LoadKeys( + s.session_id(), s.message_ptr(), sizeof(MessageData), &s.signature()[0], + s.signature().size(), s.encrypted_license().mac_key_iv, + s.encrypted_license().mac_keys, kNumKeys, s.key_array(), NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange6) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); + s.FillSimpleMessage(0, 0, 0); + s.EncryptAndSign(); - MessageData data; - s.FillSimpleMessage(&data, 0, 0, 0); + vector bad_buffer(s.key_array()[2].key_control, + s.key_array()[2].key_control + + sizeof(s.encrypted_license().keys[1].control)); + s.key_array()[2].key_control = &bad_buffer[0]; - MessageData encrypted; - s.EncryptMessage(data, &encrypted); - std::vector signature; - s.ServerSignMessage(encrypted, &signature); - OEMCrypto_KeyObject key_array[kNumKeys]; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); - s.FillKeyArray(encrypted, key_array); - - vector bad_buffer(key_array[2].key_control, - key_array[2].key_control+sizeof(encrypted.keys[1].control)); - key_array[2].key_control = &bad_buffer[0]; - - OEMCryptoResult sts = OEMCrypto_LoadKeys(s.session_id(), - message_ptr, sizeof(encrypted), - &signature[0], signature.size(), - encrypted.mac_key_iv, - encrypted.mac_keys, - kNumKeys, key_array, NULL, 0); + OEMCryptoResult sts = OEMCrypto_LoadKeys( + s.session_id(), s.message_ptr(), sizeof(MessageData), &s.signature()[0], + s.signature().size(), s.encrypted_license().mac_key_iv, + s.encrypted_license().mac_keys, kNumKeys, s.key_array(), NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange7) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); + s.FillSimpleMessage(0, 0, 0); + s.EncryptAndSign(); + vector bad_buffer( + s.key_array()[2].key_control_iv, + s.key_array()[2].key_control_iv + + sizeof(s.encrypted_license().keys[1].control_iv)); + s.key_array()[2].key_control_iv = &bad_buffer[0]; - MessageData data; - s.FillSimpleMessage(&data, 0, 0, 0); - - MessageData encrypted; - s.EncryptMessage(data, &encrypted); - std::vector signature; - s.ServerSignMessage(encrypted, &signature); - OEMCrypto_KeyObject key_array[kNumKeys]; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); - s.FillKeyArray(encrypted, key_array); - - vector bad_buffer(key_array[2].key_control_iv, - key_array[2].key_control_iv+sizeof(encrypted.keys[1].control_iv)); - key_array[2].key_control_iv = &bad_buffer[0]; - - OEMCryptoResult sts = OEMCrypto_LoadKeys(s.session_id(), - message_ptr, sizeof(encrypted), - &signature[0], signature.size(), - encrypted.mac_key_iv, - encrypted.mac_keys, - kNumKeys, key_array, NULL, 0); + OEMCryptoResult sts = OEMCrypto_LoadKeys( + s.session_id(), s.message_ptr(), sizeof(MessageData), &s.signature()[0], + s.signature().size(), s.encrypted_license().mac_key_iv, + s.encrypted_license().mac_keys, kNumKeys, s.key_array(), NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, LoadKeyWithBadNonce) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); - s.GenerateDerivedKeys(); - - MessageData data; - s.FillSimpleMessage(&data, 0, wvoec_mock::kControlNonceEnabled, - 42); // bad nonce. - MessageData encrypted; - s.EncryptMessage(data, &encrypted); - std::vector signature; - s.ServerSignMessage(encrypted, &signature); - OEMCrypto_KeyObject key_array[kNumKeys]; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); - s.FillKeyArray(encrypted, key_array); - + s.FillSimpleMessage(0, wvoec_mock::kControlNonceEnabled, 42); // bad nonce. + s.EncryptAndSign(); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), - message_ptr, sizeof(encrypted), - &signature[0], signature.size(), - encrypted.mac_key_iv, - encrypted.mac_keys, - kNumKeys, key_array, NULL, 0); + s.session_id(), s.message_ptr(), sizeof(MessageData), &s.signature()[0], + s.signature().size(), s.encrypted_license().mac_key_iv, + s.encrypted_license().mac_keys, kNumKeys, s.key_array(), NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); - - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, LoadKeyWithBadVerification) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); - - MessageData data; - s.FillSimpleMessage(&data, 0, 0, 0); - data.keys[1].control.verification[2] = 'Z'; - - MessageData encrypted; - s.EncryptMessage(data, &encrypted); - std::vector signature; - s.ServerSignMessage(encrypted, &signature); - OEMCrypto_KeyObject key_array[kNumKeys]; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); - s.FillKeyArray(encrypted, key_array); - + s.FillSimpleMessage(0, 0, 0); + s.license().keys[1].control.verification[2] = 'Z'; + s.EncryptAndSign(); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), - message_ptr, sizeof(encrypted), - &signature[0], signature.size(), - encrypted.mac_key_iv, - encrypted.mac_keys, - kNumKeys, key_array, NULL, 0); + s.session_id(), s.message_ptr(), sizeof(MessageData), &s.signature()[0], + s.signature().size(), s.encrypted_license().mac_key_iv, + s.encrypted_license().mac_keys, kNumKeys, s.key_array(), NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); - - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, LoadKeysBadSignature) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); - s.GenerateDerivedKeys(); - - MessageData data; - s.FillSimpleMessage(&data, 0, 0, 0); - - MessageData encrypted; - s.EncryptMessage(data, &encrypted); - std::vector signature; - s.ServerSignMessage(encrypted, &signature); - OEMCrypto_KeyObject key_array[kNumKeys]; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); - s.FillKeyArray(encrypted, key_array); - - signature[0] ^= 42; // Bad signature. - + s.FillSimpleMessage(0, 0, 0); + s.EncryptAndSign(); + s.signature()[0] ^= 42; // Bad signature. OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), - message_ptr, sizeof(encrypted), - &signature[0], signature.size(), - encrypted.mac_key_iv, - encrypted.mac_keys, - kNumKeys, key_array, NULL, 0); - + s.session_id(), s.message_ptr(), sizeof(MessageData), &s.signature()[0], + s.signature().size(), s.encrypted_license().mac_key_iv, + s.encrypted_license().mac_keys, kNumKeys, s.key_array(), NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); - - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, LoadKeysWithNoDerivedKeys) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); - // s.GenerateDerivedKeys(); - - MessageData data; - s.FillSimpleMessage(&data, 0, 0, 0); - - MessageData encrypted; - s.EncryptMessage(data, &encrypted); - std::vector signature; - s.ServerSignMessage(encrypted, &signature); - OEMCrypto_KeyObject key_array[kNumKeys]; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); - s.FillKeyArray(encrypted, key_array); - + s.FillSimpleMessage(0, 0, 0); + s.EncryptAndSign(); OEMCryptoResult sts = OEMCrypto_LoadKeys( - s.session_id(), - message_ptr, sizeof(encrypted), - &signature[0], signature.size(), - encrypted.mac_key_iv, - encrypted.mac_keys, - kNumKeys, key_array, NULL, 0); - + s.session_id(), s.message_ptr(), sizeof(MessageData), &s.signature()[0], + s.signature().size(), s.encrypted_license().mac_key_iv, + s.encrypted_license().mac_keys, kNumKeys, s.key_array(), NULL, 0); ASSERT_NE(OEMCrypto_SUCCESS, sts); - - s.close(); - testTearDown(); } -class DISABLED_DecryptWithHDCP : public DISABLED_TestKeybox { +class DISABLED_DecryptWithHDCP : public DISABLED_TestKeybox, + public WithParamInterface { public: void DecryptWithHDCP(OEMCrypto_HDCP_Capability version) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); OEMCrypto_HDCP_Capability current, maximum; sts = OEMCrypto_GetHDCPCapability(¤t, &maximum); ASSERT_EQ(OEMCrypto_SUCCESS, sts); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); - s.LoadTestKeys(0, (version << wvoec_mock::kControlHDCPVersionShift) - | wvoec_mock::kControlObserveHDCP | - wvoec_mock::kControlHDCPRequired, 0); + s.FillSimpleMessage(0, (version << wvoec_mock::kControlHDCPVersionShift) | + wvoec_mock::kControlObserveHDCP | + wvoec_mock::kControlHDCPRequired, + 0); + s.EncryptAndSign(); + s.LoadTestKeys(); - // Select the key (from FillSimpleMessage) - vector keyId = wvcdm::a2b_hex("000000000000000000000000"); - sts = OEMCrypto_SelectKey(s.session_id(), &keyId[0], keyId.size()); - ASSERT_EQ(OEMCrypto_SUCCESS, sts) - << "SelectKey failed with version = " << version; - // Set up our expected input and output - vector encryptedData = wvcdm::a2b_hex( - "ec261c115f9d5cda1d5cc7d33c4e37362d1397c89efdd1da5f0065c4848b0462" - "337ba14693735203c9b4184e362439c0cea5e5d1a628425eddf8a6bf9ba901ca" - "46f5a9fd973cffbbe3c276af9919e2e8f6f3f420538b7a0d6dc41487874d96b8" - "efaedb45a689b91beb8c20d36140ad467d9d620b19a5fc6f223b57e0e6a7f913" - "00fd899e5e1b89963e83067ca0912aa5b79df683e2530b55a9645be341bc5f07" - "cffc724790af635c959e2644e51ba7f23bae710eb55a1f2f4e060c3c1dd1387c" - "74415dc880492dd1d5b9ecf3f01de48a44baeb4d3ea5cc4f8d561d0865afcabb" - "fc14a9ab9647e6e31adabb72d792f0c9ba99dc3e9205657d28fc7771d64e6d4b"); - vector encryptionIv = wvcdm::a2b_hex( - "719dbcb253b2ec702bb8c1b1bc2f3bc6"); - vector unencryptedData = wvcdm::a2b_hex( - "19ef4361e16e6825b336e2012ad8ffc9ce176ab2256e1b98aa15b7877bd8c626" - "fa40b2e88373457cbcf4f1b4b9793434a8ac03a708f85974cff01bddcbdd7a8e" - "e33fd160c1d5573bfd8104efd23237edcf28205c3673920553f8dd5e916604b0" - "1082345181dceeae5ea39d829c7f49e1850c460645de33c288723b7ae3d91a17" - "a3f04195cd1945ba7b0f37fef7e82368be30f04365d877766f6d56f67d22a244" - "ef2596d3053f657c1b5d90b64e11797edf1c198a23a7bfc20e4d44c74ae41280" - "a8317f443255f4020eda850ff0954e308f53a634cbce799ae58911bc59ccd6a5" - "de2ac53ee0fa7ea15fc692cc892acc0090865dc57becacddf362a092dfd3040b"); - - // Describe the output - uint8_t outputBuffer[256]; - memset(outputBuffer, 0, sizeof(outputBuffer)); - OEMCrypto_DestBufferDesc destBuffer; - destBuffer.type = OEMCrypto_BufferType_Clear; - destBuffer.buffer.clear.address = outputBuffer; - destBuffer.buffer.clear.max_length = sizeof(outputBuffer); - - // Decrypt the data - sts = OEMCrypto_DecryptCTR(s.session_id(), &encryptedData[0], - encryptedData.size(), true, &encryptionIv[0], 0, - &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); if (version > current) { - EXPECT_EQ(OEMCrypto_ERROR_INSUFFICIENT_HDCP, sts) - << "DecryptCTR did not fail with HDCP version = " << (int)version - << ", min=" << (int)current; - EXPECT_NE(0, memcmp(&unencryptedData[0], outputBuffer, - unencryptedData.size())) - << "DecryptCTR decrypted with HDCP version = " << (int)version - << ", min=" << (int)current; + s.TestDecryptCTR(true, OEMCrypto_ERROR_INSUFFICIENT_HDCP); } else { - EXPECT_EQ(OEMCrypto_SUCCESS, sts) - << "DecryptCTR failed with HDCP version = " << (int)version - << ", min=" << (int)current; - EXPECT_EQ(0, memcmp(&unencryptedData[0], outputBuffer, - unencryptedData.size())) - << "DecryptCTR failed with HDCP version = " << (int)version - << ", min=" << (int)current; + s.TestDecryptCTR(true, OEMCrypto_SUCCESS); } - s.close(); - testTearDown(); - } }; -TEST_F(DISABLED_DecryptWithHDCP, DecryptWithHDCP) { - DecryptWithHDCP(1); // Version 1.0 - DecryptWithHDCP(2); // Version 2.0 - DecryptWithHDCP(3); // Version 2.1 - DecryptWithHDCP(4); // Version 2.2 +TEST_P(DISABLED_DecryptWithHDCP, Decrypt) { + // Test parameterized by HDCP version. + DecryptWithHDCP(static_cast(GetParam())); } - +INSTANTIATE_TEST_CASE_P(TestHDCP, DISABLED_DecryptWithHDCP, Range(1, 5)); /////////////////////////////////////////////////// // Load, Refresh Keys Test /////////////////////////////////////////////////// -class DISABLED_RefreshKeyTest : public DISABLED_TestKeybox { +class DISABLED_RefreshKeyTest + : public DISABLED_TestKeybox, + public WithParamInterface > { public: - void RefreshWithNonce(const int key_count) { - Session& s = createSession("ONE"); - s.open(); - s.GenerateDerivedKeys(); - s.LoadTestKeys(kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce()); - uint32_t nonce; - s.GenerateNonce(&nonce); - s.RefreshTestKeys(key_count, wvoec_mock::kControlNonceEnabled, nonce, true); - s.close(); - } - - void RefresNoNonce(const int key_count) { - Session& s = createSession("ONE"); - s.open(); - s.GenerateDerivedKeys(); - s.LoadTestKeys(kDuration, 0, 0); - uint32_t nonce; - s.GenerateNonce(&nonce); - s.RefreshTestKeys(key_count,0, 0, true); - s.close(); - } - - void RefreshOldNonce(const int key_count) { - Session& s = createSession("ONE"); - s.open(); - s.GenerateDerivedKeys(); - s.LoadTestKeys(kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce()); - uint32_t nonce = s.get_nonce(); - s.RefreshTestKeys(key_count, wvoec_mock::kControlNonceEnabled, nonce, - false); - s.close(); - } - void RefreshBadNonce(const int key_count) { - Session& s = createSession("ONE"); - s.open(); - s.GenerateDerivedKeys(); - s.LoadTestKeys(kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce()); - uint32_t nonce; - s.GenerateNonce(&nonce); - nonce ^= 42; - s.RefreshTestKeys(key_count, wvoec_mock::kControlNonceEnabled, nonce, - false); - s.close(); + virtual void SetUp() { + DISABLED_TestKeybox::SetUp(); + new_mac_keys_ = + GetParam().first; // Whether to put new mac keys in LoadKeys. + num_keys_ = static_cast(GetParam().second); // # keys in refresh. } + protected: + bool new_mac_keys_; + size_t num_keys_; }; -TEST_F(DISABLED_RefreshKeyTest, RefreshAllKeys) { - testSetUp(); - InstallKeybox(kDefaultKeybox, true); - RefreshWithNonce(1); // One key control block to refresh all keys. - RefreshOldNonce(1); - RefreshBadNonce(1); - testTearDown(); +TEST_P(DISABLED_RefreshKeyTest, RefreshWithNonce) { + Session s; + s.open(); + s.GenerateDerivedKeys(); + s.FillSimpleMessage(kDuration, wvoec_mock::kControlNonceEnabled, + s.get_nonce()); + s.EncryptAndSign(); + s.LoadTestKeys("", new_mac_keys_); + uint32_t nonce; + s.GenerateNonce(&nonce); + s.RefreshTestKeys(num_keys_, wvoec_mock::kControlNonceEnabled, nonce, true); } -TEST_F(DISABLED_RefreshKeyTest, RefreshEachKeys) { - testSetUp(); - InstallKeybox(kDefaultKeybox, true); - RefreshWithNonce(kNumKeys); // Each key control block updates a different key. - RefreshOldNonce(kNumKeys); - RefreshBadNonce(kNumKeys); - testTearDown(); +TEST_P(DISABLED_RefreshKeyTest, RefresNoNonce) { + Session s; + s.open(); + s.GenerateDerivedKeys(); + s.FillSimpleMessage(kDuration, 0, 0); + s.EncryptAndSign(); + s.LoadTestKeys("", new_mac_keys_); + uint32_t nonce; + s.GenerateNonce(&nonce); + s.RefreshTestKeys(num_keys_, 0, 0, true); } +TEST_P(DISABLED_RefreshKeyTest, RefreshOldNonce) { + Session s; + s.open(); + s.GenerateDerivedKeys(); + s.FillSimpleMessage(kDuration, wvoec_mock::kControlNonceEnabled, + s.get_nonce()); + s.EncryptAndSign(); + s.LoadTestKeys("", new_mac_keys_); + uint32_t nonce = s.get_nonce(); + s.RefreshTestKeys(num_keys_, wvoec_mock::kControlNonceEnabled, nonce, false); +} + +TEST_P(DISABLED_RefreshKeyTest, RefreshBadNonce) { + Session s; + s.open(); + s.GenerateDerivedKeys(); + s.FillSimpleMessage(kDuration, wvoec_mock::kControlNonceEnabled, + s.get_nonce()); + s.EncryptAndSign(); + s.LoadTestKeys("", new_mac_keys_); + uint32_t nonce; + s.GenerateNonce(&nonce); + nonce ^= 42; + s.RefreshTestKeys(num_keys_, wvoec_mock::kControlNonceEnabled, nonce, false); +} + +// Of only one key control block in the refesh, we update all the keys. +INSTANTIATE_TEST_CASE_P(TestRefreshAllKeys, DISABLED_RefreshKeyTest, + Values(std::make_pair(true, 1), + std::make_pair(false, 1))); + +// If multiple key control blocks, we update each key separately. +INSTANTIATE_TEST_CASE_P(TestRefreshEachKeys, DISABLED_RefreshKeyTest, + Values(std::make_pair(true, kNumKeys), + std::make_pair(false, kNumKeys))); + /////////////////////////////////////////////////// // Decrypt Tests /////////////////////////////////////////////////// TEST_F(DISABLED_TestKeybox, Decrypt) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); - s.LoadTestKeys(kDuration, 0, 0); - - // Select the key (from FillSimpleMessage) - vector keyId = wvcdm::a2b_hex("000000000000000000000000"); - sts = OEMCrypto_SelectKey(s.session_id(), &keyId[0], keyId.size()); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - - // Set up our expected input and output - vector encryptedData = wvcdm::a2b_hex( - "ec261c115f9d5cda1d5cc7d33c4e37362d1397c89efdd1da5f0065c4848b0462" - "337ba14693735203c9b4184e362439c0cea5e5d1a628425eddf8a6bf9ba901ca" - "46f5a9fd973cffbbe3c276af9919e2e8f6f3f420538b7a0d6dc41487874d96b8" - "efaedb45a689b91beb8c20d36140ad467d9d620b19a5fc6f223b57e0e6a7f913" - "00fd899e5e1b89963e83067ca0912aa5b79df683e2530b55a9645be341bc5f07" - "cffc724790af635c959e2644e51ba7f23bae710eb55a1f2f4e060c3c1dd1387c" - "74415dc880492dd1d5b9ecf3f01de48a44baeb4d3ea5cc4f8d561d0865afcabb" - "fc14a9ab9647e6e31adabb72d792f0c9ba99dc3e9205657d28fc7771d64e6d4b"); - vector encryptionIv = wvcdm::a2b_hex( - "719dbcb253b2ec702bb8c1b1bc2f3bc6"); - vector unencryptedData = wvcdm::a2b_hex( - "19ef4361e16e6825b336e2012ad8ffc9ce176ab2256e1b98aa15b7877bd8c626" - "fa40b2e88373457cbcf4f1b4b9793434a8ac03a708f85974cff01bddcbdd7a8e" - "e33fd160c1d5573bfd8104efd23237edcf28205c3673920553f8dd5e916604b0" - "1082345181dceeae5ea39d829c7f49e1850c460645de33c288723b7ae3d91a17" - "a3f04195cd1945ba7b0f37fef7e82368be30f04365d877766f6d56f67d22a244" - "ef2596d3053f657c1b5d90b64e11797edf1c198a23a7bfc20e4d44c74ae41280" - "a8317f443255f4020eda850ff0954e308f53a634cbce799ae58911bc59ccd6a5" - "de2ac53ee0fa7ea15fc692cc892acc0090865dc57becacddf362a092dfd3040b"); - - // Describe the output - uint8_t outputBuffer[256]; - OEMCrypto_DestBufferDesc destBuffer; - destBuffer.type = OEMCrypto_BufferType_Clear; - destBuffer.buffer.clear.address = outputBuffer; - destBuffer.buffer.clear.max_length = sizeof(outputBuffer); - - // Decrypt the data - sts = OEMCrypto_DecryptCTR(s.session_id(), &encryptedData[0], - encryptedData.size(), true, &encryptionIv[0], 0, - &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer, - unencryptedData.size())); - - s.close(); - testTearDown(); + s.FillSimpleMessage(kDuration, 0, 0); + s.EncryptAndSign(); + s.LoadTestKeys(); + s.TestDecryptCTR(); } TEST_F(DISABLED_TestKeybox, DecryptZeroDuration) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); - s.LoadTestKeys(0, 0, 0); - - // Select the key (from FillSimpleMessage) - vector keyId = wvcdm::a2b_hex("000000000000000000000000"); - sts = OEMCrypto_SelectKey(s.session_id(), &keyId[0], keyId.size()); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - - // Set up our expected input and output - vector encryptedData = wvcdm::a2b_hex( - "ec261c115f9d5cda1d5cc7d33c4e37362d1397c89efdd1da5f0065c4848b0462" - "337ba14693735203c9b4184e362439c0cea5e5d1a628425eddf8a6bf9ba901ca" - "46f5a9fd973cffbbe3c276af9919e2e8f6f3f420538b7a0d6dc41487874d96b8" - "efaedb45a689b91beb8c20d36140ad467d9d620b19a5fc6f223b57e0e6a7f913" - "00fd899e5e1b89963e83067ca0912aa5b79df683e2530b55a9645be341bc5f07" - "cffc724790af635c959e2644e51ba7f23bae710eb55a1f2f4e060c3c1dd1387c" - "74415dc880492dd1d5b9ecf3f01de48a44baeb4d3ea5cc4f8d561d0865afcabb" - "fc14a9ab9647e6e31adabb72d792f0c9ba99dc3e9205657d28fc7771d64e6d4b"); - vector encryptionIv = wvcdm::a2b_hex( - "719dbcb253b2ec702bb8c1b1bc2f3bc6"); - vector unencryptedData = wvcdm::a2b_hex( - "19ef4361e16e6825b336e2012ad8ffc9ce176ab2256e1b98aa15b7877bd8c626" - "fa40b2e88373457cbcf4f1b4b9793434a8ac03a708f85974cff01bddcbdd7a8e" - "e33fd160c1d5573bfd8104efd23237edcf28205c3673920553f8dd5e916604b0" - "1082345181dceeae5ea39d829c7f49e1850c460645de33c288723b7ae3d91a17" - "a3f04195cd1945ba7b0f37fef7e82368be30f04365d877766f6d56f67d22a244" - "ef2596d3053f657c1b5d90b64e11797edf1c198a23a7bfc20e4d44c74ae41280" - "a8317f443255f4020eda850ff0954e308f53a634cbce799ae58911bc59ccd6a5" - "de2ac53ee0fa7ea15fc692cc892acc0090865dc57becacddf362a092dfd3040b"); - - // Describe the output - uint8_t outputBuffer[256]; - OEMCrypto_DestBufferDesc destBuffer; - destBuffer.type = OEMCrypto_BufferType_Clear; - destBuffer.buffer.clear.address = outputBuffer; - destBuffer.buffer.clear.max_length = sizeof(outputBuffer); - - // Decrypt the data - sts = OEMCrypto_DecryptCTR(s.session_id(), &encryptedData[0], - encryptedData.size(), true, &encryptionIv[0], 0, - &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer, - unencryptedData.size())); - - s.close(); - testTearDown(); + s.FillSimpleMessage(0, 0, 0); + s.EncryptAndSign(); + s.LoadTestKeys(); + s.TestDecryptCTR(); } TEST_F(DISABLED_TestKeybox, DecryptWithOffset) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); - s.LoadTestKeys(kDuration, 0, 0); + s.FillSimpleMessage(kDuration, 0, 0); + s.EncryptAndSign(); + s.LoadTestKeys(); // Select the key (from FillSimpleMessage) vector keyId = wvcdm::a2b_hex("000000000000000000000000"); - sts = OEMCrypto_SelectKey(s.session_id(), - &keyId[0], - keyId.size()); + sts = OEMCrypto_SelectKey(s.session_id(), &keyId[0], keyId.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); // Set up our expected input and output @@ -2809,16 +2311,13 @@ TEST_F(DISABLED_TestKeybox, DecryptWithOffset) { destBuffer.buffer.clear.max_length = sizeof(outputBuffer); // Decrypt the data - sts = OEMCrypto_DecryptCTR(s.session_id(), &encryptedData[0], - encryptedData.size(), true, &encryptionIv[0], 5, - &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); + sts = OEMCrypto_DecryptCTR( + s.session_id(), &encryptedData[0], encryptedData.size(), true, + &encryptionIv[0], 5, &destBuffer, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer, unencryptedData.size())); - - s.close(); - testTearDown(); } // Increment counter for AES-CTR. The CENC spec specifies we increment only @@ -2829,11 +2328,11 @@ void ctr128_inc64(uint8_t* counter) { uint32_t n = 16; do { if (++counter[--n] != 0) return; - } while (n>8); + } while (n > 8); } -vector EncryptCTR(const vector &key, - const vector &iv, - const vector &in, size_t block_offset) { +vector EncryptCTR(const vector& key, + const vector& iv, const vector& in, + size_t block_offset) { AES_KEY aes_key; AES_set_encrypt_key(&key[0], AES_BLOCK_SIZE * 8, &aes_key); @@ -2843,7 +2342,7 @@ vector EncryptCTR(const vector &key, // Encrypt the IV. uint8_t ecount_buf[AES_BLOCK_SIZE]; - vector out( in.size()); + vector out(in.size()); size_t cipher_data_length = in.size(); size_t l = 0; @@ -2861,19 +2360,18 @@ vector EncryptCTR(const vector &key, TEST_F(DISABLED_TestKeybox, DecryptWithNearWrap) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); - s.LoadTestKeys(kDuration, 0, 0); + s.FillSimpleMessage(kDuration, 0, 0); + s.EncryptAndSign(); + s.LoadTestKeys(); // Select the key (from FillSimpleMessage) vector keyId = wvcdm::a2b_hex("000000000000000000000000"); - sts = OEMCrypto_SelectKey(s.session_id(), - &keyId[0], - keyId.size()); + sts = OEMCrypto_SelectKey(s.session_id(), &keyId[0], keyId.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); // Set up our expected input and output @@ -2890,8 +2388,8 @@ TEST_F(DISABLED_TestKeybox, DecryptWithNearWrap) { "eae94f98296770275b0d738207a8217cd6118f6ebc6e393428f2268cfedf800e" "a7ebc606471b9a9dfccd1589e86d88fde508261eaf190efd20554ce9e14ff3c9"); size_t block_offset = 5; - vector encryptedData = EncryptCTR(key, encryptionIv, unencryptedData, - block_offset) ; + vector encryptedData = + EncryptCTR(key, encryptionIv, unencryptedData, block_offset); // Describe the output uint8_t outputBuffer[256]; @@ -2901,27 +2399,25 @@ TEST_F(DISABLED_TestKeybox, DecryptWithNearWrap) { destBuffer.buffer.clear.max_length = sizeof(outputBuffer); // Decrypt the data - sts = OEMCrypto_DecryptCTR(s.session_id(), &encryptedData[0], - encryptedData.size(), true, &encryptionIv[0], - block_offset, &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); + sts = OEMCrypto_DecryptCTR( + s.session_id(), &encryptedData[0], encryptedData.size(), true, + &encryptionIv[0], block_offset, &destBuffer, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer, unencryptedData.size())); - - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, DecryptUnencrypted) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); - s.LoadTestKeys(kDuration, 0, 0); + s.FillSimpleMessage(kDuration, 0, 0); + s.EncryptAndSign(); + s.LoadTestKeys(); // Select the key (from FillSimpleMessage) vector keyId = wvcdm::a2b_hex("000000000000000000000000"); @@ -2949,23 +2445,19 @@ TEST_F(DISABLED_TestKeybox, DecryptUnencrypted) { destBuffer.buffer.clear.max_length = sizeof(outputBuffer); // Decrypt the data - sts = OEMCrypto_DecryptCTR(s.session_id(), &unencryptedData[0], - unencryptedData.size(), false, &encryptionIv[0], 0, - &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); + sts = OEMCrypto_DecryptCTR( + s.session_id(), &unencryptedData[0], unencryptedData.size(), false, + &encryptionIv[0], 0, &destBuffer, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer, unencryptedData.size())); - - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, DecryptUnencryptedNoKey) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("NOKEY"); + Session s; s.open(); // CLear data should be copied even if there is no key selected. @@ -2991,160 +2483,44 @@ TEST_F(DISABLED_TestKeybox, DecryptUnencryptedNoKey) { destBuffer.buffer.clear.max_length = sizeof(outputBuffer); // Decrypt the data - sts = OEMCrypto_DecryptCTR(s.session_id(), &unencryptedData[0], - unencryptedData.size(), false, &encryptionIv[0], 0, - &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); + sts = OEMCrypto_DecryptCTR( + s.session_id(), &unencryptedData[0], unencryptedData.size(), false, + &encryptionIv[0], 0, &destBuffer, + OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer, unencryptedData.size())); - - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, DecryptSecureToClear) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); - s.LoadTestKeys(kDuration, wvoec_mock::kControlObserveDataPath - | wvoec_mock::kControlDataPathSecure, 0); - - // Select the key (from FillSimpleMessage) - vector keyId = wvcdm::a2b_hex("000000000000000000000000"); - sts = OEMCrypto_SelectKey(s.session_id(), &keyId[0], keyId.size()); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - - // Set up our expected input and output - vector encryptedData = wvcdm::a2b_hex( - "ec261c115f9d5cda1d5cc7d33c4e37362d1397c89efdd1da5f0065c4848b0462" - "337ba14693735203c9b4184e362439c0cea5e5d1a628425eddf8a6bf9ba901ca" - "46f5a9fd973cffbbe3c276af9919e2e8f6f3f420538b7a0d6dc41487874d96b8" - "efaedb45a689b91beb8c20d36140ad467d9d620b19a5fc6f223b57e0e6a7f913" - "00fd899e5e1b89963e83067ca0912aa5b79df683e2530b55a9645be341bc5f07" - "cffc724790af635c959e2644e51ba7f23bae710eb55a1f2f4e060c3c1dd1387c" - "74415dc880492dd1d5b9ecf3f01de48a44baeb4d3ea5cc4f8d561d0865afcabb" - "fc14a9ab9647e6e31adabb72d792f0c9ba99dc3e9205657d28fc7771d64e6d4b"); - vector encryptionIv = wvcdm::a2b_hex( - "719dbcb253b2ec702bb8c1b1bc2f3bc6"); - vector unencryptedData = wvcdm::a2b_hex( - "19ef4361e16e6825b336e2012ad8ffc9ce176ab2256e1b98aa15b7877bd8c626" - "fa40b2e88373457cbcf4f1b4b9793434a8ac03a708f85974cff01bddcbdd7a8e" - "e33fd160c1d5573bfd8104efd23237edcf28205c3673920553f8dd5e916604b0" - "1082345181dceeae5ea39d829c7f49e1850c460645de33c288723b7ae3d91a17" - "a3f04195cd1945ba7b0f37fef7e82368be30f04365d877766f6d56f67d22a244" - "ef2596d3053f657c1b5d90b64e11797edf1c198a23a7bfc20e4d44c74ae41280" - "a8317f443255f4020eda850ff0954e308f53a634cbce799ae58911bc59ccd6a5" - "de2ac53ee0fa7ea15fc692cc892acc0090865dc57becacddf362a092dfd3040b"); - - // Describe the output - uint8_t outputBuffer[256]; - OEMCrypto_DestBufferDesc destBuffer; - destBuffer.type = OEMCrypto_BufferType_Clear; - destBuffer.buffer.clear.address = outputBuffer; - destBuffer.buffer.clear.max_length = sizeof(outputBuffer); - - // Decrypt the data - sts = OEMCrypto_DecryptCTR(s.session_id(), &encryptedData[0], - encryptedData.size(), true, &encryptionIv[0], 0, - &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - ASSERT_NE(OEMCrypto_SUCCESS, sts); - ASSERT_NE(0, memcmp(&unencryptedData[0], outputBuffer, - unencryptedData.size())); - - s.close(); - testTearDown(); + s.FillSimpleMessage(kDuration, wvoec_mock::kControlObserveDataPath | + wvoec_mock::kControlDataPathSecure, + 0); + s.EncryptAndSign(); + s.LoadTestKeys(); + s.TestDecryptCTR(true, OEMCrypto_ERROR_UNKNOWN_FAILURE); } TEST_F(DISABLED_TestKeybox, KeyDuration) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); - s.LoadTestKeys(kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce()); - - // Select the key (from FillSimpleMessage) - vector keyId = wvcdm::a2b_hex("000000000000000000000000"); - sts = OEMCrypto_SelectKey(s.session_id(), &keyId[0], keyId.size()); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - - // Set up our expected input and output - vector encryptedData = wvcdm::a2b_hex( - "ec261c115f9d5cda1d5cc7d33c4e37362d1397c89efdd1da5f0065c4848b0462" - "337ba14693735203c9b4184e362439c0cea5e5d1a628425eddf8a6bf9ba901ca" - "46f5a9fd973cffbbe3c276af9919e2e8f6f3f420538b7a0d6dc41487874d96b8" - "efaedb45a689b91beb8c20d36140ad467d9d620b19a5fc6f223b57e0e6a7f913" - "00fd899e5e1b89963e83067ca0912aa5b79df683e2530b55a9645be341bc5f07" - "cffc724790af635c959e2644e51ba7f23bae710eb55a1f2f4e060c3c1dd1387c" - "74415dc880492dd1d5b9ecf3f01de48a44baeb4d3ea5cc4f8d561d0865afcabb" - "fc14a9ab9647e6e31adabb72d792f0c9ba99dc3e9205657d28fc7771d64e6d4b"); - vector encryptionIv = wvcdm::a2b_hex( - "719dbcb253b2ec702bb8c1b1bc2f3bc6"); - vector unencryptedData = wvcdm::a2b_hex( - "19ef4361e16e6825b336e2012ad8ffc9ce176ab2256e1b98aa15b7877bd8c626" - "fa40b2e88373457cbcf4f1b4b9793434a8ac03a708f85974cff01bddcbdd7a8e" - "e33fd160c1d5573bfd8104efd23237edcf28205c3673920553f8dd5e916604b0" - "1082345181dceeae5ea39d829c7f49e1850c460645de33c288723b7ae3d91a17" - "a3f04195cd1945ba7b0f37fef7e82368be30f04365d877766f6d56f67d22a244" - "ef2596d3053f657c1b5d90b64e11797edf1c198a23a7bfc20e4d44c74ae41280" - "a8317f443255f4020eda850ff0954e308f53a634cbce799ae58911bc59ccd6a5" - "de2ac53ee0fa7ea15fc692cc892acc0090865dc57becacddf362a092dfd3040b"); - - // Describe the output - uint8_t outputBuffer[256]; - OEMCrypto_DestBufferDesc destBuffer; - destBuffer.type = OEMCrypto_BufferType_Clear; - destBuffer.buffer.clear.address = outputBuffer; - destBuffer.buffer.clear.max_length = sizeof(outputBuffer); - // Decrypt the data - sts = OEMCrypto_DecryptCTR(s.session_id(), &encryptedData[0], - encryptedData.size(), true, &encryptionIv[0], 0, - &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer, - unencryptedData.size())); - + s.FillSimpleMessage(kDuration, wvoec_mock::kControlNonceEnabled, + s.get_nonce()); + s.EncryptAndSign(); + s.LoadTestKeys(); + s.TestDecryptCTR(true, OEMCrypto_SUCCESS); sleep(kShortSleep); // Should still be valid key. - - memset(outputBuffer, 0, sizeof(outputBuffer)); - destBuffer.type = OEMCrypto_BufferType_Clear; - destBuffer.buffer.clear.address = outputBuffer; - destBuffer.buffer.clear.max_length = sizeof(outputBuffer); - - // Decrypt the data - sts = OEMCrypto_DecryptCTR(s.session_id(), &encryptedData[0], - encryptedData.size(), true, &encryptionIv[0], 0, - &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer, - unencryptedData.size())); - + s.TestDecryptCTR(false, OEMCrypto_SUCCESS); sleep(kLongSleep); // Should be expired key. - - memset(outputBuffer, 0, sizeof(outputBuffer)); - destBuffer.type = OEMCrypto_BufferType_Clear; - destBuffer.buffer.clear.address = outputBuffer; - destBuffer.buffer.clear.max_length = sizeof(outputBuffer); - - // Decrypt the data - sts = OEMCrypto_DecryptCTR(s.session_id(), &encryptedData[0], - encryptedData.size(), true, &encryptionIv[0], 0, - &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, sts); - ASSERT_NE(0, memcmp(&unencryptedData[0], outputBuffer, - unencryptedData.size())); - - s.close(); - testTearDown(); + s.TestDecryptCTR(false, OEMCrypto_ERROR_KEY_EXPIRED); } /////////////////////////////////////////////////// @@ -3153,24 +2529,24 @@ TEST_F(DISABLED_TestKeybox, KeyDuration) { void TestKey(const uint8_t key[], size_t length) { uint8_t const* p = key; - RSA* rsa = d2i_RSAPrivateKey(0, &p , length); + RSA* rsa = d2i_RSAPrivateKey(0, &p, length); if (!rsa) { cout << "d2i_RSAPrivateKey failed. "; dump_openssl_error(); ASSERT_TRUE(false); } switch (RSA_check_key(rsa)) { - case 1: // valid. - ASSERT_TRUE(true); - return; - case 0: // not valid. - cout << "[TestKey(): rsa key not valid] "; - dump_openssl_error(); - ASSERT_TRUE(false); - default: // -1 == check failed. - cout << "[TestKey(): error checking rsa key] "; - dump_openssl_error(); - ASSERT_TRUE(false); + case 1: // valid. + ASSERT_TRUE(true); + return; + case 0: // not valid. + cout << "[TestKey(): rsa key not valid] "; + dump_openssl_error(); + ASSERT_TRUE(false); + default: // -1 == check failed. + cout << "[TestKey(): error checking rsa key] "; + dump_openssl_error(); + ASSERT_TRUE(false); } } TEST_F(DISABLED_TestKeybox, ValidateRSATestKeys) { @@ -3179,9 +2555,8 @@ TEST_F(DISABLED_TestKeybox, ValidateRSATestKeys) { } TEST_F(DISABLED_TestKeybox, CertificateProvision) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); struct RSAPrivateKeyMessage encrypted; @@ -3191,264 +2566,207 @@ TEST_F(DISABLED_TestKeybox, CertificateProvision) { s.RewrapRSAKey(encrypted, signature, &wrapped_key, true); vector clear_key(kTestRSAPKCS8PrivateKeyInfo2_2048, - kTestRSAPKCS8PrivateKeyInfo2_2048 - + sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048)); + kTestRSAPKCS8PrivateKeyInfo2_2048 + + sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048)); ASSERT_EQ(NULL, find(wrapped_key, clear_key)); - - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, CertificateProvisionBadRange1) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); struct RSAPrivateKeyMessage encrypted; std::vector signature; s.MakeRSACertificate(&encrypted, &signature, kSign_RSASSA_PSS); vector wrapped_key; - - size_t wrapped_key_length = 0; const uint8_t* message_ptr = reinterpret_cast(&encrypted); + size_t wrapped_key_length = 0; ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, - OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr, - sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, - encrypted.rsa_key, - encrypted.rsa_key_length, - encrypted.rsa_key_iv, NULL, - &wrapped_key_length)); + OEMCrypto_RewrapDeviceRSAKey( + s.session_id(), message_ptr, sizeof(MessageData), &signature[0], + signature.size(), &encrypted.nonce, encrypted.rsa_key, + encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, + &wrapped_key_length)); wrapped_key.clear(); wrapped_key.resize(wrapped_key_length); uint32_t nonce = encrypted.nonce; - ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr, - sizeof(encrypted), &signature[0], - signature.size(), &nonce, - encrypted.rsa_key, - encrypted.rsa_key_length, - encrypted.rsa_key_iv, - & (wrapped_key.front()), - &wrapped_key_length)); - s.close(); - testTearDown(); + ASSERT_NE( + OEMCrypto_SUCCESS, + OEMCrypto_RewrapDeviceRSAKey( + s.session_id(), message_ptr, sizeof(MessageData), &signature[0], + signature.size(), &nonce, encrypted.rsa_key, encrypted.rsa_key_length, + encrypted.rsa_key_iv, &(wrapped_key.front()), &wrapped_key_length)); } TEST_F(DISABLED_TestKeybox, CertificateProvisionBadRange2) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); struct RSAPrivateKeyMessage encrypted; std::vector signature; s.MakeRSACertificate(&encrypted, &signature, kSign_RSASSA_PSS); vector wrapped_key; - - size_t wrapped_key_length = 0; const uint8_t* message_ptr = reinterpret_cast(&encrypted); + size_t wrapped_key_length = 0; ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, - OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr, - sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, - encrypted.rsa_key, - encrypted.rsa_key_length, - encrypted.rsa_key_iv, NULL, - &wrapped_key_length)); + OEMCrypto_RewrapDeviceRSAKey( + s.session_id(), message_ptr, sizeof(MessageData), &signature[0], + signature.size(), &encrypted.nonce, encrypted.rsa_key, + encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, + &wrapped_key_length)); wrapped_key.clear(); wrapped_key.resize(wrapped_key_length); vector bad_buffer(encrypted.rsa_key, - encrypted.rsa_key+sizeof(encrypted.rsa_key)); + encrypted.rsa_key + sizeof(encrypted.rsa_key)); ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr, - sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, - &bad_buffer[0], - encrypted.rsa_key_length, - encrypted.rsa_key_iv, - & (wrapped_key.front()), - &wrapped_key_length)); - s.close(); - testTearDown(); + OEMCrypto_RewrapDeviceRSAKey( + s.session_id(), message_ptr, sizeof(MessageData), &signature[0], + signature.size(), &encrypted.nonce, &bad_buffer[0], + encrypted.rsa_key_length, encrypted.rsa_key_iv, + &(wrapped_key.front()), &wrapped_key_length)); } TEST_F(DISABLED_TestKeybox, CertificateProvisionBadRange3) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); struct RSAPrivateKeyMessage encrypted; std::vector signature; s.MakeRSACertificate(&encrypted, &signature, kSign_RSASSA_PSS); + const uint8_t* message_ptr = reinterpret_cast(&encrypted); vector wrapped_key; size_t wrapped_key_length = 0; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, - OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr, - sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, - encrypted.rsa_key, - encrypted.rsa_key_length, - encrypted.rsa_key_iv, NULL, - &wrapped_key_length)); + OEMCrypto_RewrapDeviceRSAKey( + s.session_id(), message_ptr, sizeof(MessageData), &signature[0], + signature.size(), &encrypted.nonce, encrypted.rsa_key, + encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, + &wrapped_key_length)); wrapped_key.clear(); wrapped_key.resize(wrapped_key_length); vector bad_buffer(encrypted.rsa_key, - encrypted.rsa_key+sizeof(encrypted.rsa_key)); + encrypted.rsa_key + sizeof(encrypted.rsa_key)); ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr, - sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, - encrypted.rsa_key, - encrypted.rsa_key_length, - &bad_buffer[0], - & (wrapped_key.front()), - &wrapped_key_length)); - s.close(); - testTearDown(); + OEMCrypto_RewrapDeviceRSAKey( + s.session_id(), message_ptr, sizeof(MessageData), &signature[0], + signature.size(), &encrypted.nonce, encrypted.rsa_key, + encrypted.rsa_key_length, &bad_buffer[0], + &(wrapped_key.front()), &wrapped_key_length)); } TEST_F(DISABLED_TestKeybox, CertificateProvisionBadSignature) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); struct RSAPrivateKeyMessage encrypted; std::vector signature; s.MakeRSACertificate(&encrypted, &signature, kSign_RSASSA_PSS); vector wrapped_key; + const uint8_t* message_ptr = reinterpret_cast(&encrypted); size_t wrapped_key_length = 0; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, - OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr, - sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, - encrypted.rsa_key, - encrypted.rsa_key_length, - encrypted.rsa_key_iv, NULL, - &wrapped_key_length)); + OEMCrypto_RewrapDeviceRSAKey( + s.session_id(), message_ptr, sizeof(MessageData), &signature[0], + signature.size(), &encrypted.nonce, encrypted.rsa_key, + encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, + &wrapped_key_length)); wrapped_key.clear(); wrapped_key.resize(wrapped_key_length); signature[4] ^= 42; // bad signature. ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr, - sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, - encrypted.rsa_key, - encrypted.rsa_key_length, - encrypted.rsa_key_iv, - & (wrapped_key.front()), - &wrapped_key_length)); - s.close(); - testTearDown(); + OEMCrypto_RewrapDeviceRSAKey( + s.session_id(), message_ptr, sizeof(MessageData), &signature[0], + signature.size(), &encrypted.nonce, encrypted.rsa_key, + encrypted.rsa_key_length, encrypted.rsa_key_iv, + &(wrapped_key.front()), &wrapped_key_length)); } TEST_F(DISABLED_TestKeybox, CertificateProvisionBadNonce) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); struct RSAPrivateKeyMessage encrypted; std::vector signature; s.MakeRSACertificate(&encrypted, &signature, kSign_RSASSA_PSS); vector wrapped_key; + const uint8_t* message_ptr = reinterpret_cast(&encrypted); size_t wrapped_key_length = 0; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, - OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr, - sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, - encrypted.rsa_key, - encrypted.rsa_key_length, - encrypted.rsa_key_iv, NULL, - &wrapped_key_length)); + OEMCrypto_RewrapDeviceRSAKey( + s.session_id(), message_ptr, sizeof(MessageData), &signature[0], + signature.size(), &encrypted.nonce, encrypted.rsa_key, + encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, + &wrapped_key_length)); wrapped_key.clear(); wrapped_key.resize(wrapped_key_length); encrypted.nonce ^= 42; // Almost surely a bad nonce. ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr, - sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, - encrypted.rsa_key, - encrypted.rsa_key_length, - encrypted.rsa_key_iv, - & (wrapped_key.front()), - &wrapped_key_length)); - s.close(); - testTearDown(); + OEMCrypto_RewrapDeviceRSAKey( + s.session_id(), message_ptr, sizeof(MessageData), &signature[0], + signature.size(), &encrypted.nonce, encrypted.rsa_key, + encrypted.rsa_key_length, encrypted.rsa_key_iv, + &(wrapped_key.front()), &wrapped_key_length)); } TEST_F(DISABLED_TestKeybox, CertificateProvisionBadRSAKey) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); struct RSAPrivateKeyMessage encrypted; std::vector signature; s.MakeRSACertificate(&encrypted, &signature, kSign_RSASSA_PSS); vector wrapped_key; + const uint8_t* message_ptr = reinterpret_cast(&encrypted); size_t wrapped_key_length = 0; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, - OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr, - sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, - encrypted.rsa_key, - encrypted.rsa_key_length, - encrypted.rsa_key_iv, NULL, - &wrapped_key_length)); + OEMCrypto_RewrapDeviceRSAKey( + s.session_id(), message_ptr, sizeof(MessageData), &signature[0], + signature.size(), &encrypted.nonce, encrypted.rsa_key, + encrypted.rsa_key_length, encrypted.rsa_key_iv, NULL, + &wrapped_key_length)); wrapped_key.clear(); wrapped_key.resize(wrapped_key_length); encrypted.rsa_key[1] ^= 42; // Almost surely a bad key. ASSERT_NE(OEMCrypto_SUCCESS, - OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr, - sizeof(encrypted), &signature[0], - signature.size(), &encrypted.nonce, - encrypted.rsa_key, - encrypted.rsa_key_length, - encrypted.rsa_key_iv, - & (wrapped_key.front()), - &wrapped_key_length)); - s.close(); - testTearDown(); + OEMCrypto_RewrapDeviceRSAKey( + s.session_id(), message_ptr, sizeof(MessageData), &signature[0], + signature.size(), &encrypted.nonce, encrypted.rsa_key, + encrypted.rsa_key_length, encrypted.rsa_key_iv, + &(wrapped_key.front()), &wrapped_key_length)); } TEST_F(DISABLED_TestKeybox, LoadWrappedRSAKey) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); std::vector wrapped_rsa_key; CreateWrappedRSAKey(&wrapped_rsa_key, kSign_RSASSA_PSS, true); - Session& s = createSession("ONE"); + Session s; s.open(); sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), &wrapped_rsa_key[0], wrapped_rsa_key.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, RSASignature) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); std::vector wrapped_rsa_key; CreateWrappedRSAKey(&wrapped_rsa_key, kSign_RSASSA_PSS, true); - Session& s = createSession("ONE"); + Session s; s.open(); sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), &wrapped_rsa_key[0], wrapped_rsa_key.size()); @@ -3476,94 +2794,41 @@ TEST_F(DISABLED_TestKeybox, RSASignature) { // In the real world, the signature above would just have been used to contact // the license server to get this response. s.PreparePublicKey(); - s.VerifyRSASignature(&licenseRequest[0], licenseRequest.size(), - signature, signature_length, - kSign_RSASSA_PSS); - s.close(); - testTearDown(); - + s.VerifyRSASignature(&licenseRequest[0], licenseRequest.size(), signature, + signature_length, kSign_RSASSA_PSS); delete[] signature; } TEST_F(DISABLED_TestKeybox, LoadRSASessionKey) { - testSetUp(); - InstallKeybox(kDefaultKeybox, true); std::vector wrapped_rsa_key; CreateWrappedRSAKey(&wrapped_rsa_key, kSign_RSASSA_PSS, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.InstallRSASessionTestKey(wrapped_rsa_key); - s.close(); - testTearDown(); } TEST_F(DISABLED_TestKeybox, CertificateDecrypt) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); std::vector wrapped_rsa_key; CreateWrappedRSAKey(&wrapped_rsa_key, kSign_RSASSA_PSS, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.InstallRSASessionTestKey(wrapped_rsa_key); - s.LoadTestKeys(kDuration, 0, 0); - - // Select the key (from FillSimpleMessage) - vector keyId = wvcdm::a2b_hex("000000000000000000000000"); - sts = OEMCrypto_SelectKey(s.session_id(), &keyId[0], keyId.size()); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - - // Set up our expected input and output - vector encryptedData = wvcdm::a2b_hex( - "ec261c115f9d5cda1d5cc7d33c4e37362d1397c89efdd1da5f0065c4848b0462" - "337ba14693735203c9b4184e362439c0cea5e5d1a628425eddf8a6bf9ba901ca" - "46f5a9fd973cffbbe3c276af9919e2e8f6f3f420538b7a0d6dc41487874d96b8" - "efaedb45a689b91beb8c20d36140ad467d9d620b19a5fc6f223b57e0e6a7f913" - "00fd899e5e1b89963e83067ca0912aa5b79df683e2530b55a9645be341bc5f07" - "cffc724790af635c959e2644e51ba7f23bae710eb55a1f2f4e060c3c1dd1387c" - "74415dc880492dd1d5b9ecf3f01de48a44baeb4d3ea5cc4f8d561d0865afcabb" - "fc14a9ab9647e6e31adabb72d792f0c9ba99dc3e9205657d28fc7771d64e6d4b"); - vector encryptionIv = wvcdm::a2b_hex( - "719dbcb253b2ec702bb8c1b1bc2f3bc6"); - vector unencryptedData = wvcdm::a2b_hex( - "19ef4361e16e6825b336e2012ad8ffc9ce176ab2256e1b98aa15b7877bd8c626" - "fa40b2e88373457cbcf4f1b4b9793434a8ac03a708f85974cff01bddcbdd7a8e" - "e33fd160c1d5573bfd8104efd23237edcf28205c3673920553f8dd5e916604b0" - "1082345181dceeae5ea39d829c7f49e1850c460645de33c288723b7ae3d91a17" - "a3f04195cd1945ba7b0f37fef7e82368be30f04365d877766f6d56f67d22a244" - "ef2596d3053f657c1b5d90b64e11797edf1c198a23a7bfc20e4d44c74ae41280" - "a8317f443255f4020eda850ff0954e308f53a634cbce799ae58911bc59ccd6a5" - "de2ac53ee0fa7ea15fc692cc892acc0090865dc57becacddf362a092dfd3040b"); - - // Describe the output - uint8_t outputBuffer[256]; - OEMCrypto_DestBufferDesc destBuffer; - destBuffer.type = OEMCrypto_BufferType_Clear; - destBuffer.buffer.clear.address = outputBuffer; - destBuffer.buffer.clear.max_length = sizeof(outputBuffer); - - // Decrypt the data - sts = OEMCrypto_DecryptCTR(s.session_id(), &encryptedData[0], - encryptedData.size(), true, &encryptionIv[0], 0, - &destBuffer, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer, - unencryptedData.size())); - - s.close(); - testTearDown(); + s.FillSimpleMessage(kDuration, 0, 0); + s.EncryptAndSign(); + s.LoadTestKeys(); + s.TestDecryptCTR(); } // This test attempts to use alternate algorithms for main device certs. class DISABLED_AlternateRSAAlgorithms : public DISABLED_TestKeybox { - protected: void DisallowForbiddenPadding(RSA_Padding_Scheme scheme, size_t size) { OEMCryptoResult sts; - Session& s = createSession("ONE"); + Session s; s.open(); sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), &wrapped_rsa_key_[0], wrapped_rsa_key_.size()); @@ -3580,9 +2845,8 @@ class DISABLED_AlternateRSAAlgorithms : public DISABLED_TestKeybox { &signature_length, scheme); // Allow OEMCrypto to request a full buffer. if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { - printf("XXX It was a short buffer.\n"); ASSERT_NE(static_cast(0), signature_length); - delete [] signature; + delete[] signature; signature = new uint8_t[signature_length]; memset(signature, 0, signature_length); sts = OEMCrypto_GenerateRSASignature(s.session_id(), &licenseRequest[0], @@ -3590,17 +2854,17 @@ class DISABLED_AlternateRSAAlgorithms : public DISABLED_TestKeybox { &signature_length, scheme); } - ASSERT_NE(OEMCrypto_SUCCESS, sts) << "Signed with forbidden padding scheme=" - << scheme << ", size=" << size; - ASSERT_EQ( signature[0], 0); // signature should not be computed. - ASSERT_EQ( memcmp(signature, signature+1, signature_length-1), 0); - s.close(); + ASSERT_NE(OEMCrypto_SUCCESS, sts) + << "Signed with forbidden padding scheme=" << (int)scheme + << ", size=" << (int)size; + ASSERT_EQ(signature[0], 0); // signature should not be computed. + ASSERT_EQ(memcmp(signature, signature + 1, signature_length - 1), 0); delete[] signature; } void TestSignature(RSA_Padding_Scheme scheme, size_t size) { OEMCryptoResult sts; - Session& s = createSession("ONE"); + Session s; s.open(); sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), &wrapped_rsa_key_[0], wrapped_rsa_key_.size()); @@ -3620,27 +2884,25 @@ class DISABLED_AlternateRSAAlgorithms : public DISABLED_TestKeybox { licenseRequest.size(), signature, &signature_length, scheme); - ASSERT_EQ(OEMCrypto_SUCCESS, sts) << "Failed to sign with padding scheme=" - << scheme << ", size=" << size; + ASSERT_EQ(OEMCrypto_SUCCESS, sts) + << "Failed to sign with padding scheme=" << (int)scheme + << ", size=" << (int)size; s.PreparePublicKey(); - s.VerifyRSASignature(&licenseRequest[0], licenseRequest.size(), - signature, signature_length, scheme); - s.close(); + s.VerifyRSASignature(&licenseRequest[0], licenseRequest.size(), signature, + signature_length, scheme); delete[] signature; } void DisallowDeriveKeys() { OEMCryptoResult sts; - Session& s = createSession("ONE"); + Session s; s.open(); sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), &wrapped_rsa_key_[0], wrapped_rsa_key_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, sts); s.DisallowDeriveKeys(); - s.close(); } - void LoadWithAllowedSchemes(uint32_t schemes, bool force) { InstallKeybox(kDefaultKeybox, true); CreateWrappedRSAKey(&wrapped_rsa_key_, schemes, force); @@ -3652,14 +2914,11 @@ class DISABLED_AlternateRSAAlgorithms : public DISABLED_TestKeybox { }; TEST_F(DISABLED_AlternateRSAAlgorithms, DisallowForbiddenPadding) { - testSetUp(); LoadWithAllowedSchemes(kSign_RSASSA_PSS, true); // Use default padding scheme DisallowForbiddenPadding(kSign_PKCS1_Block1, 50); - testTearDown(); } TEST_F(DISABLED_AlternateRSAAlgorithms, TestSignaturePKCS1) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { cout << "===============================================================\n" @@ -3675,11 +2934,9 @@ TEST_F(DISABLED_AlternateRSAAlgorithms, TestSignaturePKCS1) { << "== This device does not load x509 Certs! ===\n" << "===============================================================\n"; } - testTearDown(); } TEST_F(DISABLED_AlternateRSAAlgorithms, TestSignatureBoth) { - testSetUp(); LoadWithAllowedSchemes(kSign_RSASSA_PSS | kSign_PKCS1_Block1, false); if (key_loaded_) { DisallowDeriveKeys(); @@ -3688,15 +2945,12 @@ TEST_F(DISABLED_AlternateRSAAlgorithms, TestSignatureBoth) { TestSignature(kSign_PKCS1_Block1, 50); DisallowForbiddenPadding(kSign_PKCS1_Block1, 84); } - testTearDown(); } // This tests attempts to use alternate algorithms for main device certs. class DISABLED_AlternateRSAKey : public DISABLED_TestKeybox { - protected: - - vector encode(uint8_t type, const vector &substring) { + vector encode(uint8_t type, const vector& substring) { vector result; result.push_back(type); if (substring.size() < 0x80) { @@ -3715,7 +2969,7 @@ class DISABLED_AlternateRSAKey : public DISABLED_TestKeybox { result.insert(result.end(), substring.begin(), substring.end()); return result; } - vector concat(const vector &a, const vector &b) { + vector concat(const vector& a, const vector& b) { vector result = a; result.insert(result.end(), b.begin(), b.end()); return result; @@ -3723,116 +2977,113 @@ class DISABLED_AlternateRSAKey : public DISABLED_TestKeybox { void BuildRSAKey() { vector field_n = - encode(0x02, - wvcdm::a2b_hex( - "df271fd25f8644496b0c81be4bd50297" - "ef099b002a6fd67727eb449cea566ed6" - "a3981a71312a141cabc9815c1209e320" - "a25b32464e9999f18ca13a9fd3892558" - "f9e0adefdd3650dd23a3f036d60fe398" - "843706a40b0b8462c8bee3bce12f1f28" - "60c2444cdc6a44476a75ff4aa24273cc" - "be3bf80248465f8ff8c3a7f3367dfc0d" - "f5b6509a4f82811cedd81cdaaa73c491" - "da412170d544d4ba96b97f0afc806549" - "8d3a49fd910992a1f0725be24f465cfe" - "7e0eabf678996c50bc5e7524abf73f15" - "e5bef7d518394e3138ce4944506aaaaf" - "3f9b236dcab8fc00f87af596fdc3d9d6" - "c75cd508362fae2cbeddcc4c7450b17b" - "776c079ecca1f256351a43b97dbe2153")); - vector field_e = - encode(0x02, wvcdm::a2b_hex( "010001")); + encode(0x02, wvcdm::a2b_hex( + "df271fd25f8644496b0c81be4bd50297" + "ef099b002a6fd67727eb449cea566ed6" + "a3981a71312a141cabc9815c1209e320" + "a25b32464e9999f18ca13a9fd3892558" + "f9e0adefdd3650dd23a3f036d60fe398" + "843706a40b0b8462c8bee3bce12f1f28" + "60c2444cdc6a44476a75ff4aa24273cc" + "be3bf80248465f8ff8c3a7f3367dfc0d" + "f5b6509a4f82811cedd81cdaaa73c491" + "da412170d544d4ba96b97f0afc806549" + "8d3a49fd910992a1f0725be24f465cfe" + "7e0eabf678996c50bc5e7524abf73f15" + "e5bef7d518394e3138ce4944506aaaaf" + "3f9b236dcab8fc00f87af596fdc3d9d6" + "c75cd508362fae2cbeddcc4c7450b17b" + "776c079ecca1f256351a43b97dbe2153")); + vector field_e = encode(0x02, wvcdm::a2b_hex("010001")); vector field_d = encode(0x02, wvcdm::a2b_hex( - "5bd910257830dce17520b03441a51a8c" - "ab94020ac6ecc252c808f3743c95b7c8" - "3b8c8af1a5014346ebc4242cdfb5d718" - "e30a733e71f291e4d473b61bfba6daca" - "ed0a77bd1f0950ae3c91a8f901118825" - "89e1d62765ee671e7baeea309f64d447" - "bbcfa9ea12dce05e9ea8939bc5fe6108" - "581279c982b308794b3448e7f7b95229" - "2df88c80cb40142c4b5cf5f8ddaa0891" - "678d610e582fcb880f0d707caf47d09a" - "84e14ca65841e5a3abc5e9dba94075a9" - "084341f0edad9b68e3b8e082b80b6e6e" - "8a0547b44fb5061b6a9131603a5537dd" - "abd01d8e863d8922e9aa3e4bfaea0b39" - "d79283ad2cbc8a59cce7a6ecf4e4c81e" - "d4c6591c807defd71ab06866bb5e7745")); + "5bd910257830dce17520b03441a51a8c" + "ab94020ac6ecc252c808f3743c95b7c8" + "3b8c8af1a5014346ebc4242cdfb5d718" + "e30a733e71f291e4d473b61bfba6daca" + "ed0a77bd1f0950ae3c91a8f901118825" + "89e1d62765ee671e7baeea309f64d447" + "bbcfa9ea12dce05e9ea8939bc5fe6108" + "581279c982b308794b3448e7f7b95229" + "2df88c80cb40142c4b5cf5f8ddaa0891" + "678d610e582fcb880f0d707caf47d09a" + "84e14ca65841e5a3abc5e9dba94075a9" + "084341f0edad9b68e3b8e082b80b6e6e" + "8a0547b44fb5061b6a9131603a5537dd" + "abd01d8e863d8922e9aa3e4bfaea0b39" + "d79283ad2cbc8a59cce7a6ecf4e4c81e" + "d4c6591c807defd71ab06866bb5e7745")); vector field_p = encode(0x02, wvcdm::a2b_hex( - "f44f5e4246391f482b2f5296e3602eb3" - "4aa136427710f7c0416d403fd69d4b29" - "130cfebef34e885abdb1a8a0a5f0e9b5" - "c33e1fc3bfc285b1ae17e40cc67a1913" - "dd563719815ebaf8514c2a7aa0018e63" - "b6c631dc315a46235716423d11ff5803" - "4e610645703606919f5c7ce2660cd148" - "bd9efc123d9c54b6705590d006cfcf3f")); + "f44f5e4246391f482b2f5296e3602eb3" + "4aa136427710f7c0416d403fd69d4b29" + "130cfebef34e885abdb1a8a0a5f0e9b5" + "c33e1fc3bfc285b1ae17e40cc67a1913" + "dd563719815ebaf8514c2a7aa0018e63" + "b6c631dc315a46235716423d11ff5803" + "4e610645703606919f5c7ce2660cd148" + "bd9efc123d9c54b6705590d006cfcf3f")); vector field_q = encode(0x02, wvcdm::a2b_hex( - "e9d49841e0e0a6ad0d517857133e36dc" - "72c1bdd90f9174b52e26570f373640f1" - "c185e7ea8e2ed7f1e4ebb951f70a5802" - "3633b0097aec67c6dcb800fc1a67f9bb" - "0563610f08ebc8746ad129772136eb1d" - "daf46436450d318332a84982fe5d28db" - "e5b3e912407c3e0e03100d87d436ee40" - "9eec1cf85e80aba079b2e6106b97bced")); + "e9d49841e0e0a6ad0d517857133e36dc" + "72c1bdd90f9174b52e26570f373640f1" + "c185e7ea8e2ed7f1e4ebb951f70a5802" + "3633b0097aec67c6dcb800fc1a67f9bb" + "0563610f08ebc8746ad129772136eb1d" + "daf46436450d318332a84982fe5d28db" + "e5b3e912407c3e0e03100d87d436ee40" + "9eec1cf85e80aba079b2e6106b97bced")); vector field_exp1 = encode(0x02, wvcdm::a2b_hex( - "ed102acdb26871534d1c414ecad9a4d7" - "32fe95b10eea370da62f05de2c393b1a" - "633303ea741b6b3269c97f704b352702" - "c9ae79922f7be8d10db67f026a8145de" - "41b30c0a42bf923bac5f7504c248604b" - "9faa57ed6b3246c6ba158e36c644f8b9" - "548fcf4f07e054a56f768674054440bc" - "0dcbbc9b528f64a01706e05b0b91106f")); + "ed102acdb26871534d1c414ecad9a4d7" + "32fe95b10eea370da62f05de2c393b1a" + "633303ea741b6b3269c97f704b352702" + "c9ae79922f7be8d10db67f026a8145de" + "41b30c0a42bf923bac5f7504c248604b" + "9faa57ed6b3246c6ba158e36c644f8b9" + "548fcf4f07e054a56f768674054440bc" + "0dcbbc9b528f64a01706e05b0b91106f")); vector field_exp2 = encode(0x02, wvcdm::a2b_hex( - "6827924a85e88b55ba00f8219128bd37" - "24c6b7d1dfe5629ef197925fecaff5ed" - "b9cdf3a7befd8ea2e8dd3707138b3ff8" - "7c3c39c57f439e562e2aa805a39d7cd7" - "9966d2ece7845f1dbc16bee99999e4d0" - "bf9eeca45fcda8a8500035fe6b5f03bc" - "2f6d1bfc4d4d0a3723961af0cdce4a01" - "eec82d7f5458ec19e71b90eeef7dff61")); + "6827924a85e88b55ba00f8219128bd37" + "24c6b7d1dfe5629ef197925fecaff5ed" + "b9cdf3a7befd8ea2e8dd3707138b3ff8" + "7c3c39c57f439e562e2aa805a39d7cd7" + "9966d2ece7845f1dbc16bee99999e4d0" + "bf9eeca45fcda8a8500035fe6b5f03bc" + "2f6d1bfc4d4d0a3723961af0cdce4a01" + "eec82d7f5458ec19e71b90eeef7dff61")); vector field_invq = encode(0x02, wvcdm::a2b_hex( - "57b73888d183a99a6307422277551a3d" - "9e18adf06a91e8b55ceffef9077c8496" - "948ecb3b16b78155cb2a3a57c119d379" - "951c010aa635edcf62d84c5a122a8d67" - "ab5fa9e5a4a8772a1e943bafc70ae3a4" - "c1f0f3a4ddffaefd1892c8cb33bb0d0b" - "9590e963a69110fb34db7b906fc4ba28" - "36995aac7e527490ac952a02268a4f18")); + "57b73888d183a99a6307422277551a3d" + "9e18adf06a91e8b55ceffef9077c8496" + "948ecb3b16b78155cb2a3a57c119d379" + "951c010aa635edcf62d84c5a122a8d67" + "ab5fa9e5a4a8772a1e943bafc70ae3a4" + "c1f0f3a4ddffaefd1892c8cb33bb0d0b" + "9590e963a69110fb34db7b906fc4ba28" + "36995aac7e527490ac952a02268a4f18")); // Header of rsa key is constant. - encoded_key_ = - wvcdm::a2b_hex( - // 0x02 0x01 0x00 == integer, size 1 byte, value = 0 (field=version) - "020100" - // 0x30, sequence, size = d = 13 (field=pkeyalg) AlgorithmIdentifier - "300d" - // 0x06 = object identifier. length = 9 - // (this should be 1.2.840.113549.1.1.1) (field=algorithm) - "0609" - "2a" // 1*0x40 + 2 = 42 = 0x2a. - "8648" // 840 = 0x348, 0x03 *2 + 0x80 + (0x48>>15) = 0x86. - // 0x48 -> 0x48 - "86f70d" // 113549 = 0x1668d -> (110 , 1110111, 0001101) - // -> (0x80+0x06, 0x80+0x77, 0x0d) - "01" // 1 - "01" // 1 - "01" // 1 - "05" // null object. (field=parameter?) - "00" // size of null object - ); + encoded_key_ = wvcdm::a2b_hex( + // 0x02 0x01 0x00 == integer, size 1 byte, value = 0 (field=version) + "020100" + // 0x30, sequence, size = d = 13 (field=pkeyalg) AlgorithmIdentifier + "300d" + // 0x06 = object identifier. length = 9 + // (this should be 1.2.840.113549.1.1.1) (field=algorithm) + "0609" + "2a" // 1*0x40 + 2 = 42 = 0x2a. + "8648" // 840 = 0x348, 0x03 *2 + 0x80 + (0x48>>15) = 0x86. + // 0x48 -> 0x48 + "86f70d" // 113549 = 0x1668d -> (110 , 1110111, 0001101) + // -> (0x80+0x06, 0x80+0x77, 0x0d) + "01" // 1 + "01" // 1 + "01" // 1 + "05" // null object. (field=parameter?) + "00" // size of null object + ); vector pkey = wvcdm::a2b_hex("020100"); // integer, version = 0. pkey = concat(pkey, field_n); @@ -3847,12 +3098,12 @@ class DISABLED_AlternateRSAKey : public DISABLED_TestKeybox { pkey = encode(0x04, pkey); encoded_key_ = concat(encoded_key_, pkey); - encoded_key_ = encode(0x30, encoded_key_); // 0x30=sequence + encoded_key_ = encode(0x30, encoded_key_); // 0x30=sequence } void DisallowForbiddenPadding(RSA_Padding_Scheme scheme, size_t size) { OEMCryptoResult sts; - Session& s = createSession("ONE"); + Session s; s.open(); sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), &wrapped_rsa_key_[0], wrapped_rsa_key_.size()); @@ -3869,9 +3120,8 @@ class DISABLED_AlternateRSAKey : public DISABLED_TestKeybox { &signature_length, scheme); // Allow OEMCrypto to request a full buffer. if (sts == OEMCrypto_ERROR_SHORT_BUFFER) { - printf("XXX It was a short buffer.\n"); ASSERT_NE(static_cast(0), signature_length); - delete [] signature; + delete[] signature; signature = new uint8_t[signature_length]; memset(signature, 0, signature_length); sts = OEMCrypto_GenerateRSASignature(s.session_id(), &licenseRequest[0], @@ -3879,20 +3129,19 @@ class DISABLED_AlternateRSAKey : public DISABLED_TestKeybox { &signature_length, scheme); } - ASSERT_NE(OEMCrypto_SUCCESS, sts) << "Signed with forbidden padding scheme=" - << scheme << ", size=" << size; - ASSERT_EQ( signature[0], 0); // signature should not be computed. - ASSERT_EQ( memcmp(signature, signature+1, signature_length-1), 0); - s.close(); + ASSERT_NE(OEMCrypto_SUCCESS, sts) + << "Signed with forbidden padding scheme=" << (int)scheme + << ", size=" << (int)size; + ASSERT_EQ(signature[0], 0); // signature should not be computed. + ASSERT_EQ(memcmp(signature, signature + 1, signature_length - 1), 0); delete[] signature; } // This is used to test a signature from the file pkcs1v15sign-vectors.txt. - void TestSignature(RSA_Padding_Scheme scheme, - const vector &message, - const vector &correct_signature ) { + void TestSignature(RSA_Padding_Scheme scheme, const vector& message, + const vector& correct_signature) { OEMCryptoResult sts; - Session& s = createSession("ONE"); + Session s; s.open(); sts = OEMCrypto_LoadDeviceRSAKey(s.session_id(), &wrapped_rsa_key_[0], wrapped_rsa_key_.size()); @@ -3902,21 +3151,20 @@ class DISABLED_AlternateRSAKey : public DISABLED_TestKeybox { // test must do that also. uint8_t hash[SHA_DIGEST_LENGTH]; if (!SHA1(&message[0], message.size(), hash)) { - printf("error creating signature hash.]"); dump_openssl_error(); - ASSERT_TRUE(false); + ASSERT_TRUE(false) << "openssl error creating SHA1 hash."; } // The application will prepend the digest info to the hash. // SHA-1 digest info prefix = 0x30 0x21 0x30 ... vector digest = wvcdm::a2b_hex("3021300906052b0e03021a05000414"); - digest.insert(digest.end(), hash, hash+SHA_DIGEST_LENGTH); + digest.insert(digest.end(), hash, hash + SHA_DIGEST_LENGTH); // OEMCrypto will apply the padding, and encrypt to generate the signature. size_t signature_length = 0; sts = OEMCrypto_GenerateRSASignature(s.session_id(), &digest[0], - digest.size(), NULL, - &signature_length, scheme); + digest.size(), NULL, &signature_length, + scheme); ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts); ASSERT_NE(static_cast(0), signature_length); @@ -3925,8 +3173,9 @@ class DISABLED_AlternateRSAKey : public DISABLED_TestKeybox { digest.size(), signature, &signature_length, scheme); - ASSERT_EQ(OEMCrypto_SUCCESS, sts) << "Failed to sign with padding scheme=" - << scheme << ", size=" << message.size(); + ASSERT_EQ(OEMCrypto_SUCCESS, sts) + << "Failed to sign with padding scheme=" << (int)scheme + << ", size=" << (int)message.size(); s.PreparePublicKey(&encoded_key_[0], encoded_key_.size()); // Verify that the signature matches the official test vector. @@ -3935,20 +3184,18 @@ class DISABLED_AlternateRSAKey : public DISABLED_TestKeybox { // Also verify that our verification algorithm agrees. This is not needed // to test OEMCrypto, but it does verify that this test is valid. - s.VerifyRSASignature(&digest[0], digest.size(), - signature, signature_length, scheme); - s.VerifyRSASignature(&digest[0], digest.size(), - &correct_signature[0], + s.VerifyRSASignature(&digest[0], digest.size(), signature, signature_length, + scheme); + s.VerifyRSASignature(&digest[0], digest.size(), &correct_signature[0], correct_signature.size(), scheme); - s.close(); delete[] signature; } void LoadWithAllowedSchemes(uint32_t schemes, bool force) { BuildRSAKey(); InstallKeybox(kDefaultKeybox, true); - CreateWrappedRSAKey(&wrapped_rsa_key_, schemes, force, - &encoded_key_[0], encoded_key_.size()); + CreateWrappedRSAKey(&wrapped_rsa_key_, schemes, force, &encoded_key_[0], + encoded_key_.size()); key_loaded_ = (wrapped_rsa_key_.size() > 0); } @@ -3959,7 +3206,6 @@ class DISABLED_AlternateRSAKey : public DISABLED_TestKeybox { // # PKCS#1 v1.5 Signature Example 15.1 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_1) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -3997,11 +3243,9 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_1) { "5df3eed21e7792d249480487f3655261"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.2 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_2) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4034,12 +3278,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_2) { "9500c9708500a5972bd54f72cf8db0c8"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.3 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_3) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4078,12 +3320,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_3) { "ed74dcbee811dbf6575941f08a6523b8"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); }; // # PKCS#1 v1.5 Signature Example 15.4 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_4) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4110,16 +3350,13 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_4) { "97643c7e0740de016355453d6c95ae72"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.5 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_5) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { - vector message = wvcdm::a2b_hex( - "bda3a1c79059eae598308d3df609"); + vector message = wvcdm::a2b_hex("bda3a1c79059eae598308d3df609"); vector signature = wvcdm::a2b_hex( "a156176cb96777c7fb96105dbd913bc4" "f74054f6807c6008a1a956ea92c1f81c" @@ -4139,12 +3376,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_5) { "1647106b490c729d54a8fe2802a6d126"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.6 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_6) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4174,12 +3409,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_6) { "1f0557205f5b0bd7ffe9c850f396d7c4"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.7 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_7) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4210,12 +3443,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_7) { "4e6d886779d64594d369158fdbc1f694"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.8 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_8) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4252,12 +3483,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_8) { "861ca18987227d37b42b584a8357cb04"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.9 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_9) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4292,12 +3521,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_9) { "10f11e01741471bbfd6518a175734575"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.10 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_10) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4325,12 +3552,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_10) { "443b97e71718970e2f4bf62023e95b67"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.11 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_11) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4362,12 +3587,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_11) { "8ede57acbc5bd4deae74a56f86671de2"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.12 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_12) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4406,12 +3629,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_12) { "606ea178150b1efc15856934c7255cfe"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.13 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_13) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4438,12 +3659,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_13) { "81c46de6cd76ea8a0c8f6fe331712d24"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.14 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_14) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4477,12 +3696,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_14) { "bdf2394b749cf164480df1ab6880273b"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.15 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_15) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4519,12 +3736,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_15) { "59070890ee18ff658fa4d741969d70a5"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.16 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_16) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4563,12 +3778,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_16) { "2d0befe1545150fc47b876de09b00a94"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.17 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_17) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4595,12 +3808,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_17) { "68fb7bef4f697c5ea2b35062f48a36dd"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.18 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_18) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4628,12 +3839,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_18) { "5558fcf260b1f0e554ebb3df3cfcb958"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.19 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_19) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4668,12 +3877,10 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_19) { "ae47e6d9395c184b93a374c671faa2ce"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } // # PKCS#1 v1.5 Signature Example 15.20 TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_20) { - testSetUp(); LoadWithAllowedSchemes(kSign_PKCS1_Block1, false); if (key_loaded_) { vector message = wvcdm::a2b_hex( @@ -4708,138 +3915,112 @@ TEST_F(DISABLED_AlternateRSAKey, TestSignaturePKCS1_15_20) { "d00acc10407e5df58dd1c3c5c559a506"); TestSignature(kSign_PKCS1_Block1, message, signature); } - testTearDown(); } - class DISABLED_GenericDRMTest : public DISABLED_TestKeybox { protected: - MessageData message_data_; - static const size_t kBufferSize = 160; // multiple of encryption block size. uint8_t clear_buffer_[kBufferSize]; uint8_t encrypted_buffer_[kBufferSize]; uint8_t iv_[wvcdm::KEY_IV_SIZE]; - void MakeFourKeys(Session* s) { - s->FillSimpleMessage(&message_data_, kDuration, 0, 0); - message_data_.keys[0].control.control_bits = htonl(wvoec_mock::kControlAllowEncrypt); - message_data_.keys[1].control.control_bits = htonl(wvoec_mock::kControlAllowDecrypt); - message_data_.keys[2].control.control_bits = htonl(wvoec_mock::kControlAllowSign); - message_data_.keys[3].control.control_bits = htonl(wvoec_mock::kControlAllowVerify); + void MakeFourKeys(Session* s, uint32_t duration = kDuration, + uint32_t control = 0, uint32_t nonce = 0, + const std::string& pst = "") { + s->FillSimpleMessage(duration, control, nonce, pst); + s->license().keys[0].control.control_bits |= htonl(wvoec_mock::kControlAllowEncrypt); + s->license().keys[1].control.control_bits |= htonl(wvoec_mock::kControlAllowDecrypt); + s->license().keys[2].control.control_bits |= htonl(wvoec_mock::kControlAllowSign); + s->license().keys[3].control.control_bits |= htonl(wvoec_mock::kControlAllowVerify); - message_data_.keys[2].key_data_length = wvcdm::MAC_KEY_SIZE; - message_data_.keys[3].key_data_length = wvcdm::MAC_KEY_SIZE; + s->license().keys[2].key_data_length = wvcdm::MAC_KEY_SIZE; + s->license().keys[3].key_data_length = wvcdm::MAC_KEY_SIZE; - for(size_t i=0; i < kBufferSize; i++) { - clear_buffer_[i] = 1 + i %250; + for (size_t i = 0; i < kBufferSize; i++) { + clear_buffer_[i] = 1 + i % 250; } - for(size_t i=0; i < wvcdm::KEY_IV_SIZE; i++) { + for (size_t i = 0; i < wvcdm::KEY_IV_SIZE; i++) { iv_[i] = i; } - } - void LoadFourKeys(Session* s) { - MessageData encrypted; - s->EncryptMessage(message_data_, &encrypted); - std::vector signature; - s->ServerSignMessage(encrypted, &signature); - OEMCrypto_KeyObject key_array[kNumKeys]; - const uint8_t* message_ptr = reinterpret_cast(&encrypted); - s->FillKeyArray(encrypted, key_array); - - OEMCryptoResult sts = OEMCrypto_LoadKeys(s->session_id(), - message_ptr, sizeof(encrypted), - &signature[0], signature.size(), - encrypted.mac_key_iv, - encrypted.mac_keys, - kNumKeys, key_array, NULL, 0); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - } - - void EncryptBuffer(unsigned int key_index, const uint8_t* in_buffer, - uint8_t *out_buffer) { - + void EncryptBuffer(Session* s, unsigned int key_index, + const uint8_t* in_buffer, uint8_t* out_buffer) { AES_KEY aes_key; - ASSERT_EQ(0, AES_set_encrypt_key(message_data_.keys[key_index].key_data, + ASSERT_EQ(0, AES_set_encrypt_key(s->license().keys[key_index].key_data, AES_BLOCK_SIZE * 8, &aes_key)); uint8_t iv_buffer[wvcdm::KEY_IV_SIZE]; memcpy(iv_buffer, iv_, wvcdm::KEY_IV_SIZE); - AES_cbc_encrypt(in_buffer, out_buffer, kBufferSize, - &aes_key, iv_buffer, AES_ENCRYPT); + AES_cbc_encrypt(in_buffer, out_buffer, kBufferSize, &aes_key, iv_buffer, + AES_ENCRYPT); } // Sign the buffer with the specified key. - void SignBuffer(unsigned int key_index, const uint8_t* in_buffer, + void SignBuffer(Session* s, unsigned int key_index, const uint8_t* in_buffer, uint8_t signature[SHA256_DIGEST_LENGTH]) { unsigned int md_len = SHA256_DIGEST_LENGTH; - HMAC(EVP_sha256(), message_data_.keys[key_index].key_data, - SHA256_DIGEST_LENGTH, in_buffer, kBufferSize, signature, &md_len); + HMAC(EVP_sha256(), s->license().keys[key_index].key_data, + wvcdm::MAC_KEY_SIZE, in_buffer, kBufferSize, signature, &md_len); } void BadEncrypt(unsigned int key_index, OEMCrypto_Algorithm algorithm, size_t buffer_length) { OEMCryptoResult sts; InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); MakeFourKeys(&s); - LoadFourKeys(&s); + s.EncryptAndSign(); + s.LoadTestKeys(); uint8_t expected_encrypted[kBufferSize]; - EncryptBuffer(key_index, clear_buffer_, expected_encrypted); - sts = OEMCrypto_SelectKey(s.session_id(), - message_data_.keys[key_index].key_id, - kTestKeyIdLength); + EncryptBuffer(&s, key_index, clear_buffer_, expected_encrypted); + sts = OEMCrypto_SelectKey( + s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength); ASSERT_EQ(OEMCrypto_SUCCESS, sts); uint8_t encrypted[kBufferSize]; sts = OEMCrypto_Generic_Encrypt(s.session_id(), clear_buffer_, - buffer_length, iv_, - algorithm, encrypted); + buffer_length, iv_, algorithm, encrypted); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NE(0, memcmp(encrypted, expected_encrypted, buffer_length)); - s.close(); } void BadDecrypt(unsigned int key_index, OEMCrypto_Algorithm algorithm, size_t buffer_length) { OEMCryptoResult sts; InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); MakeFourKeys(&s); - LoadFourKeys(&s); + s.EncryptAndSign(); + s.LoadTestKeys(); uint8_t encrypted[kBufferSize]; - EncryptBuffer(key_index, clear_buffer_, encrypted); - sts = OEMCrypto_SelectKey(s.session_id(), - message_data_.keys[key_index].key_id, - kTestKeyIdLength); + EncryptBuffer(&s, key_index, clear_buffer_, encrypted); + sts = OEMCrypto_SelectKey( + s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength); ASSERT_EQ(OEMCrypto_SUCCESS, sts); uint8_t resultant[kBufferSize]; - sts = OEMCrypto_Generic_Decrypt(s.session_id(), encrypted, - buffer_length, iv_, - algorithm, resultant); + sts = OEMCrypto_Generic_Decrypt(s.session_id(), encrypted, buffer_length, + iv_, algorithm, resultant); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NE(0, memcmp(clear_buffer_, resultant, buffer_length)); - s.close(); } void BadSign(unsigned int key_index, OEMCrypto_Algorithm algorithm) { OEMCryptoResult sts; InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); MakeFourKeys(&s); - LoadFourKeys(&s); + s.EncryptAndSign(); + s.LoadTestKeys(); uint8_t expected_signature[SHA256_DIGEST_LENGTH]; - SignBuffer(key_index, clear_buffer_, expected_signature); + SignBuffer(&s, key_index, clear_buffer_, expected_signature); - sts = OEMCrypto_SelectKey(s.session_id(), - message_data_.keys[key_index].key_id, - kTestKeyIdLength); + sts = OEMCrypto_SelectKey( + s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength); ASSERT_EQ(OEMCrypto_SUCCESS, sts); size_t signature_length = (size_t)SHA256_DIGEST_LENGTH; uint8_t signature[SHA256_DIGEST_LENGTH]; @@ -4847,98 +4028,87 @@ class DISABLED_GenericDRMTest : public DISABLED_TestKeybox { algorithm, signature, &signature_length); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NE(0, memcmp(signature, expected_signature, SHA256_DIGEST_LENGTH)); - s.close(); } void BadVerify(unsigned int key_index, OEMCrypto_Algorithm algorithm, size_t signature_size, bool alter_data) { OEMCryptoResult sts; InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); MakeFourKeys(&s); - LoadFourKeys(&s); + s.EncryptAndSign(); + s.LoadTestKeys(); uint8_t signature[SHA256_DIGEST_LENGTH]; - SignBuffer(key_index, clear_buffer_, signature); - if( alter_data ) { + SignBuffer(&s, key_index, clear_buffer_, signature); + if (alter_data) { signature[0] ^= 42; } - sts = OEMCrypto_SelectKey(s.session_id(), - message_data_.keys[key_index].key_id, - kTestKeyIdLength); + sts = OEMCrypto_SelectKey( + s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength); ASSERT_EQ(OEMCrypto_SUCCESS, sts); sts = OEMCrypto_Generic_Verify(s.session_id(), clear_buffer_, kBufferSize, - algorithm,signature, - signature_size); + algorithm, signature, signature_size); ASSERT_NE(OEMCrypto_SUCCESS, sts); - s.close(); } }; TEST_F(DISABLED_GenericDRMTest, GenericKeyLoad) { - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); MakeFourKeys(&s); - LoadFourKeys(&s); - - s.close(); - testTearDown(); + s.EncryptAndSign(); + s.LoadTestKeys(); } TEST_F(DISABLED_GenericDRMTest, GenericKeyEncrypt) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); MakeFourKeys(&s); - LoadFourKeys(&s); + s.EncryptAndSign(); + s.LoadTestKeys(); unsigned int key_index = 0; uint8_t expected_encrypted[kBufferSize]; - EncryptBuffer(key_index, clear_buffer_, expected_encrypted); - sts = OEMCrypto_SelectKey(s.session_id(), - message_data_.keys[key_index].key_id, + EncryptBuffer(&s, key_index, clear_buffer_, expected_encrypted); + sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength); ASSERT_EQ(OEMCrypto_SUCCESS, sts); uint8_t encrypted[kBufferSize]; - sts = OEMCrypto_Generic_Encrypt(s.session_id(), clear_buffer_, kBufferSize, iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, encrypted); + sts = + OEMCrypto_Generic_Encrypt(s.session_id(), clear_buffer_, kBufferSize, iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, encrypted); ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_EQ(0, memcmp(encrypted, expected_encrypted, kBufferSize)); - s.close(); - testTearDown(); } - TEST_F(DISABLED_GenericDRMTest, GenericKeyBadEncrypt) { - testSetUp(); BadEncrypt(0, OEMCrypto_HMAC_SHA256, kBufferSize); - BadEncrypt(0, OEMCrypto_AES_CBC_128_NO_PADDING, kBufferSize-10); + BadEncrypt(0, OEMCrypto_AES_CBC_128_NO_PADDING, kBufferSize - 10); BadEncrypt(1, OEMCrypto_AES_CBC_128_NO_PADDING, kBufferSize); BadEncrypt(2, OEMCrypto_AES_CBC_128_NO_PADDING, kBufferSize); BadEncrypt(3, OEMCrypto_AES_CBC_128_NO_PADDING, kBufferSize); - testTearDown(); } TEST_F(DISABLED_GenericDRMTest, GenericKeyDecrypt) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); MakeFourKeys(&s); - LoadFourKeys(&s); + s.EncryptAndSign(); + s.LoadTestKeys(); unsigned int key_index = 1; uint8_t encrypted[kBufferSize]; - EncryptBuffer(key_index, clear_buffer_, encrypted); - sts = OEMCrypto_SelectKey(s.session_id(), message_data_.keys[key_index].key_id, + EncryptBuffer(&s, key_index, clear_buffer_, encrypted); + sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength); ASSERT_EQ(OEMCrypto_SUCCESS, sts); uint8_t resultant[kBufferSize]; @@ -4946,26 +4116,23 @@ TEST_F(DISABLED_GenericDRMTest, GenericKeyDecrypt) { OEMCrypto_AES_CBC_128_NO_PADDING, resultant); ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_EQ(0, memcmp(clear_buffer_, resultant, kBufferSize)); - s.close(); - testTearDown(); } TEST_F(DISABLED_GenericDRMTest, GenericSecureToClear) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); MakeFourKeys(&s); - message_data_.keys[1].control.control_bits - |= htonl(wvoec_mock::kControlObserveDataPath - | wvoec_mock::kControlDataPathSecure); - LoadFourKeys(&s); + s.license().keys[1].control.control_bits |= htonl( + wvoec_mock::kControlObserveDataPath | wvoec_mock::kControlDataPathSecure); + s.EncryptAndSign(); + s.LoadTestKeys(); unsigned int key_index = 1; uint8_t encrypted[kBufferSize]; - EncryptBuffer(key_index, clear_buffer_, encrypted); - sts = OEMCrypto_SelectKey(s.session_id(), message_data_.keys[key_index].key_id, + EncryptBuffer(&s, key_index, clear_buffer_, encrypted); + sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength); ASSERT_EQ(OEMCrypto_SUCCESS, sts); uint8_t resultant[kBufferSize]; @@ -4973,35 +4140,30 @@ TEST_F(DISABLED_GenericDRMTest, GenericSecureToClear) { OEMCrypto_AES_CBC_128_NO_PADDING, resultant); ASSERT_NE(OEMCrypto_SUCCESS, sts); ASSERT_NE(0, memcmp(clear_buffer_, resultant, kBufferSize)); - s.close(); - testTearDown(); } - TEST_F(DISABLED_GenericDRMTest, GenericKeyBadDecrypt) { - testSetUp(); BadDecrypt(1, OEMCrypto_HMAC_SHA256, kBufferSize); - BadDecrypt(1, OEMCrypto_AES_CBC_128_NO_PADDING, kBufferSize-10); + BadDecrypt(1, OEMCrypto_AES_CBC_128_NO_PADDING, kBufferSize - 10); BadDecrypt(0, OEMCrypto_AES_CBC_128_NO_PADDING, kBufferSize); BadDecrypt(2, OEMCrypto_AES_CBC_128_NO_PADDING, kBufferSize); BadDecrypt(3, OEMCrypto_AES_CBC_128_NO_PADDING, kBufferSize); - testTearDown(); } TEST_F(DISABLED_GenericDRMTest, GenericKeySign) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); MakeFourKeys(&s); - LoadFourKeys(&s); + s.EncryptAndSign(); + s.LoadTestKeys(); unsigned int key_index = 2; uint8_t expected_signature[SHA256_DIGEST_LENGTH]; - SignBuffer(key_index, clear_buffer_, expected_signature); + SignBuffer(&s, key_index, clear_buffer_, expected_signature); - sts = OEMCrypto_SelectKey(s.session_id(), message_data_.keys[key_index].key_id, + sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength); ASSERT_EQ(OEMCrypto_SUCCESS, sts); size_t gen_signature_length = 0; @@ -5012,49 +4174,42 @@ TEST_F(DISABLED_GenericDRMTest, GenericKeySign) { ASSERT_EQ(static_cast(SHA256_DIGEST_LENGTH), gen_signature_length); uint8_t signature[SHA256_DIGEST_LENGTH]; sts = OEMCrypto_Generic_Sign(s.session_id(), clear_buffer_, kBufferSize, - OEMCrypto_HMAC_SHA256,signature, + OEMCrypto_HMAC_SHA256, signature, &gen_signature_length); ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_EQ(0, memcmp(signature, expected_signature, SHA256_DIGEST_LENGTH)); - s.close(); - testTearDown(); } TEST_F(DISABLED_GenericDRMTest, GenericKeyBadSign) { - testSetUp(); - BadSign(0, OEMCrypto_HMAC_SHA256); // Can't sign with encrypt key. - BadSign(1, OEMCrypto_HMAC_SHA256); // Can't sign with decrypt key. - BadSign(3, OEMCrypto_HMAC_SHA256); // Can't sign with verify key. + BadSign(0, OEMCrypto_HMAC_SHA256); // Can't sign with encrypt key. + BadSign(1, OEMCrypto_HMAC_SHA256); // Can't sign with decrypt key. + BadSign(3, OEMCrypto_HMAC_SHA256); // Can't sign with verify key. BadSign(2, OEMCrypto_AES_CBC_128_NO_PADDING); // Bad signing algorithm. - testTearDown(); } TEST_F(DISABLED_GenericDRMTest, GenericKeyVerify) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); MakeFourKeys(&s); - LoadFourKeys(&s); + s.EncryptAndSign(); + s.LoadTestKeys(); unsigned int key_index = 3; uint8_t signature[SHA256_DIGEST_LENGTH]; - SignBuffer(key_index, clear_buffer_, signature); + SignBuffer(&s, key_index, clear_buffer_, signature); - sts = OEMCrypto_SelectKey(s.session_id(), message_data_.keys[key_index].key_id, + sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength); ASSERT_EQ(OEMCrypto_SUCCESS, sts); sts = OEMCrypto_Generic_Verify(s.session_id(), clear_buffer_, kBufferSize, - OEMCrypto_HMAC_SHA256,signature, + OEMCrypto_HMAC_SHA256, signature, SHA256_DIGEST_LENGTH); ASSERT_EQ(OEMCrypto_SUCCESS, sts); - s.close(); - testTearDown(); } TEST_F(DISABLED_GenericDRMTest, GenericKeyBadVerify) { - testSetUp(); BadVerify(0, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH, false); BadVerify(1, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH, false); BadVerify(2, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH, false); @@ -5062,68 +4217,59 @@ TEST_F(DISABLED_GenericDRMTest, GenericKeyBadVerify) { BadVerify(3, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH - 1, false); BadVerify(3, OEMCrypto_HMAC_SHA256, SHA256_DIGEST_LENGTH + 1, false); BadVerify(3, OEMCrypto_AES_CBC_128_NO_PADDING, SHA256_DIGEST_LENGTH, false); - testTearDown(); } TEST_F(DISABLED_GenericDRMTest, KeyDurationEncrypt) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); - MakeFourKeys(&s); - message_data_.keys[0].control.duration = htonl(kDuration); - message_data_.keys[1].control.duration = htonl(kDuration); - message_data_.keys[2].control.duration = htonl(kDuration); - message_data_.keys[3].control.duration = htonl(kDuration); - LoadFourKeys(&s); + MakeFourKeys(&s, kDuration); + s.EncryptAndSign(); + s.LoadTestKeys(); uint8_t expected_encrypted[kBufferSize]; - EncryptBuffer(0, clear_buffer_, expected_encrypted); + EncryptBuffer(&s, 0, clear_buffer_, expected_encrypted); unsigned int key_index = 0; uint8_t encrypted[kBufferSize]; sleep(kShortSleep); // Should still be valid key. memset(encrypted, 0, kBufferSize); - sts = OEMCrypto_SelectKey(s.session_id(), message_data_.keys[key_index].key_id, + sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength); ASSERT_EQ(OEMCrypto_SUCCESS, sts); - sts = OEMCrypto_Generic_Encrypt(s.session_id(), clear_buffer_, kBufferSize, iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, encrypted); + sts = + OEMCrypto_Generic_Encrypt(s.session_id(), clear_buffer_, kBufferSize, iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, encrypted); ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_EQ(0, memcmp(encrypted, expected_encrypted, kBufferSize)); sleep(kLongSleep); // Should be expired key. memset(encrypted, 0, kBufferSize); - sts = OEMCrypto_Generic_Encrypt(s.session_id(), clear_buffer_, kBufferSize, iv_, - OEMCrypto_AES_CBC_128_NO_PADDING, encrypted); + sts = + OEMCrypto_Generic_Encrypt(s.session_id(), clear_buffer_, kBufferSize, iv_, + OEMCrypto_AES_CBC_128_NO_PADDING, encrypted); ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, sts); ASSERT_NE(0, memcmp(encrypted, expected_encrypted, kBufferSize)); - s.close(); - testTearDown(); } TEST_F(DISABLED_GenericDRMTest, KeyDurationDecrypt) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); - MakeFourKeys(&s); - message_data_.keys[0].control.duration = htonl(kDuration); - message_data_.keys[1].control.duration = htonl(kDuration); - message_data_.keys[2].control.duration = htonl(kDuration); - message_data_.keys[3].control.duration = htonl(kDuration); - LoadFourKeys(&s); + MakeFourKeys(&s, kDuration); + s.EncryptAndSign(); + s.LoadTestKeys(); unsigned int key_index = 1; uint8_t encrypted[kBufferSize]; - EncryptBuffer(key_index, clear_buffer_, encrypted); - sts = OEMCrypto_SelectKey(s.session_id(), message_data_.keys[key_index].key_id, + EncryptBuffer(&s, key_index, clear_buffer_, encrypted); + sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength); ASSERT_EQ(OEMCrypto_SUCCESS, sts); @@ -5143,33 +4289,25 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationDecrypt) { OEMCrypto_AES_CBC_128_NO_PADDING, resultant); ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, sts); ASSERT_NE(0, memcmp(clear_buffer_, resultant, kBufferSize)); - s.close(); - testTearDown(); } TEST_F(DISABLED_GenericDRMTest, KeyDurationSign) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); - MakeFourKeys(&s); - - message_data_.keys[0].control.duration = htonl(kDuration); - message_data_.keys[1].control.duration = htonl(kDuration); - message_data_.keys[2].control.duration = htonl(kDuration); - message_data_.keys[3].control.duration = htonl(kDuration); - - LoadFourKeys(&s); + MakeFourKeys(&s, kDuration); + s.EncryptAndSign(); + s.LoadTestKeys(); unsigned int key_index = 2; uint8_t expected_signature[SHA256_DIGEST_LENGTH]; uint8_t signature[SHA256_DIGEST_LENGTH]; size_t signature_length = SHA256_DIGEST_LENGTH; - SignBuffer(key_index, clear_buffer_, expected_signature); + SignBuffer(&s, key_index, clear_buffer_, expected_signature); - sts = OEMCrypto_SelectKey(s.session_id(), message_data_.keys[key_index].key_id, + sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength); ASSERT_EQ(OEMCrypto_SUCCESS, sts); @@ -5177,7 +4315,7 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationSign) { memset(signature, 0, SHA256_DIGEST_LENGTH); sts = OEMCrypto_Generic_Sign(s.session_id(), clear_buffer_, kBufferSize, - OEMCrypto_HMAC_SHA256,signature, + OEMCrypto_HMAC_SHA256, signature, &signature_length); ASSERT_EQ(OEMCrypto_SUCCESS, sts); ASSERT_EQ(0, memcmp(signature, expected_signature, SHA256_DIGEST_LENGTH)); @@ -5186,52 +4324,42 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationSign) { memset(signature, 0, SHA256_DIGEST_LENGTH); sts = OEMCrypto_Generic_Sign(s.session_id(), clear_buffer_, kBufferSize, - OEMCrypto_HMAC_SHA256,signature, + OEMCrypto_HMAC_SHA256, signature, &signature_length); ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, sts); ASSERT_NE(0, memcmp(signature, expected_signature, SHA256_DIGEST_LENGTH)); - - s.close(); - testTearDown(); } TEST_F(DISABLED_GenericDRMTest, KeyDurationVerify) { OEMCryptoResult sts; - testSetUp(); InstallKeybox(kDefaultKeybox, true); - Session& s = createSession("ONE"); + Session s; s.open(); s.GenerateDerivedKeys(); - MakeFourKeys(&s); - message_data_.keys[0].control.duration = htonl(kDuration); - message_data_.keys[1].control.duration = htonl(kDuration); - message_data_.keys[2].control.duration = htonl(kDuration); - message_data_.keys[3].control.duration = htonl(kDuration); - LoadFourKeys(&s); + MakeFourKeys(&s, kDuration); + s.EncryptAndSign(); + s.LoadTestKeys(); unsigned int key_index = 3; uint8_t signature[SHA256_DIGEST_LENGTH]; - SignBuffer(key_index, clear_buffer_, signature); + SignBuffer(&s, key_index, clear_buffer_, signature); - sts = OEMCrypto_SelectKey(s.session_id(), message_data_.keys[key_index].key_id, + sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[key_index].key_id, kTestKeyIdLength); ASSERT_EQ(OEMCrypto_SUCCESS, sts); sleep(kShortSleep); // Should still be valid key. sts = OEMCrypto_Generic_Verify(s.session_id(), clear_buffer_, kBufferSize, - OEMCrypto_HMAC_SHA256,signature, + OEMCrypto_HMAC_SHA256, signature, SHA256_DIGEST_LENGTH); ASSERT_EQ(OEMCrypto_SUCCESS, sts); sleep(kLongSleep); // Should be expired key. sts = OEMCrypto_Generic_Verify(s.session_id(), clear_buffer_, kBufferSize, - OEMCrypto_HMAC_SHA256,signature, + OEMCrypto_HMAC_SHA256, signature, SHA256_DIGEST_LENGTH); ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, sts); - - s.close(); - testTearDown(); } } // namespace wvoec