Merge "Sync oemcrypto reference code" into sc-dev am: 6d1898f20f
Original change: https://googleplex-android-review.googlesource.com/c/platform/vendor/widevine/+/15055360 Change-Id: Ie36ebd1145028597dfbbee5bd58b8e4582ce119f
This commit is contained in:
@@ -50,7 +50,7 @@ typedef enum SessionType {
|
|||||||
class CryptoEngine {
|
class CryptoEngine {
|
||||||
public:
|
public:
|
||||||
static const uint32_t kApiVersion = 16;
|
static const uint32_t kApiVersion = 16;
|
||||||
static const uint32_t kMinorApiVersion = 3;
|
static const uint32_t kMinorApiVersion = 4;
|
||||||
static const int64_t kTimeInfoUpdateWindowInSeconds = 300;
|
static const int64_t kTimeInfoUpdateWindowInSeconds = 300;
|
||||||
|
|
||||||
// This is like a factory method, except we choose which version to use at
|
// This is like a factory method, except we choose which version to use at
|
||||||
|
|||||||
@@ -554,9 +554,12 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_QueryKeyControl(
|
|||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
uint32_t* block = reinterpret_cast<uint32_t*>(key_control_block);
|
uint32_t* block = reinterpret_cast<uint32_t*>(key_control_block);
|
||||||
if ((key_control_block_length == nullptr) ||
|
if (key_control_block_length == nullptr) {
|
||||||
(*key_control_block_length < wvoec::KEY_CONTROL_SIZE)) {
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
|
}
|
||||||
|
if (*key_control_block_length < wvoec::KEY_CONTROL_SIZE) {
|
||||||
LOGE("[OEMCrypto_QueryKeyControl(): OEMCrypto_ERROR_SHORT_BUFFER]");
|
LOGE("[OEMCrypto_QueryKeyControl(): OEMCrypto_ERROR_SHORT_BUFFER]");
|
||||||
|
*key_control_block_length = wvoec::KEY_CONTROL_SIZE;
|
||||||
return OEMCrypto_ERROR_SHORT_BUFFER;
|
return OEMCrypto_ERROR_SHORT_BUFFER;
|
||||||
}
|
}
|
||||||
*key_control_block_length = wvoec::KEY_CONTROL_SIZE;
|
*key_control_block_length = wvoec::KEY_CONTROL_SIZE;
|
||||||
@@ -572,6 +575,9 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_QueryKeyControl(
|
|||||||
LOGE("[OEMCrypto_QueryKeyControl(): ERROR_INVALID_SESSION]");
|
LOGE("[OEMCrypto_QueryKeyControl(): ERROR_INVALID_SESSION]");
|
||||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
}
|
}
|
||||||
|
if (key_id_length > wvoec::KEY_ID_SIZE || key_id_length == 0) {
|
||||||
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
|
}
|
||||||
const std::vector<uint8_t> key_id_str =
|
const std::vector<uint8_t> key_id_str =
|
||||||
std::vector<uint8_t>(key_id, key_id + key_id_length);
|
std::vector<uint8_t>(key_id, key_id + key_id_length);
|
||||||
if (!session_ctx->QueryKeyControlBlock(key_id_str, block)) {
|
if (!session_ctx->QueryKeyControlBlock(key_id_str, block)) {
|
||||||
@@ -596,7 +602,9 @@ OEMCrypto_SelectKey(const OEMCrypto_SESSION session, const uint8_t* key_id,
|
|||||||
LOGE("[OEMCrypto_SelectKey(): ERROR_INVALID_SESSION]");
|
LOGE("[OEMCrypto_SelectKey(): ERROR_INVALID_SESSION]");
|
||||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
}
|
}
|
||||||
|
if (key_id_length > wvoec::KEY_ID_SIZE || key_id_length == 0) {
|
||||||
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
|
}
|
||||||
const std::vector<uint8_t> key_id_str =
|
const std::vector<uint8_t> key_id_str =
|
||||||
std::vector<uint8_t>(key_id, key_id + key_id_length);
|
std::vector<uint8_t>(key_id, key_id + key_id_length);
|
||||||
return session_ctx->SelectContentKey(key_id_str, cipher_mode);
|
return session_ctx->SelectContentKey(key_id_str, cipher_mode);
|
||||||
@@ -1272,7 +1280,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateRSASignature(
|
|||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signature_length == 0) {
|
if (signature_length == nullptr) {
|
||||||
LOGE("[OEMCrypto_GenerateRSASignature(): OEMCrypto_ERROR_INVALID_CONTEXT]");
|
LOGE("[OEMCrypto_GenerateRSASignature(): OEMCrypto_ERROR_INVALID_CONTEXT]");
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
}
|
}
|
||||||
@@ -1289,8 +1297,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateRSASignature(
|
|||||||
return OEMCrypto_ERROR_SHORT_BUFFER;
|
return OEMCrypto_ERROR_SHORT_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message == nullptr || message_length == 0 || signature == nullptr ||
|
if (message == nullptr || message_length == 0 || signature == nullptr) {
|
||||||
signature_length == 0) {
|
|
||||||
LOGE("[OEMCrypto_GenerateRSASignature(): OEMCrypto_ERROR_INVALID_CONTEXT]");
|
LOGE("[OEMCrypto_GenerateRSASignature(): OEMCrypto_ERROR_INVALID_CONTEXT]");
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||||
// source code may only be used and distributed under the Widevine Master
|
// source code may only be used and distributed under the Widevine
|
||||||
// License Agreement.
|
// License Agreement.
|
||||||
//
|
//
|
||||||
// Reference implementation of OEMCrypto APIs
|
// Reference implementation of OEMCrypto APIs
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||||
// source code may only be used and distributed under the Widevine Master
|
// source code may only be used and distributed under the Widevine
|
||||||
// License Agreement.
|
// License Agreement.
|
||||||
//
|
//
|
||||||
// Reference implementation of OEMCrypto APIs
|
// Reference implementation of OEMCrypto APIs
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ bool SessionContext::DeriveKey(const std::vector<uint8_t>& key,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CMAC_Init(cmac_ctx, &key[0], key.size(), cipher, 0)) {
|
if (!CMAC_Init(cmac_ctx, &key[0], key.size(), cipher, nullptr)) {
|
||||||
LOGE("[DeriveKey(): OEMCrypto_ERROR_CMAC_FAILURE]");
|
LOGE("[DeriveKey(): OEMCrypto_ERROR_CMAC_FAILURE]");
|
||||||
CMAC_CTX_free(cmac_ctx);
|
CMAC_CTX_free(cmac_ctx);
|
||||||
return false;
|
return false;
|
||||||
@@ -521,7 +521,7 @@ OEMCryptoResult SessionContext::GenerateCertSignature(
|
|||||||
size_t* signature_length) {
|
size_t* signature_length) {
|
||||||
// TODO(b/67735947): Add ECC cert support.
|
// TODO(b/67735947): Add ECC cert support.
|
||||||
if (message == nullptr || message_length == 0 || signature == nullptr ||
|
if (message == nullptr || message_length == 0 || signature == nullptr ||
|
||||||
signature_length == 0) {
|
signature_length == nullptr) {
|
||||||
LOGE("OEMCrypto_ERROR_INVALID_CONTEXT");
|
LOGE("OEMCrypto_ERROR_INVALID_CONTEXT");
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
}
|
}
|
||||||
@@ -571,7 +571,7 @@ OEMCryptoResult SessionContext::GenerateRSASignature(
|
|||||||
const uint8_t* message, size_t message_length, uint8_t* signature,
|
const uint8_t* message, size_t message_length, uint8_t* signature,
|
||||||
size_t* signature_length, RSA_Padding_Scheme padding_scheme) {
|
size_t* signature_length, RSA_Padding_Scheme padding_scheme) {
|
||||||
if (message == nullptr || message_length == 0 || signature == nullptr ||
|
if (message == nullptr || message_length == 0 || signature == nullptr ||
|
||||||
signature_length == 0) {
|
signature_length == nullptr) {
|
||||||
LOGE("OEMCrypto_ERROR_INVALID_CONTEXT");
|
LOGE("OEMCrypto_ERROR_INVALID_CONTEXT");
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -407,11 +407,12 @@ OEMCryptoResult UsageTable::LoadUsageEntry(
|
|||||||
if (new_entry->generation_number() != generation_numbers_[index]) {
|
if (new_entry->generation_number() != generation_numbers_[index]) {
|
||||||
LOGE("Generation SKEW: %ld -> %ld", new_entry->generation_number(),
|
LOGE("Generation SKEW: %ld -> %ld", new_entry->generation_number(),
|
||||||
generation_numbers_[index]);
|
generation_numbers_[index]);
|
||||||
if ((new_entry->generation_number() + 1 < generation_numbers_[index]) ||
|
if ((new_entry->generation_number() + 1 == generation_numbers_[index]) ||
|
||||||
(new_entry->generation_number() - 1 > generation_numbers_[index])) {
|
(new_entry->generation_number() - 1 == generation_numbers_[index])) {
|
||||||
|
status = OEMCrypto_WARNING_GENERATION_SKEW;
|
||||||
|
} else {
|
||||||
return OEMCrypto_ERROR_GENERATION_SKEW;
|
return OEMCrypto_ERROR_GENERATION_SKEW;
|
||||||
}
|
}
|
||||||
status = OEMCrypto_WARNING_GENERATION_SKEW;
|
|
||||||
}
|
}
|
||||||
sessions_[index] = session;
|
sessions_[index] = session;
|
||||||
*entry = std::move(new_entry);
|
*entry = std::move(new_entry);
|
||||||
@@ -583,11 +584,12 @@ OEMCryptoResult UsageTable::LoadUsageTableHeader(
|
|||||||
if (clear->master_generation != master_generation_number_) {
|
if (clear->master_generation != master_generation_number_) {
|
||||||
LOGE("Generation SKEW: %ld -> %ld", clear->master_generation,
|
LOGE("Generation SKEW: %ld -> %ld", clear->master_generation,
|
||||||
master_generation_number_);
|
master_generation_number_);
|
||||||
if ((clear->master_generation + 1 < master_generation_number_) ||
|
if ((clear->master_generation + 1 == master_generation_number_) ||
|
||||||
(clear->master_generation - 1 > master_generation_number_)) {
|
(clear->master_generation - 1 == master_generation_number_)) {
|
||||||
|
status = OEMCrypto_WARNING_GENERATION_SKEW;
|
||||||
|
} else {
|
||||||
return OEMCrypto_ERROR_GENERATION_SKEW;
|
return OEMCrypto_ERROR_GENERATION_SKEW;
|
||||||
}
|
}
|
||||||
status = OEMCrypto_WARNING_GENERATION_SKEW;
|
|
||||||
}
|
}
|
||||||
int64_t* stored_generations =
|
int64_t* stored_generations =
|
||||||
reinterpret_cast<int64_t*>(&clear_buffer[0] + sizeof(SignedHeaderBlock));
|
reinterpret_cast<int64_t*>(&clear_buffer[0] + sizeof(SignedHeaderBlock));
|
||||||
@@ -615,7 +617,7 @@ OEMCryptoResult UsageTable::MoveEntry(UsageTableEntry* entry,
|
|||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
sessions_[new_index] = sessions_[entry->index()];
|
sessions_[new_index] = sessions_[entry->index()];
|
||||||
sessions_[entry->index()] = 0;
|
sessions_[entry->index()] = nullptr;
|
||||||
|
|
||||||
entry->set_index(new_index);
|
entry->set_index(new_index);
|
||||||
generation_numbers_[new_index] = master_generation_number_;
|
generation_numbers_[new_index] = master_generation_number_;
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ class UsageTable {
|
|||||||
OEMCryptoResult ShrinkUsageTableHeader(uint32_t new_table_size,
|
OEMCryptoResult ShrinkUsageTableHeader(uint32_t new_table_size,
|
||||||
uint8_t* header_buffer,
|
uint8_t* header_buffer,
|
||||||
size_t* header_buffer_length);
|
size_t* header_buffer_length);
|
||||||
void ReleaseEntry(uint32_t index) { sessions_[index] = 0; }
|
void ReleaseEntry(uint32_t index) { sessions_[index] = nullptr; }
|
||||||
void IncrementGeneration();
|
void IncrementGeneration();
|
||||||
static size_t SignedHeaderSize(size_t count);
|
static size_t SignedHeaderSize(size_t count);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// source code may only be used and distributed under the Widevine
|
// source code may only be used and distributed under the Widevine
|
||||||
// License Agreement.
|
// License Agreement.
|
||||||
//
|
//
|
||||||
// Compute CRC32/MPEG2 Checksum. Needed for verification of WV Keybox.
|
// Compute CRC32 Checksum. Needed for verification of WV Keybox.
|
||||||
//
|
//
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "wvcrc32.h"
|
#include "wvcrc32.h"
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
// Copyright 2021 Google LLC. All Rights Reserved. This file and proprietary
|
|
||||||
// source code may only be used and distributed under the Widevine License
|
|
||||||
// Agreement.
|
|
||||||
//
|
|
||||||
// Reference implementation of OEMCrypto APIs
|
|
||||||
//
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
#include "wvcrc32.h"
|
|
||||||
|
|
||||||
namespace wvoec_ref {
|
|
||||||
|
|
||||||
uint32_t ComputeCrc32(const std::string& s) {
|
|
||||||
return wvcrc32(reinterpret_cast<const uint8_t*>(s.data()), s.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ComputeCrc32Cont(const std::string& s, uint32_t prev_crc) {
|
|
||||||
return wvcrc32Cont(reinterpret_cast<const uint8_t*>(s.data()), s.size(),
|
|
||||||
prev_crc);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(OEMCryptoWvCrc32Test, BasicTest) {
|
|
||||||
EXPECT_EQ(0xF88AC628, ComputeCrc32("abcdefg"));
|
|
||||||
EXPECT_EQ(0xDF520F72, ComputeCrc32("Widevine"));
|
|
||||||
EXPECT_EQ(0x0376E6E7, ComputeCrc32("123456789"));
|
|
||||||
EXPECT_EQ(0xBA62119E,
|
|
||||||
ComputeCrc32("The quick brown fox jumps over the lazy dog"));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(OEMCryptoWvCrc32Test, StreamTest) {
|
|
||||||
const std::vector<std::string> parts = {"The ", "quick", " brown ",
|
|
||||||
"fox", " jumps ", "over",
|
|
||||||
" the ", "lazy", " dog"};
|
|
||||||
uint32_t crc = wvcrc32Init();
|
|
||||||
for (const auto& part : parts) {
|
|
||||||
crc = ComputeCrc32Cont(part, crc);
|
|
||||||
}
|
|
||||||
EXPECT_EQ(0xBA62119E, crc);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(OEMCryptoWvCrc32Test, Keybox) {
|
|
||||||
// clang-format off
|
|
||||||
const uint8_t kKeyboxData[128] = {
|
|
||||||
// deviceID = WidevineCRCTestKeyBox
|
|
||||||
0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65,
|
|
||||||
0x43, 0x52, 0x43, 0x54, 0x65, 0x73, 0x74, 0x4b,
|
|
||||||
0x65, 0x79, 0x62, 0x6f, 0x78, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
// key = random
|
|
||||||
0x8a, 0x7c, 0xda, 0x3e, 0x09, 0xd9, 0x8e, 0xd5,
|
|
||||||
0x47, 0x47, 0x00, 0x84, 0x5a, 0x1f, 0x52, 0xd4,
|
|
||||||
// data = random
|
|
||||||
0x98, 0xa5, 0x00, 0x19, 0x8b, 0xfe, 0x54, 0xfd,
|
|
||||||
0xca, 0x4d, 0x26, 0xa3, 0xfa, 0xaa, 0x3b, 0x6c,
|
|
||||||
0x35, 0xfe, 0x03, 0x7c, 0xbf, 0x35, 0xba, 0xce,
|
|
||||||
0x31, 0xb5, 0x1e, 0x3c, 0x49, 0xd6, 0x3f, 0x9c,
|
|
||||||
0x3a, 0xde, 0x9b, 0x58, 0xcc, 0x54, 0x8d, 0xc0,
|
|
||||||
0x4b, 0x04, 0xcc, 0xee, 0xae, 0x4d, 0x9f, 0x90,
|
|
||||||
0xd3, 0xf3, 0xfe, 0x23, 0x26, 0x13, 0x56, 0x80,
|
|
||||||
0xe4, 0x3b, 0x79, 0x22, 0x69, 0x5d, 0xd6, 0xb7,
|
|
||||||
0xa0, 0x0e, 0x7e, 0x07, 0xcd, 0x1a, 0x15, 0xca,
|
|
||||||
// magic
|
|
||||||
'k', 'b', 'o', 'x',
|
|
||||||
// crc
|
|
||||||
0x09, 0x7b, 0x7e, 0xcc
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
const uint32_t crc_computed = wvcrc32n(kKeyboxData, 124);
|
|
||||||
uint32_t crc_current;
|
|
||||||
memcpy(&crc_current, &kKeyboxData[124], 4);
|
|
||||||
EXPECT_EQ(crc_computed, crc_current);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace wvoec_ref
|
|
||||||
Reference in New Issue
Block a user