OEMCrypto v16.2

Merge from Widevine repo of http://go/wvgerrit/93404

This is the unit tests, reference code, and documentation for
OEMCrypto v16.2. Backwards compatibility should work for a v15
OEMCrypto.

Some review comments will be addressed in future CLs.

Bug: 141247171
Test: Unit tests
Test: Media GTS tests on bonito
Change-Id: I9d427c07580e180c0a4cfdc4a68f538d351c0ddd
This commit is contained in:
Fred Gylys-Colwell
2020-01-18 10:18:50 -08:00
parent 7665614b2e
commit db2050dff1
62 changed files with 2947 additions and 2286 deletions

View File

@@ -18,6 +18,7 @@
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
@@ -429,7 +430,7 @@ OEMCryptoResult SessionContext::PrepAndSignRenewalRequest(
}
// If we are talking to an old license server, then we only sign the message
// body.
if (nonce_values_.api_version < 16) {
if (nonce_values_.api_major_version < 16) {
const uint8_t* message_body = message + *core_message_length;
const size_t message_body_length = message_length - *core_message_length;
return GenerateSignature(message_body, message_body_length, signature,
@@ -643,7 +644,7 @@ bool SessionContext::ValidateMessage(const uint8_t* given_message,
LOGE("ValidateMessage: Could not compute signature");
return false;
}
if (memcmp(given_signature, computed_signature, signature_length)) {
if (CRYPTO_memcmp(given_signature, computed_signature, signature_length)) {
LOGE("Invalid signature given: %s",
wvcdm::HexEncode(given_signature, signature_length).c_str());
LOGE("Invalid signature computed: %s",
@@ -1099,10 +1100,40 @@ OEMCryptoResult SessionContext::RefreshKey(
if (session_keys_ == nullptr) {
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
if (key_control.empty()) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
std::vector<uint8_t> decrypted_key_control;
if (key_id.empty()) {
// Key control is not encrypted if key id is NULL
decrypted_key_control = key_control;
} else {
Key* content_key = session_keys_->Find(key_id);
if (nullptr == content_key) {
LOGE("Key ID not found.");
return OEMCrypto_ERROR_NO_CONTENT_KEY;
}
const std::vector<uint8_t> content_key_value = content_key->value();
// Decrypt encrypted key control block
if (key_control_iv.empty()) {
decrypted_key_control = key_control;
} else {
if (!DecryptMessage(content_key_value, key_control_iv, key_control,
&decrypted_key_control, 128 /* key size */)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}
}
KeyControlBlock key_control_block(decrypted_key_control);
if (!key_control_block.valid()) {
LOGE("Parse key control error.");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
uint32_t new_key_duration = key_control_block.duration();
uint64_t* timer_value = nullptr;
const OEMCryptoResult result =
ODK_RefreshV15Values(&timer_limits_, &clock_values_, &nonce_values_,
ce_->SystemTime(), timer_value);
ce_->SystemTime(), new_key_duration, timer_value);
if (result == ODK_SET_TIMER || result == ODK_DISABLE_TIMER)
return OEMCrypto_SUCCESS;
if (result == ODK_TIMER_EXPIRED) return OEMCrypto_ERROR_KEY_EXPIRED;
@@ -1375,7 +1406,8 @@ OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer,
uint8_t computed_signature[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)) {
if (0 ==
CRYPTO_memcmp(signature, computed_signature, SHA256_DIGEST_LENGTH)) {
return OEMCrypto_SUCCESS;
} else {
return OEMCrypto_ERROR_SIGNATURE_FAILURE;