Replace hardcoded parameters
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user