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

@@ -10,6 +10,7 @@
#include <openssl/cmac.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <stddef.h>
@@ -356,8 +357,9 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadKeys(
"range check iv]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
} else {
if (memcmp(message + enc_mac_keys.offset - wvoec::KEY_IV_SIZE,
message + enc_mac_keys_iv.offset, wvoec::KEY_IV_SIZE) == 0) {
if (CRYPTO_memcmp(message + enc_mac_keys.offset - wvoec::KEY_IV_SIZE,
message + enc_mac_keys_iv.offset,
wvoec::KEY_IV_SIZE) == 0) {
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT - "
"suspicious iv]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
@@ -465,14 +467,17 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_RefreshKeys(
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
// Range check
for (size_t i = 0; i < num_keys; i++) {
if (!RangeCheck(message_length, key_array[i].key_id, true) ||
!RangeCheck(message_length, key_array[i].key_control, false) ||
!RangeCheck(message_length, key_array[i].key_control_iv, true)) {
LOGE("Range Check %zu", i);
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
// We only use the first key object to update the entire license. Since we
// know num_keys > 0 after the last if statement, we can assume index is not
// out of bounds.
constexpr size_t kIndex = 0;
// Range check.
if (!RangeCheck(message_length, key_array[kIndex].key_id, true) ||
!RangeCheck(message_length, key_array[kIndex].key_control, false) ||
!RangeCheck(message_length, key_array[kIndex].key_control_iv, true)) {
LOGE("Range Check %zu", kIndex);
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
// Validate message signature
@@ -487,37 +492,31 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_RefreshKeys(
std::vector<uint8_t> key_id;
std::vector<uint8_t> key_control;
std::vector<uint8_t> key_control_iv;
for (size_t i = 0; i < num_keys; i++) {
if (key_array[i].key_id.length != 0) {
key_id.assign(
message + key_array[i].key_id.offset,
message + key_array[i].key_id.offset + key_array[i].key_id.length);
key_control.assign(
message + key_array[i].key_control.offset,
message + key_array[i].key_control.offset + wvoec::KEY_CONTROL_SIZE);
if (key_array[i].key_control_iv.length == 0) {
key_control_iv.clear();
} else {
key_control_iv.assign(
message + key_array[i].key_control_iv.offset,
message + key_array[i].key_control_iv.offset + wvoec::KEY_IV_SIZE);
}
} else {
// key_id could be null if special control key type
// key_control is not encrypted in this case
key_id.clear();
if (key_array[kIndex].key_id.length != 0) {
key_id.assign(message + key_array[kIndex].key_id.offset,
message + key_array[kIndex].key_id.offset +
key_array[kIndex].key_id.length);
key_control.assign(message + key_array[kIndex].key_control.offset,
message + key_array[kIndex].key_control.offset +
wvoec::KEY_CONTROL_SIZE);
if (key_array[kIndex].key_control_iv.length == 0) {
key_control_iv.clear();
key_control.assign(
message + key_array[i].key_control.offset,
message + key_array[i].key_control.offset + wvoec::KEY_CONTROL_SIZE);
}
status = session_ctx->RefreshKey(key_id, key_control, key_control_iv);
if (status != OEMCrypto_SUCCESS) {
LOGE("error %d in key %zu", status, i);
break;
} else {
key_control_iv.assign(message + key_array[kIndex].key_control_iv.offset,
message + key_array[kIndex].key_control_iv.offset +
wvoec::KEY_IV_SIZE);
}
} else {
// key_id could be null if special control key type
// key_control is not encrypted in this case
key_id.clear();
key_control_iv.clear();
key_control.assign(message + key_array[kIndex].key_control.offset,
message + key_array[kIndex].key_control.offset +
wvoec::KEY_CONTROL_SIZE);
}
status = session_ctx->RefreshKey(key_id, key_control, key_control_iv);
if (status != OEMCrypto_SUCCESS) {
return status;
}