Sync oemcrypto reference code

This is a merge from the Widevine repo of
http://go/wvgerrit/117311
Update backwards compatibility builds

http://go/wvgerrit/117423
Restrict maximum size of key id
To protect from out-of-memory found by fuzz testing.

http://go/wvgerrit/117683
Generation number should wrap

The master generation number should wrap around on overflow. This
means that we cannot use less than to check for a skew of 1.

http://go/wvgerrit/119232
Replace 0 with nullptr

Bug: 176234903
Bug: 184866351
Bug: 161243686
Test: ran unit tests (CL affects test code only)
Merged-In: Ie787bcf9c66a7605700c3dc29a8aa16406926ce3
Change-Id: I2b02a36a70a0920f31ffc00de102a23516d4b20e
This commit is contained in:
Fred Gylys-Colwell
2021-06-21 23:10:45 +00:00
parent 52d3c9f7c1
commit 830a7acc48
9 changed files with 30 additions and 95 deletions

View File

@@ -50,7 +50,7 @@ typedef enum SessionType {
class CryptoEngine {
public:
static const uint32_t kApiVersion = 16;
static const uint32_t kMinorApiVersion = 3;
static const uint32_t kMinorApiVersion = 4;
static const int64_t kTimeInfoUpdateWindowInSeconds = 300;
// This is like a factory method, except we choose which version to use at

View File

@@ -554,9 +554,12 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_QueryKeyControl(
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
uint32_t* block = reinterpret_cast<uint32_t*>(key_control_block);
if ((key_control_block_length == nullptr) ||
(*key_control_block_length < wvoec::KEY_CONTROL_SIZE)) {
if (key_control_block_length == nullptr) {
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
if (*key_control_block_length < wvoec::KEY_CONTROL_SIZE) {
LOGE("[OEMCrypto_QueryKeyControl(): OEMCrypto_ERROR_SHORT_BUFFER]");
*key_control_block_length = wvoec::KEY_CONTROL_SIZE;
return OEMCrypto_ERROR_SHORT_BUFFER;
}
*key_control_block_length = wvoec::KEY_CONTROL_SIZE;
@@ -572,6 +575,9 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_QueryKeyControl(
LOGE("[OEMCrypto_QueryKeyControl(): 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 =
std::vector<uint8_t>(key_id, key_id + key_id_length);
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]");
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 =
std::vector<uint8_t>(key_id, key_id + key_id_length);
return session_ctx->SelectContentKey(key_id_str, cipher_mode);
@@ -1272,7 +1280,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateRSASignature(
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (signature_length == 0) {
if (signature_length == nullptr) {
LOGE("[OEMCrypto_GenerateRSASignature(): OEMCrypto_ERROR_INVALID_CONTEXT]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
@@ -1289,8 +1297,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateRSASignature(
return OEMCrypto_ERROR_SHORT_BUFFER;
}
if (message == nullptr || message_length == 0 || signature == nullptr ||
signature_length == 0) {
if (message == nullptr || message_length == 0 || signature == nullptr) {
LOGE("[OEMCrypto_GenerateRSASignature(): OEMCrypto_ERROR_INVALID_CONTEXT]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}

View File

@@ -1,5 +1,5 @@
// 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.
//
// Reference implementation of OEMCrypto APIs

View File

@@ -1,5 +1,5 @@
// 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.
//
// Reference implementation of OEMCrypto APIs

View File

@@ -227,7 +227,7 @@ bool SessionContext::DeriveKey(const std::vector<uint8_t>& key,
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]");
CMAC_CTX_free(cmac_ctx);
return false;
@@ -521,7 +521,7 @@ OEMCryptoResult SessionContext::GenerateCertSignature(
size_t* signature_length) {
// TODO(b/67735947): Add ECC cert support.
if (message == nullptr || message_length == 0 || signature == nullptr ||
signature_length == 0) {
signature_length == nullptr) {
LOGE("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,
size_t* signature_length, RSA_Padding_Scheme padding_scheme) {
if (message == nullptr || message_length == 0 || signature == nullptr ||
signature_length == 0) {
signature_length == nullptr) {
LOGE("OEMCrypto_ERROR_INVALID_CONTEXT");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}

View File

@@ -407,11 +407,12 @@ OEMCryptoResult UsageTable::LoadUsageEntry(
if (new_entry->generation_number() != generation_numbers_[index]) {
LOGE("Generation SKEW: %ld -> %ld", new_entry->generation_number(),
generation_numbers_[index]);
if ((new_entry->generation_number() + 1 < generation_numbers_[index]) ||
(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])) {
status = OEMCrypto_WARNING_GENERATION_SKEW;
} else {
return OEMCrypto_ERROR_GENERATION_SKEW;
}
status = OEMCrypto_WARNING_GENERATION_SKEW;
}
sessions_[index] = session;
*entry = std::move(new_entry);
@@ -583,11 +584,12 @@ OEMCryptoResult UsageTable::LoadUsageTableHeader(
if (clear->master_generation != master_generation_number_) {
LOGE("Generation SKEW: %ld -> %ld", clear->master_generation,
master_generation_number_);
if ((clear->master_generation + 1 < master_generation_number_) ||
(clear->master_generation - 1 > master_generation_number_)) {
if ((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;
}
status = OEMCrypto_WARNING_GENERATION_SKEW;
}
int64_t* stored_generations =
reinterpret_cast<int64_t*>(&clear_buffer[0] + sizeof(SignedHeaderBlock));
@@ -615,7 +617,7 @@ OEMCryptoResult UsageTable::MoveEntry(UsageTableEntry* entry,
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
sessions_[new_index] = sessions_[entry->index()];
sessions_[entry->index()] = 0;
sessions_[entry->index()] = nullptr;
entry->set_index(new_index);
generation_numbers_[new_index] = master_generation_number_;

View File

@@ -107,7 +107,7 @@ class UsageTable {
OEMCryptoResult ShrinkUsageTableHeader(uint32_t new_table_size,
uint8_t* header_buffer,
size_t* header_buffer_length);
void ReleaseEntry(uint32_t index) { sessions_[index] = 0; }
void ReleaseEntry(uint32_t index) { sessions_[index] = nullptr; }
void IncrementGeneration();
static size_t SignedHeaderSize(size_t count);

View File

@@ -2,7 +2,7 @@
// source code may only be used and distributed under the Widevine
// 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 "wvcrc32.h"