Replace hardcoded parameters

This commit is contained in:
Lu Chen
2020-01-27 16:05:15 -08:00
parent cdd4d97e0f
commit 5c42bf9b7f
134 changed files with 9510 additions and 1938 deletions

View File

@@ -17,7 +17,6 @@
#include "openssl/evp.h"
#include "openssl/hmac.h"
#include "openssl/sha.h"
#include "util/endian/endian.h"
namespace widevine {
namespace crypto_util {
@@ -41,6 +40,11 @@ const char kGroupKeyLabel[] = "GROUP_ENCRYPTION";
const char kPhonyGroupMasterKey[] = "fedcba9876543210";
const int kAes128KeySizeBits = 128;
const int kAes128KeySizeBytes = 16;
const int kAes256KeySizeBytes = 32;
const char kKeyboxV3Label[] = "Keyboxv3";
const int kAesBlockSizeBits = AES_BLOCK_SIZE * 8;
const int kAesMaxDerivedBlocks = 255;
const uint32_t kCENCSchemeID = 0x63656E63; // 'cenc' (AES-CTR): 0x63656E63
const uint32_t kCBC1SchemeID = 0x63626331; // 'cbc1' (AES-CBC): 0x63626331
@@ -51,7 +55,7 @@ const uint32_t kCBCSSchemeID =
// Creates a SHA-256 HMAC signature for the given message.
std::string CreateSignatureHmacSha256(absl::string_view key,
absl::string_view message) {
absl::string_view message) {
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init(&ctx, key.data(), key.size(), EVP_sha256());
@@ -74,7 +78,7 @@ bool VerifySignatureHmacSha256(absl::string_view key,
// Creates a SHA-1 HMAC signature for the given message.
std::string CreateSignatureHmacSha1(absl::string_view key,
absl::string_view message) {
absl::string_view message) {
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init(&ctx, key.data(), key.size(), EVP_sha1());
@@ -94,31 +98,45 @@ bool VerifySignatureHmacSha1(absl::string_view key, absl::string_view signature,
return CreateSignatureHmacSha1(key, message) == signature;
}
// Derives an AES 128 key from the provided key and additional info.
// Derives a key from the provided AES 128 or 256 key and additional info.
std::string DeriveKey(absl::string_view key, absl::string_view label,
absl::string_view context, const uint32_t size_bits) {
if (key.size() != kAes128KeySizeBytes) return "";
// We only handle even multiples of 16 bytes (128 bits) right now.
if ((size_bits % 128) || (size_bits > (128 * 255))) {
absl::string_view context, const uint32_t size_bits) {
// We only handle multiples of AES blocks (16 bytes) with a maximum of 255
// blocks.
const uint32_t output_block_count = size_bits / kAesBlockSizeBits;
if (size_bits % kAesBlockSizeBits ||
output_block_count > kAesMaxDerivedBlocks) {
return "";
}
std::string result;
const EVP_CIPHER* cipher = nullptr;
const size_t key_size_bytes = key.size();
const EVP_CIPHER* cipher = EVP_aes_128_cbc();
switch (key_size_bytes) {
case kAes128KeySizeBytes:
cipher = EVP_aes_128_cbc();
break;
case kAes256KeySizeBytes:
cipher = EVP_aes_256_cbc();
break;
default:
return "";
}
std::string result;
CMAC_CTX* cmac_ctx = CMAC_CTX_new();
for (unsigned char counter = 1; counter <= (size_bits / 128); counter++) {
if (CMAC_Init(cmac_ctx, key.data(), key.size(), cipher, 0)) {
for (unsigned char counter = 0; counter < output_block_count; counter++) {
if (CMAC_Init(cmac_ctx, key.data(), key_size_bytes, cipher, nullptr)) {
std::string message;
message.append(1, counter);
message.append(1, counter + 1);
message.append(label.data(), label.size());
message.append(1, '\0');
message.append(context.data(), context.size());
char size_string[4];
BigEndian::Store32(&size_string, size_bits);
message.append(&size_string[0], &size_string[0] + 4);
message.append(1, (size_bits >> 24) & 0xFF);
message.append(1, (size_bits >> 16) & 0xFF);
message.append(1, (size_bits >> 8) & 0xFF);
message.append(1, size_bits & 0xFF);
if (CMAC_Update(cmac_ctx, reinterpret_cast<const uint8_t*>(message.data()),
message.size())) {
size_t reslen;
@@ -146,12 +164,12 @@ std::string DeriveKeyId(absl::string_view context) {
}
std::string DeriveGroupSessionKey(absl::string_view context,
const uint32_t size_bits) {
const uint32_t size_bits) {
return DeriveKey(kPhonyGroupMasterKey, kGroupKeyLabel, context, size_bits);
}
std::string DeriveSigningKey(absl::string_view key, absl::string_view context,
const uint32_t size_bits) {
const uint32_t size_bits) {
return DeriveKey(key, kSigningKeyLabel, context, size_bits);
}