diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp index 76d4ca49..c4dd9762 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.cpp @@ -570,194 +570,198 @@ bool SessionContext::LoadRSAKey(uint8_t* pkcs8_rsa_key, } } -bool SessionContext::Generic_Encrypt(const uint8_t* in_buffer, - size_t buffer_length, - const uint8_t* iv, - OEMCrypto_Algorithm algorithm, - uint8_t* out_buffer) { +OEMCryptoResult SessionContext::Generic_Encrypt(const uint8_t* in_buffer, + size_t buffer_length, + const uint8_t* iv, + OEMCrypto_Algorithm algorithm, + uint8_t* out_buffer) { // Check there is a content key if (current_content_key() == NULL) { LOGE("[Generic_Encrypt(): OEMCrypto_ERROR_NO_CONTENT_KEY]"); - return false; + return OEMCrypto_ERROR_NO_CONTENT_KEY; } const std::vector& key = current_content_key()->value(); const KeyControlBlock& control = current_content_key()->control(); // Set the AES key. if (static_cast(key.size()) != AES_BLOCK_SIZE) { LOGE("[Generic_Encrypt(): CONTENT_KEY has wrong size: %d",key.size()); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (!(control.control_bits() & kControlAllowEncrypt)) { LOGE("[Generic_Encrypt(): control bit says not allowed."); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (control.duration() > 0) { if (control.duration() < CurrentTimer()) { LOGE("[Generic_Encrypt(): key expired."); - return false; + return OEMCrypto_ERROR_KEY_EXPIRED; } } if( algorithm != OEMCrypto_AES_CBC_128_NO_PADDING ) { LOGE("[Generic_Encrypt(): algorithm bad."); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if( buffer_length % AES_BLOCK_SIZE != 0 ) { LOGE("[Generic_Encrypt(): buffers size bad."); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } const uint8_t* key_u8 = &key[0]; AES_KEY aes_key; if (AES_set_encrypt_key(key_u8, AES_BLOCK_SIZE * 8, &aes_key) != 0) { LOGE("[Generic_Encrypt(): FAILURE]"); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } uint8_t iv_buffer[ wvcdm::KEY_IV_SIZE]; memcpy(iv_buffer, iv, wvcdm::KEY_IV_SIZE); AES_cbc_encrypt(in_buffer, out_buffer, buffer_length, &aes_key, iv_buffer, AES_ENCRYPT); - return true; + return OEMCrypto_SUCCESS; } -bool SessionContext::Generic_Decrypt(const uint8_t* in_buffer, - size_t buffer_length, - const uint8_t* iv, - OEMCrypto_Algorithm algorithm, - uint8_t* out_buffer) { +OEMCryptoResult SessionContext::Generic_Decrypt(const uint8_t* in_buffer, + size_t buffer_length, + const uint8_t* iv, + OEMCrypto_Algorithm algorithm, + uint8_t* out_buffer) { // Check there is a content key if (current_content_key() == NULL) { LOGE("[Generic_Decrypt(): OEMCrypto_ERROR_NO_CONTENT_KEY]"); - return false; + return OEMCrypto_ERROR_NO_CONTENT_KEY; } const std::vector& key = current_content_key()->value(); const KeyControlBlock& control = current_content_key()->control(); // Set the AES key. if (static_cast(key.size()) != AES_BLOCK_SIZE) { LOGE("[Generic_Decrypt(): CONTENT_KEY has wrong size."); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (!(control.control_bits() & kControlAllowDecrypt)) { LOGE("[Generic_Decrypt(): control bit says not allowed."); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (control.control_bits() & kControlDataPathSecure) { LOGE("[Generic_Decrypt(): control bit says secure path only."); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (control.duration() > 0) { if (control.duration() < CurrentTimer()) { LOGE("[Generic_Decrypt(): key expired."); - return false; + return OEMCrypto_ERROR_KEY_EXPIRED; } } if( algorithm != OEMCrypto_AES_CBC_128_NO_PADDING ) { LOGE("[Generic_Decrypt(): bad algorithm."); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if( buffer_length % AES_BLOCK_SIZE != 0 ) { LOGE("[Generic_Decrypt(): bad buffer size."); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } const uint8_t* key_u8 = &key[0]; AES_KEY aes_key; if (AES_set_decrypt_key(key_u8, AES_BLOCK_SIZE * 8, &aes_key) != 0) { LOGE("[Generic_Decrypt(): FAILURE]"); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } uint8_t iv_buffer[ wvcdm::KEY_IV_SIZE]; memcpy(iv_buffer, iv, wvcdm::KEY_IV_SIZE); AES_cbc_encrypt(in_buffer, out_buffer, buffer_length, &aes_key, iv_buffer, AES_DECRYPT); - return true; + return OEMCrypto_SUCCESS; } -bool SessionContext::Generic_Sign(const uint8_t* in_buffer, - size_t buffer_length, - OEMCrypto_Algorithm algorithm, - uint8_t* signature, - size_t* signature_length) { +OEMCryptoResult SessionContext::Generic_Sign(const uint8_t* in_buffer, + size_t buffer_length, + OEMCrypto_Algorithm algorithm, + uint8_t* signature, + size_t* signature_length) { // Check there is a content key if (current_content_key() == NULL) { LOGE("[Generic_Sign(): OEMCrypto_ERROR_NO_CONTENT_KEY]"); - return false; + return OEMCrypto_ERROR_NO_CONTENT_KEY; } if (*signature_length < SHA256_DIGEST_LENGTH) { *signature_length = SHA256_DIGEST_LENGTH; LOGE("[Generic_Sign(): bad signature length."); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } const std::vector& key = current_content_key()->value(); const KeyControlBlock& control = current_content_key()->control(); if (static_cast(key.size()) != SHA256_DIGEST_LENGTH) { LOGE("[Generic_Sign(): CONTENT_KEY has wrong size; %d", key.size()); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (!(control.control_bits() & kControlAllowSign)) { LOGE("[Generic_Sign(): control bit says not allowed."); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (control.duration() > 0) { if (control.duration() < CurrentTimer()) { LOGE("[Generic_Sign(): key expired."); - return false; + return OEMCrypto_ERROR_KEY_EXPIRED; } } if( algorithm != OEMCrypto_HMAC_SHA256 ) { LOGE("[Generic_Sign(): bad algorithm."); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } unsigned int md_len = *signature_length; if (HMAC(EVP_sha256(), &key[0], SHA256_DIGEST_LENGTH, in_buffer, buffer_length, signature, &md_len)) { *signature_length = md_len; - return true; + return OEMCrypto_SUCCESS; } LOGE("[Generic_Sign(): hmac failed."); dump_openssl_error(); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } -bool SessionContext::Generic_Verify(const uint8_t* in_buffer, - size_t buffer_length, - OEMCrypto_Algorithm algorithm, - const uint8_t* signature, - size_t signature_length) { +OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer, + size_t buffer_length, + OEMCrypto_Algorithm algorithm, + const uint8_t* signature, + size_t signature_length) { // Check there is a content key if (current_content_key() == NULL) { LOGE("[Decrypt_Verify(): OEMCrypto_ERROR_NO_CONTENT_KEY]"); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (signature_length < SHA256_DIGEST_LENGTH) { - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } const std::vector& key = current_content_key()->value(); const KeyControlBlock& control = current_content_key()->control(); if (static_cast(key.size()) != SHA256_DIGEST_LENGTH) { LOGE("[Generic_Verify(): CONTENT_KEY has wrong size: %d", key.size()); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (!(control.control_bits() & kControlAllowVerify)) { LOGE("[Generic_Verify(): control bit says not allowed."); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } if (control.duration() > 0) { if (control.duration() < CurrentTimer()) { LOGE("[Generic_Verify(): key expired."); - return false; + return OEMCrypto_ERROR_KEY_EXPIRED; } } if( algorithm != OEMCrypto_HMAC_SHA256 ) { LOGE("[Generic_Verify(): bad algorithm."); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } unsigned int md_len = signature_length; uint8_t computed_signature[SHA256_DIGEST_LENGTH]; if (HMAC(EVP_sha256(), &key[0], SHA256_DIGEST_LENGTH, in_buffer, buffer_length, computed_signature, &md_len)) { - return (0 == memcmp( signature, computed_signature, SHA256_DIGEST_LENGTH)); + if (0 == memcmp(signature, computed_signature, SHA256_DIGEST_LENGTH)) { + return OEMCrypto_SUCCESS; + } else { + return OEMCrypto_ERROR_SIGNATURE_FAILURE; + } } LOGE("[Generic_Verify(): HMAC failed."); dump_openssl_error(); - return false; + return OEMCrypto_ERROR_UNKNOWN_FAILURE; } bool SessionContext::RefreshKey(const KeyId& key_id, @@ -928,41 +932,41 @@ bool CryptoEngine::DecryptMessage(SessionContext* session, return true; } -bool 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 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) { // If the data is clear, we do not need a current key selected. if (!is_encrypted && buffer_type != kBufferTypeDirect) { memcpy(reinterpret_cast(clear_data), cipher_data, cipher_data_length); - return true; + return OEMCrypto_SUCCESS; } // Check there is a content key if (session->current_content_key() == NULL) { LOGE("[DecryptCTR(): OEMCrypto_ERROR_NO_CONTENT_KEY]"); - return false; + return OEMCrypto_ERROR_DECRYPT_FAILED; } const KeyControlBlock& control = session->current_content_key()->control(); if (control.control_bits() & kControlDataPathSecure) { if (buffer_type == kBufferTypeClear) { LOGE("[DecryptCTR(): Secure key with insecure buffer]"); - return false; + return OEMCrypto_ERROR_DECRYPT_FAILED; } } if (control.control_bits() & kControlHDCPRequired) { // For reference implementation, we do not implement any HDCP. - return false; + LOGE("[DecryptCTR(): DECRYPT FAILED: HDCP Required]"); + return OEMCrypto_ERROR_DECRYPT_FAILED; } if (control.duration() > 0) { if (control.duration() < session->CurrentTimer()) { - return false; + LOGE("[DecryptCTR(): KEY_EXPIRED]"); + return OEMCrypto_ERROR_KEY_EXPIRED; } } @@ -971,23 +975,23 @@ bool CryptoEngine::DecryptCTR(SessionContext* session, // Set the AES key. if (static_cast(content_key.size()) != AES_BLOCK_SIZE) { LOGE("[DecryptCTR(): CONTENT_KEY has wrong size: %d", content_key.size()); - return false; + return OEMCrypto_ERROR_DECRYPT_FAILED; } const uint8_t* key_u8 = &content_key[0]; AES_KEY aes_key; if (AES_set_encrypt_key(key_u8, AES_BLOCK_SIZE * 8, &aes_key) != 0) { LOGE("[DecryptCTR(): FAILURE]"); - return false; + return OEMCrypto_ERROR_DECRYPT_FAILED; } if (buffer_type == kBufferTypeDirect) { // For reference implementation, we quietly drop direct video. - return true; + return OEMCrypto_SUCCESS; } if (buffer_type == kBufferTypeSecure) { // For reference implementation, we also quietly drop secure data. - return true; + return OEMCrypto_SUCCESS; } // Local copy (will be modified). @@ -1011,7 +1015,7 @@ bool CryptoEngine::DecryptCTR(SessionContext* session, ctr128_inc64(aes_iv); block_offset = 0; } - return true; + return OEMCrypto_SUCCESS; } void NonceTable::AddNonce(uint32_t nonce) { diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h index 07d37d74..256b9460 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_engine_mock.h @@ -116,26 +116,21 @@ class SessionContext { size_t message_length, const uint8_t* signature, size_t signature_length); - bool Generic_Encrypt(const uint8_t* in_buffer, - size_t buffer_length, - const uint8_t* iv, - OEMCrypto_Algorithm algorithm, - uint8_t* out_buffer); - bool Generic_Decrypt(const uint8_t* in_buffer, - size_t buffer_length, - const uint8_t* iv, - OEMCrypto_Algorithm algorithm, - uint8_t* out_buffer); - bool Generic_Sign(const uint8_t* in_buffer, - size_t buffer_length, - OEMCrypto_Algorithm algorithm, - uint8_t* signature, - size_t* signature_length); - bool Generic_Verify(const uint8_t* in_buffer, - size_t buffer_length, - OEMCrypto_Algorithm algorithm, - const uint8_t* signature, - size_t signature_length); + OEMCryptoResult Generic_Encrypt(const uint8_t* in_buffer, + size_t buffer_length, const uint8_t* iv, + OEMCrypto_Algorithm algorithm, + uint8_t* out_buffer); + OEMCryptoResult Generic_Decrypt(const uint8_t* in_buffer, + size_t buffer_length, const uint8_t* iv, + OEMCrypto_Algorithm algorithm, + uint8_t* out_buffer); + OEMCryptoResult Generic_Sign(const uint8_t* in_buffer, size_t buffer_length, + OEMCrypto_Algorithm algorithm, + uint8_t* signature, size_t* signature_length); + OEMCryptoResult Generic_Verify(const uint8_t* in_buffer, size_t buffer_length, + OEMCrypto_Algorithm algorithm, + const uint8_t* signature, + size_t signature_length); void StartTimer(); uint32_t CurrentTimer(); // (seconds). bool InstallKey(const KeyId& key_id, @@ -248,14 +243,10 @@ class CryptoEngine { const std::vector& message, std::vector* decrypted); - bool 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 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); private: diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp index 8594a106..73fa91d5 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp @@ -582,14 +582,9 @@ OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session, return OEMCrypto_ERROR_INVALID_CONTEXT; } - if (!crypto_engine->DecryptCTR(session_ctx, iv, block_offset, - data_addr, data_length, is_encrypted, - destination, buffer_type)) { - LOGE("[OEMCrypto_DecryptCTR(): OEMCrypto_ERROR_DECRYPT_FAILED]"); - return OEMCrypto_ERROR_DECRYPT_FAILED; - } - - return OEMCrypto_SUCCESS; + return crypto_engine->DecryptCTR(session_ctx, iv, block_offset, data_addr, + data_length, is_encrypted, destination, + buffer_type); } extern "C" @@ -1053,12 +1048,8 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt(OEMCrypto_SESSION session, LOGE("[OEMCrypto_Generic_Enrypt(): OEMCrypto_ERROR_INVALID_CONTEXT]"); return OEMCrypto_ERROR_INVALID_CONTEXT; } - if (!session_ctx->Generic_Encrypt(in_buffer, buffer_length, iv, algorithm, - out_buffer)) { - LOGE("[OEMCrypto_Generic_Enrypt(): OEMCrypto_ERROR_UNKNOWN_FAILURE]"); - return OEMCrypto_ERROR_UNKNOWN_FAILURE; - } - return OEMCrypto_SUCCESS; + return session_ctx->Generic_Encrypt(in_buffer, buffer_length, iv, algorithm, + out_buffer); } extern "C" @@ -1077,16 +1068,13 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt(OEMCrypto_SESSION session, LOGE("[OEMCrypto_Generic_Decrypt(): ERROR_INVALID_SESSION]"); return OEMCrypto_ERROR_INVALID_SESSION; } - if (!session_ctx->Generic_Decrypt(in_buffer, buffer_length, iv, algorithm, - out_buffer)) { - return OEMCrypto_ERROR_UNKNOWN_FAILURE; - } if (in_buffer == NULL || buffer_length == 0 || iv == NULL || out_buffer == NULL) { LOGE("[OEMCrypto_Generic_Decrypt(): OEMCrypto_ERROR_INVALID_CONTEXT]"); return OEMCrypto_ERROR_INVALID_CONTEXT; } - return OEMCrypto_SUCCESS; + return session_ctx->Generic_Decrypt(in_buffer, buffer_length, iv, algorithm, + out_buffer); } extern "C" @@ -1113,11 +1101,8 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session, LOGE("[OEMCrypto_Generic_Sign(): OEMCrypto_ERROR_INVALID_CONTEXT]"); return OEMCrypto_ERROR_INVALID_CONTEXT; } - if (!session_ctx->Generic_Sign(in_buffer, buffer_length, algorithm, - signature, signature_length)) { - return OEMCrypto_ERROR_UNKNOWN_FAILURE; - } - return OEMCrypto_SUCCESS; + return session_ctx->Generic_Sign(in_buffer, buffer_length, algorithm, + signature, signature_length); } extern "C" @@ -1143,11 +1128,8 @@ OEMCryptoResult OEMCrypto_Generic_Verify(OEMCrypto_SESSION session, LOGE("[OEMCrypto_Generic_Verify(): OEMCrypto_ERROR_INVALID_CONTEXT]"); return OEMCrypto_ERROR_INVALID_CONTEXT; } - if (!session_ctx->Generic_Verify(in_buffer, buffer_length, algorithm, - signature, signature_length)) { - return OEMCrypto_ERROR_UNKNOWN_FAILURE; - } - return OEMCrypto_SUCCESS; + return session_ctx->Generic_Verify(in_buffer, buffer_length, algorithm, + signature, signature_length); } extern "C" diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index 91a90aaa..39d10f24 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -3014,7 +3014,7 @@ TEST_F(DISABLED_TestKeybox, KeyDuration) { encryptedData.size(), true, &encryptionIv[0], 0, &destBuffer, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - ASSERT_NE(OEMCrypto_SUCCESS, sts); + ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, sts); ASSERT_NE(0, memcmp(&unencryptedData[0], outputBuffer, unencryptedData.size())); @@ -4975,7 +4975,7 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationEncrypt) { memset(encrypted, 0, kBufferSize); sts = OEMCrypto_Generic_Encrypt(s.session_id(), clear_buffer_, kBufferSize, iv_, OEMCrypto_AES_CBC_128_NO_PADDING, encrypted); - ASSERT_NE(OEMCrypto_SUCCESS, sts); + ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, sts); ASSERT_NE(0, memcmp(encrypted, expected_encrypted, kBufferSize)); s.close(); testTearDown(); @@ -5016,7 +5016,7 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationDecrypt) { memset(resultant, 0, kBufferSize); sts = OEMCrypto_Generic_Decrypt(s.session_id(), encrypted, kBufferSize, iv_, OEMCrypto_AES_CBC_128_NO_PADDING, resultant); - ASSERT_NE(OEMCrypto_SUCCESS, sts); + ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, sts); ASSERT_NE(0, memcmp(clear_buffer_, resultant, kBufferSize)); s.close(); testTearDown(); @@ -5063,7 +5063,7 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationSign) { sts = OEMCrypto_Generic_Sign(s.session_id(), clear_buffer_, kBufferSize, OEMCrypto_HMAC_SHA256,signature, &signature_length); - ASSERT_NE(OEMCrypto_SUCCESS, sts); + ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, sts); ASSERT_NE(0, memcmp(signature, expected_signature, SHA256_DIGEST_LENGTH)); s.close(); @@ -5104,7 +5104,7 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationVerify) { sts = OEMCrypto_Generic_Verify(s.session_id(), clear_buffer_, kBufferSize, OEMCrypto_HMAC_SHA256,signature, SHA256_DIGEST_LENGTH); - ASSERT_NE(OEMCrypto_SUCCESS, sts); + ASSERT_EQ(OEMCrypto_ERROR_KEY_EXPIRED, sts); s.close(); testTearDown();