OEMCrypto Usage Tables
This CL adds usage tables to the OEMCrypto reference implementation (mock) and unit tests. There is also a new parameter called oem_crypto_require_usage_tables that determines if the usage tables are required or not. This is set to true for Android and false for all other platforms. This CL is most of OEMCrypto version 9 updates. This CL is a copy of https://widevine-internal-review.googlesource.com/#/c/9720 https://widevine-internal-review.googlesource.com/#/c/9874 https://widevine-internal-review.googlesource.com/#/c/9873 Change-Id: I78c4f7651306f9f79ba2260c3e04fb1eca7e20e3
This commit is contained in:
@@ -1,11 +1,7 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Reference implementation of OEMCrypto APIs
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Reference implementation of OEMCrypto APIs
|
||||
//
|
||||
#include "OEMCryptoCENC.h"
|
||||
|
||||
#include <iostream>
|
||||
@@ -15,6 +11,7 @@
|
||||
#include <string>
|
||||
#include "log.h"
|
||||
#include "oemcrypto_engine_mock.h"
|
||||
#include "oemcrypto_usage_table_mock.h"
|
||||
#include "openssl/cmac.h"
|
||||
#include "openssl/evp.h"
|
||||
#include "openssl/hmac.h"
|
||||
@@ -179,8 +176,10 @@ OEMCryptoResult OEMCrypto_GenerateDerivedKeys(OEMCrypto_SESSION session,
|
||||
uint32_t enc_key_context_length) {
|
||||
if (trace_all_calls) {
|
||||
printf("-- OEMCryptoResult OEMCrypto_GenerateDerivedKeys(\n");
|
||||
dump_hex("mac_key_context", mac_key_context, (size_t)mac_key_context_length);
|
||||
dump_hex("enc_key_context", enc_key_context, (size_t)enc_key_context_length);
|
||||
dump_hex("mac_key_context", mac_key_context,
|
||||
(size_t)mac_key_context_length);
|
||||
dump_hex("enc_key_context", enc_key_context,
|
||||
(size_t)enc_key_context_length);
|
||||
}
|
||||
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
|
||||
LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_KEYBOX_INVALID]");
|
||||
@@ -193,10 +192,10 @@ OEMCryptoResult OEMCrypto_GenerateDerivedKeys(OEMCrypto_SESSION session,
|
||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
}
|
||||
|
||||
const std::vector<uint8_t> mac_ctx_str(mac_key_context,
|
||||
mac_key_context + mac_key_context_length);
|
||||
const std::vector<uint8_t> enc_ctx_str(enc_key_context,
|
||||
enc_key_context + enc_key_context_length);
|
||||
const std::vector<uint8_t>
|
||||
mac_ctx_str(mac_key_context, mac_key_context + mac_key_context_length);
|
||||
const std::vector<uint8_t>
|
||||
enc_ctx_str(enc_key_context, 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(),
|
||||
@@ -291,7 +290,8 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session,
|
||||
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);
|
||||
printf("key_array[%zu].key_id_length=%zu;\n", i,
|
||||
key_array[i].key_id_length);
|
||||
dump_array_part("key_array", i, "key_id",
|
||||
key_array[i].key_id, key_array[i].key_id_length);
|
||||
dump_array_part("key_array", i, "key_data_iv",
|
||||
@@ -325,9 +325,10 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session,
|
||||
|
||||
// Range check
|
||||
if (!RangeCheck(message, message_length, enc_mac_keys,
|
||||
2*wvcdm::MAC_KEY_SIZE, true) ||
|
||||
!RangeCheck(message, message_length, enc_mac_key_iv,
|
||||
wvcdm::KEY_IV_SIZE, true)) {
|
||||
2 * wvcdm::MAC_KEY_SIZE, true) ||
|
||||
!RangeCheck(message, message_length, enc_mac_key_iv, wvcdm::KEY_IV_SIZE,
|
||||
true) ||
|
||||
!RangeCheck(message, message_length, pst, pst_length, true)) {
|
||||
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_SIGNATURE_FAILURE - range check.]");
|
||||
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
|
||||
}
|
||||
@@ -348,9 +349,9 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session,
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
return session_ctx->LoadKeys(message, message_length, signature,
|
||||
signature_length, enc_mac_key_iv, enc_mac_keys,
|
||||
num_keys, key_array, pst, pst_length);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
@@ -362,7 +363,8 @@ OEMCryptoResult OEMCrypto_RefreshKeys(OEMCrypto_SESSION session,
|
||||
size_t num_keys,
|
||||
const OEMCrypto_KeyRefreshObject* key_array) {
|
||||
if (trace_all_calls) {
|
||||
printf("-- OEMCryptoResult OEMCrypto_RefreshKeys(num_keys=%zu)\n", num_keys);
|
||||
printf("-- OEMCryptoResult OEMCrypto_RefreshKeys(num_keys=%zu)\n",
|
||||
num_keys);
|
||||
}
|
||||
|
||||
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
|
||||
@@ -464,7 +466,8 @@ OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session,
|
||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
}
|
||||
|
||||
const std::vector<uint8_t> key_id_str = std::vector<uint8_t>(key_id, key_id + key_id_length);
|
||||
const std::vector<uint8_t> key_id_str =
|
||||
std::vector<uint8_t>(key_id, key_id + key_id_length);
|
||||
if (!session_ctx->SelectContentKey(key_id_str)) {
|
||||
LOGE("[OEMCrypto_SelectKey(): FAIL]");
|
||||
return OEMCrypto_ERROR_NO_CONTENT_KEY;
|
||||
@@ -692,7 +695,8 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session,
|
||||
}
|
||||
|
||||
// Range check
|
||||
if (!RangeCheck(message, message_length, reinterpret_cast<const uint8_t*>(nonce),
|
||||
if (!RangeCheck(message, message_length,
|
||||
reinterpret_cast<const uint8_t*>(nonce),
|
||||
sizeof(uint32_t), true) ||
|
||||
!RangeCheck(message, message_length, enc_rsa_key, enc_rsa_key_length,
|
||||
true) ||
|
||||
@@ -702,7 +706,6 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session,
|
||||
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
// Validate nonce
|
||||
if (!session_ctx->CheckNonce(*nonce)) {
|
||||
return OEMCrypto_ERROR_INVALID_NONCE;
|
||||
@@ -745,8 +748,8 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session,
|
||||
result = OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
}
|
||||
const std::vector<uint8_t> context(wrapped->context,
|
||||
wrapped->context + sizeof(wrapped->context));
|
||||
const std::vector<uint8_t>
|
||||
context(wrapped->context, 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(), context,
|
||||
@@ -811,8 +814,8 @@ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session,
|
||||
LOGE("[OEMCrypto_LoadDeviceRSAKey(): ERROR_INVALID_SESSION]");
|
||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
}
|
||||
const std::vector<uint8_t> context(wrapped->context,
|
||||
wrapped->context + sizeof(wrapped->context));
|
||||
const std::vector<uint8_t>
|
||||
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(), context,
|
||||
context)) {
|
||||
@@ -837,11 +840,10 @@ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session,
|
||||
size_t rsa_key_length = enc_rsa_key_length - padding;
|
||||
// verify signature.
|
||||
if (result == OEMCrypto_SUCCESS) {
|
||||
if (!session_ctx->LoadRSAKey(pkcs8_rsa_key, rsa_key_length,
|
||||
wrapped->context,
|
||||
wrapped_rsa_key_length - sizeof(wrapped->signature),
|
||||
wrapped->signature,
|
||||
sizeof(wrapped->signature))) {
|
||||
if (!session_ctx->LoadRSAKey(
|
||||
pkcs8_rsa_key, rsa_key_length, wrapped->context,
|
||||
wrapped_rsa_key_length - sizeof(wrapped->signature),
|
||||
wrapped->signature, sizeof(wrapped->signature))) {
|
||||
result = OEMCrypto_ERROR_SIGNATURE_FAILURE;
|
||||
// return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||
}
|
||||
@@ -914,8 +916,10 @@ OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
|
||||
if (trace_all_calls) {
|
||||
printf("-- OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(\n");
|
||||
dump_hex("enc_session_key", enc_session_key, enc_session_key_length);
|
||||
dump_hex("mac_key_context", mac_key_context, (size_t)mac_key_context_length);
|
||||
dump_hex("enc_key_context", enc_key_context, (size_t)enc_key_context_length);
|
||||
dump_hex("mac_key_context", mac_key_context,
|
||||
(size_t)mac_key_context_length);
|
||||
dump_hex("enc_key_context", enc_key_context,
|
||||
(size_t)enc_key_context_length);
|
||||
}
|
||||
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
|
||||
LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_KEYBOX_INVALID]");
|
||||
@@ -933,12 +937,12 @@ OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
|
||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||
}
|
||||
|
||||
const std::vector<uint8_t> ssn_key_str(enc_session_key,
|
||||
enc_session_key + enc_session_key_length);
|
||||
const std::vector<uint8_t> mac_ctx_str(mac_key_context,
|
||||
mac_key_context + mac_key_context_length);
|
||||
const std::vector<uint8_t> enc_ctx_str(enc_key_context,
|
||||
enc_key_context + enc_key_context_length);
|
||||
const std::vector<uint8_t>
|
||||
ssn_key_str(enc_session_key, enc_session_key + enc_session_key_length);
|
||||
const std::vector<uint8_t>
|
||||
mac_ctx_str(mac_key_context, mac_key_context + mac_key_context_length);
|
||||
const std::vector<uint8_t>
|
||||
enc_ctx_str(enc_key_context, enc_key_context + enc_key_context_length);
|
||||
|
||||
// Generate mac and encryption keys for current session context
|
||||
if (!session_ctx->RSADeriveKeys(ssn_key_str, mac_ctx_str, enc_ctx_str)) {
|
||||
@@ -1125,17 +1129,28 @@ OEMCryptoResult OEMCrypto_Generic_Verify(OEMCrypto_SESSION session,
|
||||
|
||||
extern "C"
|
||||
bool OEMCrypto_SupportsUsageTable() {
|
||||
return false;
|
||||
if (trace_all_calls) {
|
||||
printf("-- bool OEMCrypto_SupportsUsageTable(); // returns true.\n");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
extern "C"
|
||||
OEMCryptoResult OEMCrypto_UpdateUsageTable() {
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
if (trace_all_calls) {
|
||||
printf("-- OEMCryptoResult OEMCrypto_UpdateUsageTable();\n");
|
||||
}
|
||||
return crypto_engine->usage_table()->UpdateTable();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst,
|
||||
size_t pst_length) {
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
if (trace_all_calls) {
|
||||
printf("-- OEMCryptoResult OEMCrypto_DeactivateUsageEntry(\n");
|
||||
dump_hex("pst", pst, pst_length);
|
||||
}
|
||||
std::vector<uint8_t> pstv(pst, pst + pst_length);
|
||||
return crypto_engine->usage_table()->DeactivateEntry(pstv);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
@@ -1144,7 +1159,29 @@ OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
|
||||
size_t pst_length,
|
||||
OEMCrypto_PST_Report *buffer,
|
||||
size_t *buffer_length) {
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
if (trace_all_calls) {
|
||||
printf("-- OEMCryptoResult OEMCrypto_ReportUsage(\n");
|
||||
dump_hex("pst", pst, pst_length);
|
||||
}
|
||||
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
||||
if (!session_ctx || !session_ctx->isValid()) {
|
||||
LOGE("[OEMCrypto_ReportUsage(): ERROR_INVALID_SESSION]");
|
||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
}
|
||||
std::vector<uint8_t> pstv(pst, pst + pst_length);
|
||||
UsageTableEntry* entry = crypto_engine->usage_table()->FindEntry(pstv);
|
||||
if (!entry) {
|
||||
LOGE("[OEMCrypto_ReportUsage(): Usage Table Entry not found]");
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
}
|
||||
OEMCryptoResult sts =
|
||||
entry->ReportUsage(session_ctx, pstv, buffer, buffer_length);
|
||||
crypto_engine->usage_table()->UpdateTable();
|
||||
if (trace_all_calls) {
|
||||
dump_hex("usage buffer", reinterpret_cast<uint8_t*>(buffer),
|
||||
*buffer_length);
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
@@ -1155,12 +1192,48 @@ OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION session,
|
||||
size_t message_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length) {
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
if (trace_all_calls) {
|
||||
printf("-- OEMCryptoResult OEMCrypto_DeleteUsageEntry(\n");
|
||||
dump_hex("pst", pst, pst_length);
|
||||
dump_hex("message", message, message_length);
|
||||
dump_hex("signature", signature, signature_length);
|
||||
}
|
||||
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
||||
if (!session_ctx || !session_ctx->isValid()) {
|
||||
LOGE("[OEMCrypto_DeleteUsageEntry(): ERROR_INVALID_SESSION]");
|
||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
}
|
||||
if (message == NULL || message_length == 0 || signature == NULL ||
|
||||
signature_length == 0 || pst == NULL || pst_length == 0) {
|
||||
LOGE("[OEMCrypto_DeleteUsageEntry(): OEMCrypto_ERROR_INVALID_CONTEXT]");
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
}
|
||||
if (!RangeCheck(message, message_length, pst, pst_length, false)) {
|
||||
LOGE("[OEMCrypto_DeleteUsageEntry(): range check.]");
|
||||
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
|
||||
}
|
||||
// Validate message signature
|
||||
if (!session_ctx->ValidateMessage(message, message_length, signature,
|
||||
signature_length)) {
|
||||
LOGE("[OEMCrypto_DeleteUsageEntry(): OEMCrypto_ERROR_SIGNATURE_FAILURE.]");
|
||||
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
|
||||
}
|
||||
std::vector<uint8_t> pstv(pst, pst + pst_length);
|
||||
if (crypto_engine->usage_table()->DeleteEntry(pstv)) {
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
OEMCryptoResult OEMCrypto_DeleteUsageTable() {
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
if (trace_all_calls) {
|
||||
printf("-- OEMCryptoResult OEMCrypto_DeleteUsageTable()\n");
|
||||
}
|
||||
if (crypto_engine->usage_table()->Clear()) {
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
|
||||
}; // namespace wvoec_mock
|
||||
|
||||
Reference in New Issue
Block a user