Files
android/libwvdrmengine/level3/arm/l3crypto_mock.cpp
Jeff Tinker 1a8aa0dd05 Initial import of Widevine Common Encryption DRM engine
Builds libwvmdrmengine.so, which is loaded by the new
MediaDrm APIs to support playback of Widevine/CENC
protected content.

Change-Id: I6f57dd37083dfd96c402cb9dd137c7d74edc8f1c
2013-03-22 11:14:17 -07:00

634 lines
22 KiB
C++

/*******************************************************************************
*
* Copyright 2013 Google Inc. All Rights Reserved.
*
* mock implementation of OEMCrypto APIs
*
******************************************************************************/
#include "L3CryptoCENC.h"
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <string>
#include "log.h"
#include "l3crypto_engine_mock.h"
#include "openssl/rand.h"
#include "wv_cdm_constants.h"
namespace wvoec_obfs {
static CryptoEngine* crypto_engine = NULL;
// Set this to true when you are generating test vectors.
const bool trace_all_calls = false;
static void dump_hex(std::string name, const uint8_t* vector, size_t length) {
printf("%s = ", name.c_str());
if (vector == NULL) {
printf("NULL;\n");
return;
}
// TODO(fredgc): replace with HEXEncode.
for (size_t i = 0; i < length; i++) {
if (i == 0) {
printf("\n wvcdm::a2b_hex(\"");
} else if (i % 32 == 0) {
printf("\"\n \"");
}
printf("%02X", vector[i]);
}
printf("\");\n");
}
void dump_array_part(std::string array, size_t index,
std::string name, const uint8_t* vector, size_t length) {
if (vector == NULL) {
printf("%s[%d].%s = NULL;\n", array.c_str(), index, name.c_str());
return;
}
printf("std::string s%d_", index);
dump_hex(name, vector, length);
printf("%s[%d].%s = message_ptr + message.find(s%d_%s.data());\n",
array.c_str(), index, name.c_str(), index, name.c_str());
}
extern "C"
OEMCryptoResult L3Crypto_Initialize(void) {
if (trace_all_calls) {
printf("------------------------- L3Crypto_Initialize(void)\n");
}
crypto_engine = new CryptoEngine;
if (!crypto_engine || !crypto_engine->Initialized()) {
LOGE("[L3Crypto_Initialize(): failed]");
return OEMCrypto_ERROR_INIT_FAILED;
}
LOGD("[L3Crypto_Initialize(): success]");
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult L3Crypto_Terminate(void) {
if (trace_all_calls) {
printf("----------------- OEMCryptoResult L3Crypto_Terminate(void)\n");
}
if (!crypto_engine) {
LOGE("[L3Crypto_Terminate(): failed]");
return OEMCrypto_ERROR_TERMINATE_FAILED;
}
if (crypto_engine->Initialized()) {
crypto_engine->Terminate();
}
delete crypto_engine;
crypto_engine = NULL;
LOGD("[L3Crypto_Terminate(): success]");
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult L3Crypto_OpenSession(OEMCrypto_SESSION* session) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_OpenSession(OEMCrypto_SESSION *session)\n");
}
SessionId sid = crypto_engine->CreateSession();
*session = (OEMCrypto_SESSION)sid;
LOGD("[L3Crypto_OpenSession(): SID=%08x]", sid);
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult L3Crypto_CloseSession(OEMCrypto_SESSION session) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_CloseSession(OEMCrypto_SESSION session)\n");
}
if (!crypto_engine->DestroySession((SessionId)session)) {
LOGD("[L3Crypto_CloseSession(SID=%08X): failed]", session);
return OEMCrypto_ERROR_CLOSE_SESSION_FAILED;
} else {
LOGD("[L3Crypto_CloseSession(SID=%08X): success]", session);
return OEMCrypto_SUCCESS;
}
}
extern "C"
OEMCryptoResult L3Crypto_GenerateNonce(OEMCrypto_SESSION session,
uint32_t* nonce) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_GenerateNonce(OEMCrypto_SESSION session,\n");
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[L3Crypto_GenerateNonce(): ERROR_NO_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
uint32_t nonce_value;
uint8_t* nonce_string = reinterpret_cast<uint8_t*>(&nonce_value);
// Generate 4 bytes of random data
if (!RAND_bytes(nonce_string, 4)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
session_ctx->AddNonce(nonce_value);
*nonce = nonce_value;
if (trace_all_calls) {
printf("nonce = %08x\n", nonce_value);
}
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult L3Crypto_GenerateDerivedKeys(
OEMCrypto_SESSION session,
const uint8_t* mac_key_context,
uint32_t mac_key_context_length,
const uint8_t* enc_key_context,
uint32_t enc_key_context_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_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);
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[L3Crypto_GenerateDerivedKeys(): ERROR_KEYBOX_INVALID]");
return OEMCrypto_ERROR_KEYBOX_INVALID;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[L3Crypto_GenerateDerivedKeys(): ERROR_NO_INVALID_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);
// Generate mac and encryption keys for current session context
if (!session_ctx->DeriveKeys(mac_ctx_str, enc_ctx_str)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult L3Crypto_GenerateSignature(
OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
uint8_t* signature,
size_t* signature_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_GenerateSignature(\n");
dump_hex("message", message, message_length);
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[L3Crypto_GenerateSignature(): ERROR_KEYBOX_INVALID]");
return OEMCrypto_ERROR_KEYBOX_INVALID;
}
if (message == NULL || message_length == 0 ||
signature == NULL || signature_length == 0) {
LOGE("[L3Crypto_GenerateSignature(): OEMCrypto_ERROR_INVALID_CONTEXT]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[L3Crypto_GenerateSignature(): ERROR_NO_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
if (session_ctx->GenerateSignature(message,
message_length,
signature,
signature_length)) {
if (trace_all_calls) {
dump_hex("signature", signature, *signature_length);
}
return OEMCrypto_SUCCESS;
}
return OEMCrypto_ERROR_UNKNOWN_FAILURE;;
}
bool RangeCheck(const uint8_t* message,
uint32_t message_length,
const uint8_t* field,
uint32_t field_length,
bool allow_null) {
if (field == NULL) return allow_null;
if (field < message) return false;
if (field + field_length > message + message_length) return false;
return true;
}
extern "C"
OEMCryptoResult L3Crypto_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_key,
size_t num_keys,
const OEMCrypto_KeyObject* key_array) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_LoadKeys(OEMCrypto_SESSION session,\n");
dump_hex("message", message, message_length);
dump_hex("signature", signature, signature_length);
dump_hex("enc_mac_key_iv", enc_mac_key_iv, wvcdm::KEY_IV_SIZE);
dump_hex("enc_mac_key", enc_mac_key, wvcdm::MAC_KEY_SIZE);
for (size_t i = 0; i < num_keys; i++) {
printf("key_array[%d].key_id_length=%d;\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",
key_array[i].key_data_iv, wvcdm::KEY_IV_SIZE);
dump_array_part("key_array", i, "key_data",
key_array[i].key_data, wvcdm::KEY_IV_SIZE);
dump_array_part("key_array", i, "key_control_iv",
key_array[i].key_control_iv, wvcdm::KEY_IV_SIZE);
dump_array_part("key_array", i, "key_control",
key_array[i].key_control, wvcdm::KEY_IV_SIZE);
}
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[L3Crypto_LoadKeys(): ERROR_KEYBOX_INVALID]");
return OEMCrypto_ERROR_KEYBOX_INVALID;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[L3Crypto_LoadKeys(): ERROR_NO_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
if (message == NULL || message_length == 0 ||
signature == NULL || signature_length == 0 ||
key_array == NULL || num_keys == 0) {
LOGE("[L3Crypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
// Range check
if (!RangeCheck(message, message_length, enc_mac_key,
wvcdm::MAC_KEY_SIZE, true) ||
!RangeCheck(message, message_length, enc_mac_key_iv,
wvcdm::KEY_IV_SIZE, true)) {
LOGE("[L3Crypto_LoadKeys(): OEMCrypto_ERROR_SIGNATURE_FAILURE - range check.]");
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
}
for (unsigned int i = 0; i < num_keys; i++) {
if (!RangeCheck(message, message_length, key_array[i].key_id,
key_array[i].key_id_length, false) ||
!RangeCheck(message, message_length, key_array[i].key_data,
wvcdm::KEY_SIZE, false) ||
!RangeCheck(message, message_length, key_array[i].key_data_iv,
wvcdm::KEY_IV_SIZE, false) ||
!RangeCheck(message, message_length, key_array[i].key_control,
wvcdm::KEY_CONTROL_SIZE, true) ||
!RangeCheck(message, message_length, key_array[i].key_control_iv,
wvcdm::KEY_IV_SIZE, true)) {
LOGE("[L3Crypto_LoadKeys(): OEMCrypto_ERROR_SIGNATURE_FAILURE -range check %d]", i);
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
}
}
// Validate message signature
if (!session_ctx->ValidateMessage(message, message_length, signature, signature_length)) {
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
}
// Decrypt and install keys in key object
std::vector<uint8_t> key_id;
std::vector<uint8_t> enc_key_data;
std::vector<uint8_t> key_data_iv;
std::vector<uint8_t> key_control;
std::vector<uint8_t> 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 + wvcdm::KEY_SIZE);
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) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
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)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}
// enc_mac_key can be NULL if license renewal is not supported
if (enc_mac_key == NULL) return OEMCrypto_SUCCESS;
// V2 license protocol: update mac key after processing license response
const std::vector<uint8_t> enc_mac_key_str = std::vector<uint8_t>(
enc_mac_key, enc_mac_key + wvcdm::MAC_KEY_SIZE);
const std::vector<uint8_t> enc_mac_key_iv_str = std::vector<uint8_t>(
enc_mac_key_iv, enc_mac_key_iv + wvcdm::KEY_IV_SIZE);
if (!session_ctx->UpdateMacKey(enc_mac_key_str, enc_mac_key_iv_str)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult L3Crypto_RefreshKeys(OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
const uint8_t* signature,
size_t signature_length,
size_t num_keys,
const OEMCrypto_KeyRefreshObject* key_array) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_RefreshKeys(OEMCrypto_SESSION session,\n");
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[L3Crypto_RefreshKeys(): ERROR_KEYBOX_INVALID]");
return OEMCrypto_ERROR_KEYBOX_INVALID;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[L3Crypto_RefreshKeys(): ERROR_NO_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
if (message == NULL || message_length == 0 ||
signature == NULL || signature_length == 0) {
LOGE("[L3Crypto_RefreshKeys(): OEMCrypto_ERROR_INVALID_CONTEXT]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
// Range check
for (unsigned int i = 0; i < num_keys; i++) {
if (!RangeCheck(message, message_length, key_array[i].key_id,
key_array[i].key_id_length, true) ||
!RangeCheck(message, message_length, key_array[i].key_control,
wvcdm::KEY_CONTROL_SIZE, true) ||
!RangeCheck(message, message_length, key_array[i].key_control_iv,
wvcdm::KEY_IV_SIZE, true)) {
LOGE("[L3Crypto_RefreshKeys(): OEMCrypto_ERROR_SIGNATURE_FAILURE]");
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
}
}
// Validate message signature
if (!session_ctx->ValidateMessage(message, message_length,
signature, signature_length)) {
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
}
// Decrypt and refresh keys in key refresh object
std::vector<uint8_t> key_id;
std::vector<uint8_t> key_control;
std::vector<uint8_t> key_control_iv;
for (unsigned int i = 0; i < num_keys; i++) {
// TODO(gmorgan): key_id may be null if special control key type (TBS)
if (key_array[i].key_id != NULL) {
key_id.assign(key_array[i].key_id,
key_array[i].key_id + key_array[i].key_id_length);
} else {
key_id.clear();
}
if (key_array[i].key_control != NULL) {
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);
} else {
key_control.clear();
key_control_iv.clear();
}
if (!session_ctx->RefreshKey(key_id, key_control, key_control_iv)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult L3Crypto_SelectKey(const OEMCrypto_SESSION session,
const uint8_t* key_id,
size_t key_id_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_SelectKey(const OEMCrypto_SESSION session,\n");
dump_hex("key_id", key_id, key_id_length);
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[L3Crypto_SelectKey(): ERROR_KEYBOX_INVALID]");
return OEMCrypto_ERROR_KEYBOX_INVALID;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[L3Crypto_SelectKey(): ERROR_NO_INVALID_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);
if (!session_ctx->SelectContentKey(key_id_str)) {
LOGE("[L3Crypto_SelectKey(): FAIL]");
return OEMCrypto_ERROR_NO_CONTENT_KEY;
}
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult L3Crypto_DecryptCTR(OEMCrypto_SESSION session,
const uint8_t *data_addr,
size_t data_length,
bool is_encrypted,
const uint8_t *iv,
size_t offset,
const OEMCrypto_DestBufferDesc* out_buffer) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_DecryptCTR(OEMCrypto_SESSION session,\n");
}
wvoec_obfs::BufferType buffer_type = BUFFER_TYPE_DIRECT;
void *destination = NULL;
size_t max_length = 0;
switch (out_buffer->type) {
case OEMCrypto_BufferType_Clear:
buffer_type = BUFFER_TYPE_CLEAR;
destination = out_buffer->buffer.clear.address;
max_length = out_buffer->buffer.clear.max_length;
break;
case OEMCrypto_BufferType_Secure:
buffer_type = BUFFER_TYPE_SECURE;
destination = out_buffer->buffer.secure.handle;
max_length = out_buffer->buffer.secure.max_length;
break;
default:
case OEMCrypto_BufferType_Direct:
buffer_type = BUFFER_TYPE_DIRECT;
destination = NULL;
break;
}
if (buffer_type != BUFFER_TYPE_DIRECT && max_length < data_length) {
LOGE("[L3Crypto_DecryptCTR(): OEMCrypto_ERROR_SHORT_BUFFER]");
return OEMCrypto_ERROR_SHORT_BUFFER;
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[L3Crypto_DecryptCTR(): ERROR_KEYBOX_INVALID]");
return OEMCrypto_ERROR_KEYBOX_INVALID;
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
LOGE("[L3Crypto_DecryptCTR(): ERROR_NO_INVALID_SESSION]");
return OEMCrypto_ERROR_INVALID_SESSION;
}
if (data_addr == NULL || data_length == 0 ||
iv == NULL || out_buffer == NULL) {
LOGE("[L3Crypto_DecryptCTR(): OEMCrypto_ERROR_INVALID_CONTEXT]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
std::vector<uint8_t> iv_v(iv, iv+16);
std::vector<uint8_t> content(data_addr, data_addr+data_length);
if (!crypto_engine->DecryptCTR(session_ctx, iv_v, (int)offset,
content, is_encrypted,
destination, buffer_type)) {
LOGE("[L3Crypto_DecryptCTR(): OEMCrypto_ERROR_INVALID_CONTEXT]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult L3Crypto_InstallKeybox(const uint8_t* keybox,
size_t keyBoxLength) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_InstallKeybox(const uint8_t *keybox,\n");
}
if (crypto_engine->keybox().InstallKeybox(keybox, keyBoxLength)) {
return OEMCrypto_SUCCESS;
}
return OEMCrypto_ERROR_WRITE_KEYBOX;
}
extern "C"
OEMCryptoResult L3Crypto_IsKeyboxValid(void) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_IsKeyboxValid(void) {\n");
}
switch(crypto_engine->ValidateKeybox()) {
case NO_ERROR: return OEMCrypto_SUCCESS;
case BAD_CRC: return OEMCrypto_ERROR_BAD_CRC;
case BAD_MAGIC: return OEMCrypto_ERROR_BAD_MAGIC;
default:
case OTHER_ERROR: return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}
extern "C"
OEMCryptoResult L3Crypto_GetDeviceID(uint8_t* deviceID,
size_t* idLength) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_GetDeviceID(uint8_t* deviceID,\n");
}
std::vector<uint8_t> dev_id_string = crypto_engine->keybox().device_id();
if (dev_id_string.empty()) {
LOGE("[L3Crypto_GetDeviceId(): Keybox Invalid]");
return OEMCrypto_ERROR_KEYBOX_INVALID;
}
size_t dev_id_len = dev_id_string.size();
if (*idLength < dev_id_len) {
*idLength = dev_id_len;
LOGE("[L3Crypto_GetDeviceId(): ERROR_SHORT_BUFFER]");
return OEMCrypto_ERROR_SHORT_BUFFER;
}
memset(deviceID, 0, *idLength);
memcpy(deviceID, &dev_id_string[0], dev_id_len);
*idLength = dev_id_len;
LOGD("[L3Crypto_GetDeviceId(): success]");
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult L3Crypto_GetKeyData(uint8_t* keyData,
size_t* keyDataLength) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_GetKeyData(uint8_t* keyData,\n");
}
size_t length = crypto_engine->keybox().key_data_length();
if (*keyDataLength < length) {
*keyDataLength = length;
LOGE("[L3Crypto_GetKeyData(): ERROR_SHORT_BUFFER]");
return OEMCrypto_ERROR_SHORT_BUFFER;
}
memset(keyData, 0, *keyDataLength);
memcpy(keyData, crypto_engine->keybox().key_data(), length);
*keyDataLength = length;
LOGD("[L3Crypto_GetKeyData(): success]");
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult L3Crypto_GetRandom(uint8_t* randomData, size_t dataLength) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_GetRandom(uint8_t* randomData, size_t dataLength) {\n");
}
if (!randomData) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (RAND_bytes(randomData, dataLength)) {
return OEMCrypto_SUCCESS;
}
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
extern "C"
OEMCryptoResult L3Crypto_WrapKeybox(const uint8_t* keybox,
size_t keyBoxLength,
uint8_t* wrappedKeybox,
size_t* wrappedKeyBoxLength,
const uint8_t* transportKey,
size_t transportKeyLength) {
if (trace_all_calls) {
printf("-- OEMCryptoResult L3Crypto_WrapKeybox(const uint8_t *keybox,\n");
}
if (!keybox || !wrappedKeybox || !wrappedKeyBoxLength
|| (keyBoxLength != *wrappedKeyBoxLength)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
// This implementation ignores the transport key. For test keys, we
// don't need to encrypt the keybox.
memcpy(wrappedKeybox, keybox, keyBoxLength);
return OEMCrypto_SUCCESS;
}
}; // namespace wvoec_obfs