Source release 17.1.0

This commit is contained in:
John "Juce" Bruce
2022-07-07 17:14:31 -07:00
parent 8c17574083
commit 694cf6fb25
2233 changed files with 272026 additions and 223371 deletions

View File

@@ -0,0 +1,129 @@
// 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 utilities of OEMCrypto APIs
//
#include <gtest/gtest.h>
#include "cmac.h"
namespace wvoec {
namespace util {
namespace {
// Test vectors are from NIST Special Publication 800-38B for
// CMAC-AES-128 and CMAC-AES-256. The same data chunks are used
// for both tests.
const uint8_t kDataChunk1[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
const uint8_t kDataChunk2[] = {0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11};
const uint8_t kDataChunk3[] = {0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10};
const uint8_t kKey128[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
const uint8_t kKey256[32] = {0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4};
} // namespace
TEST(OEMCryptoCmacTest, BadInit) {
// If the parameters to the Create() function are invalid, the
// Cmac instance is not created.
std::unique_ptr<Cmac> cmac = Cmac::Create(nullptr, sizeof(kKey128));
EXPECT_FALSE(cmac);
cmac = Cmac::Create(nullptr, sizeof(kKey256));
EXPECT_FALSE(cmac);
cmac = Cmac::Create(kKey128, 0);
EXPECT_FALSE(cmac);
cmac = Cmac::Create(kKey256, (sizeof(kKey128) + sizeof(kKey256)) / 2);
EXPECT_FALSE(cmac);
}
TEST(OEMCryptoCmacTest, CmacAes128) {
std::unique_ptr<Cmac> cmac = Cmac::Create(kKey128, sizeof(kKey128));
ASSERT_TRUE(cmac);
std::vector<uint8_t> digest;
ASSERT_TRUE(cmac->Finalize(&digest));
const std::vector<uint8_t> kExpectedEmptyDigest = {
0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46};
EXPECT_EQ(kExpectedEmptyDigest, digest);
cmac->Reset();
ASSERT_TRUE(cmac->Update(kDataChunk1, sizeof(kDataChunk1)));
ASSERT_TRUE(cmac->Finalize(&digest));
const std::vector<uint8_t> kExpectedDigest1 = {
0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c};
EXPECT_EQ(kExpectedDigest1, digest);
cmac->Reset();
ASSERT_TRUE(cmac->Update(kDataChunk1, sizeof(kDataChunk1)));
ASSERT_TRUE(cmac->Update(kDataChunk2, sizeof(kDataChunk2)));
ASSERT_TRUE(cmac->Finalize(&digest));
const std::vector<uint8_t> kExpectedDigest2 = {
0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27};
EXPECT_EQ(kExpectedDigest2, digest);
cmac->Reset();
ASSERT_TRUE(cmac->Update(kDataChunk1, sizeof(kDataChunk1)));
for (size_t i = 0; i < sizeof(kDataChunk2); i++) {
ASSERT_TRUE(cmac->Update(kDataChunk2[i])) << " i = " << i;
}
ASSERT_TRUE(cmac->Update(kDataChunk3, sizeof(kDataChunk3)));
ASSERT_TRUE(cmac->Finalize(&digest));
const std::vector<uint8_t> kExpectedDigest3 = {
0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe};
EXPECT_EQ(kExpectedDigest3, digest);
}
TEST(OEMCryptoCmacTest, CmacAes256) {
std::unique_ptr<Cmac> cmac = Cmac::Create(kKey256, sizeof(kKey256));
ASSERT_TRUE(cmac);
std::vector<uint8_t> digest;
ASSERT_TRUE(cmac->Finalize(&digest));
const std::vector<uint8_t> kExpectedEmptyDigest = {
0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e,
0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83};
EXPECT_EQ(kExpectedEmptyDigest, digest);
cmac->Reset();
ASSERT_TRUE(cmac->Update(kDataChunk1, sizeof(kDataChunk1)));
ASSERT_TRUE(cmac->Finalize(&digest));
const std::vector<uint8_t> kExpectedDigest1 = {
0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82,
0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c};
EXPECT_EQ(kExpectedDigest1, digest);
cmac->Reset();
ASSERT_TRUE(cmac->Update(kDataChunk1, sizeof(kDataChunk1)));
ASSERT_TRUE(cmac->Update(kDataChunk2, sizeof(kDataChunk2)));
ASSERT_TRUE(cmac->Finalize(&digest));
const std::vector<uint8_t> kExpectedDigest2 = {
0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2,
0x32, 0xf5, 0xb1, 0x69, 0xb9, 0xc9, 0x11, 0xe6};
EXPECT_EQ(kExpectedDigest2, digest);
cmac->Reset();
ASSERT_TRUE(cmac->Update(kDataChunk1, sizeof(kDataChunk1)));
for (size_t i = 0; i < sizeof(kDataChunk2); i++) {
ASSERT_TRUE(cmac->Update(kDataChunk2[i])) << " i = " << i;
}
ASSERT_TRUE(cmac->Update(kDataChunk3, sizeof(kDataChunk3)));
ASSERT_TRUE(cmac->Finalize(&digest));
const std::vector<uint8_t> kExpectedDigest3 = {
0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5,
0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10};
EXPECT_EQ(kExpectedDigest3, digest);
}
} // namespace util
} // namespace wvoec

View File

@@ -0,0 +1,597 @@
// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine License
// Agreement.
//
// Reference implementation utilities of OEMCrypto APIs
//
#include <ostream>
#include <gtest/gtest.h>
#include "hmac.h"
#include "string_conversions.h"
namespace wvoec {
namespace util {
namespace {
struct HmacTestVector {
std::vector<uint8_t> key;
std::vector<uint8_t> message;
std::vector<uint8_t> signature;
std::vector<uint8_t> signature_sha1;
};
void PrintTo(const HmacTestVector& v, std::ostream* os) {
constexpr size_t kMaxSize = 32;
*os << "{";
if (v.key.size() > kMaxSize) {
std::vector<uint8_t> short_short(v.key.begin(), v.key.begin() + kMaxSize);
*os << "key = " << wvutil::b2a_hex(short_short);
*os << "... (size = " << std::to_string(v.key.size()) << "), ";
} else {
*os << "key = " << wvutil::b2a_hex(v.key) << ", ";
}
if (v.message.size() > kMaxSize) {
std::vector<uint8_t> short_message(v.message.begin(),
v.message.begin() + kMaxSize);
*os << "message = " << wvutil::b2a_hex(short_message);
*os << "... (size = " << std::to_string(v.message.size()) << "), ";
} else {
*os << "message = " << wvutil::b2a_hex(v.message) << ", ";
}
*os << "signature = " << wvutil::b2a_hex(v.signature) << ", ";
*os << "signature_sha1 = " << wvutil::b2a_hex(v.signature_sha1) << "}";
}
std::vector<uint8_t> FromString(const std::string& s) {
return std::vector<uint8_t>(s.begin(), s.end());
}
// Test vectors come from RFC4231 Section 4 (test case 5 is omitted).
const HmacTestVector kHmacTestVectorList[] = {
{/* key = */ wvutil::a2b_hex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"),
/* message = */ FromString("Hi There"),
/* signature = */
wvutil::a2b_hex(
"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"),
/* signature_sha1 = */
wvutil::a2b_hex("b617318655057264e28bc0b6fb378c8ef146be00")},
{/* key = */ FromString("Jefe"),
/* message = */ FromString("what do ya want for nothing?"),
/* signature = */
wvutil::a2b_hex(
"5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"),
/* signature_sha1 = */
wvutil::a2b_hex("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79")},
{/* key = */ std::vector<uint8_t>(20, 0xaa),
/* message = */ std::vector<uint8_t>(50, 0xdd),
/* signature = */
wvutil::a2b_hex(
"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe"),
/* signature_sha1 = */
wvutil::a2b_hex("125d7342b9ac11cd91a39af48aa17b4f63f175d3")},
{/* key = */ wvutil::a2b_hex(
"0102030405060708090a0b0c0d0e0f10111213141516171819"),
/* message = */ std::vector<uint8_t>(50, 0xcd),
/* signature = */
wvutil::a2b_hex(
"82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"),
/* signature_sha1 = */
wvutil::a2b_hex("4c9007f4026250c6bc8414f9bf50c86c2d7235da")},
{/* key = */ std::vector<uint8_t>(131, 0xaa),
/* message = */
FromString("Test Using Larger Than Block-Size Key - Hash Key First"),
/* signature = */
wvutil::a2b_hex(
"60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54"),
/* signature_sha1 = */
wvutil::a2b_hex("90d0dace1c1bdc957339307803160335bde6df2b")},
{/* key = */ std::vector<uint8_t>(131, 0xaa),
/* message = */
FromString(
"This is a test using a larger than block-size key and a larger "
"than block-size data. The key needs to be hashed before being "
"used by the HMAC algorithm."),
/* signature = */
wvutil::a2b_hex(
"9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2"),
/* signature_sha1 = */
wvutil::a2b_hex("217e44bb08b6e06a2d6c30f3cb9f537f97c63356")}};
const std::vector<uint8_t> kEmptyVector;
const std::string kEmptyString;
} // namespace
TEST(OEMCryptoHmacApiTest, GenerateSignatureSha1_InvalidParameters) {
const std::vector<uint8_t> key = kHmacTestVectorList[0].key;
const std::vector<uint8_t> message = kHmacTestVectorList[0].message;
// Pointers only.
size_t signature_length = kHmacSha256SignatureSize;
std::vector<uint8_t> signature(signature_length);
OEMCryptoResult result =
HmacSha1(nullptr, key.size(), message.data(), message.size(),
signature.data(), &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key = nullptr";
result = HmacSha1(key.data(), 0, message.data(), message.size(),
signature.data(), &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key_length = 0";
result = HmacSha1(key.data(), key.size(), nullptr, message.size(),
signature.data(), &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message = nullptr";
result = HmacSha1(key.data(), key.size(), message.data(), 0, signature.data(),
&signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message_length = 0";
result = HmacSha1(key.data(), key.size(), message.data(), message.size(),
nullptr, &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "signature = nullptr";
result = HmacSha1(key.data(), key.size(), message.data(), message.size(),
signature.data(), nullptr);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT)
<< "signature_length = nullptr";
// Vector key.
result = HmacSha1(kEmptyVector, message.data(), message.size(),
signature.data(), &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key = <empty>";
result = HmacSha1(key, nullptr, message.size(), signature.data(),
&signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message = nullptr";
result =
HmacSha1(key, message.data(), 0, signature.data(), &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message_length = 0";
result =
HmacSha1(key, message.data(), message.size(), nullptr, &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "signature = nullptr";
result =
HmacSha1(key, message.data(), message.size(), signature.data(), nullptr);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT)
<< "signature_length = nullptr";
// Vector message, vector output.
signature = HmacSha1(kEmptyVector, message);
EXPECT_TRUE(signature.empty()) << "key = <empty>";
signature = HmacSha1(key, kEmptyVector);
EXPECT_TRUE(signature.empty()) << "message = <empty>";
}
TEST(OEMCryptoHmacApiTest, GenerateSignature_InvalidParameters) {
const std::vector<uint8_t> key = kHmacTestVectorList[0].key;
const std::vector<uint8_t> message = kHmacTestVectorList[0].message;
// Pointers only.
size_t signature_length = kHmacSha256SignatureSize;
std::vector<uint8_t> signature(signature_length);
OEMCryptoResult result =
HmacSha256(nullptr, key.size(), message.data(), message.size(),
signature.data(), &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key = nullptr";
result = HmacSha256(key.data(), 0, message.data(), message.size(),
signature.data(), &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key_length = 0";
result = HmacSha256(key.data(), key.size(), nullptr, message.size(),
signature.data(), &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message = nullptr";
result = HmacSha256(key.data(), key.size(), message.data(), 0,
signature.data(), &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message_length = 0";
result = HmacSha256(key.data(), key.size(), message.data(), message.size(),
nullptr, &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "signature = nullptr";
result = HmacSha256(key.data(), key.size(), message.data(), message.size(),
signature.data(), nullptr);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT)
<< "signature_length = nullptr";
// Vector key.
result = HmacSha256(kEmptyVector, message.data(), message.size(),
signature.data(), &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key = <empty>";
result = HmacSha256(key, nullptr, message.size(), signature.data(),
&signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message = nullptr";
result =
HmacSha256(key, message.data(), 0, signature.data(), &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message_length = 0";
result = HmacSha256(key, message.data(), message.size(), nullptr,
&signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "signature = nullptr";
result = HmacSha256(key, message.data(), message.size(), signature.data(),
nullptr);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT)
<< "signature_length = nullptr";
// Vector message, vector output signature parameter.
signature.clear();
EXPECT_FALSE(HmacSha256(kEmptyVector, message, &signature))
<< "key = <empty>";
EXPECT_FALSE(HmacSha256(key, kEmptyVector, &signature))
<< "message = <empty>";
EXPECT_FALSE(HmacSha256(key, message, nullptr)) << "signature = nullptr";
// String message, vector output signature parameter.
const std::string message_str(message.begin(), message.end());
EXPECT_FALSE(HmacSha256(kEmptyVector, message_str, &signature))
<< "key = <empty>";
EXPECT_FALSE(HmacSha256(key, kEmptyString, &signature))
<< "message = <empty>";
EXPECT_FALSE(HmacSha256(key, message_str, nullptr)) << "signature = nullptr";
// Pointer message, vector output.
signature = HmacSha256(kEmptyVector, message.data(), message.size());
EXPECT_TRUE(signature.empty()) << "key = <empty>";
signature = HmacSha256(key, nullptr, message.size());
EXPECT_TRUE(signature.empty()) << "message = nullptr";
signature = HmacSha256(key, message.data(), 0);
EXPECT_TRUE(signature.empty()) << "message_length = 0";
// Vector message, vector output.
signature = HmacSha256(kEmptyVector, message);
EXPECT_TRUE(signature.empty()) << "key = <empty>";
signature = HmacSha256(key, kEmptyVector);
EXPECT_TRUE(signature.empty()) << "message = <empty>";
// String message, vector output.
signature = HmacSha256(kEmptyVector, message_str);
EXPECT_TRUE(signature.empty()) << "key = <empty>";
signature = HmacSha256(key, kEmptyString);
EXPECT_TRUE(signature.empty()) << "message = <empty>";
}
TEST(OEMCryptoHmacApiTest, VerifySignatureSha1_InvalidParameters) {
const std::vector<uint8_t> key = kHmacTestVectorList[0].key;
const std::vector<uint8_t> message = kHmacTestVectorList[0].message;
const std::vector<uint8_t> signature = kHmacTestVectorList[0].signature_sha1;
// Pointers only.
OEMCryptoResult result =
HmacSha1Verify(nullptr, key.size(), message.data(), message.size(),
signature.data(), signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key = nullptr";
result = HmacSha1Verify(key.data(), 0, message.data(), message.size(),
signature.data(), signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key_length = 0";
result = HmacSha1Verify(key.data(), key.size(), nullptr, message.size(),
signature.data(), signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message = nullptr";
result = HmacSha1Verify(key.data(), key.size(), message.data(), 0,
signature.data(), signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message_length = 0";
result = HmacSha1Verify(key.data(), key.size(), message.data(),
message.size(), nullptr, signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "signature = nullptr";
result = HmacSha1Verify(key.data(), key.size(), message.data(),
message.size(), signature.data(), 0);
EXPECT_EQ(result, OEMCrypto_ERROR_SIGNATURE_FAILURE)
<< "signature_length = 0";
// Vector key, pointer others.
result = HmacSha1Verify(kEmptyVector, message.data(), message.size(),
signature.data(), signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key = <empty>";
result = HmacSha1Verify(key, nullptr, message.size(), signature.data(),
signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message = nullptr";
result = HmacSha1Verify(key, message.data(), 0, signature.data(),
signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message_length = 0";
result = HmacSha1Verify(key, message.data(), message.size(), nullptr,
signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "signature = nullptr";
result =
HmacSha1Verify(key, message.data(), message.size(), signature.data(), 0);
EXPECT_EQ(result, OEMCrypto_ERROR_SIGNATURE_FAILURE)
<< "signature_length = 0";
// Vector only.
result = HmacSha1Verify(kEmptyVector, message, signature);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key = <empty>";
result = HmacSha1Verify(key, kEmptyVector, signature);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message = <empty>";
result = HmacSha1Verify(key, message, kEmptyVector);
EXPECT_EQ(result, OEMCrypto_ERROR_SIGNATURE_FAILURE) << "signature = <empty>";
}
TEST(OEMCryptoHmacApiTest, VerifySignature_InvalidParameters) {
const std::vector<uint8_t> key = kHmacTestVectorList[0].key;
const std::vector<uint8_t> message = kHmacTestVectorList[0].message;
const std::vector<uint8_t> signature = kHmacTestVectorList[0].signature;
// Pointers only.
OEMCryptoResult result =
HmacSha256Verify(nullptr, key.size(), message.data(), message.size(),
signature.data(), signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key = nullptr";
result = HmacSha256Verify(key.data(), 0, message.data(), message.size(),
signature.data(), signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key_length = 0";
result = HmacSha256Verify(key.data(), key.size(), nullptr, message.size(),
signature.data(), signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message = nullptr";
result = HmacSha256Verify(key.data(), key.size(), message.data(), 0,
signature.data(), signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message_length = 0";
result = HmacSha256Verify(key.data(), key.size(), message.data(),
message.size(), nullptr, signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "signature = nullptr";
result = HmacSha256Verify(key.data(), key.size(), message.data(),
message.size(), signature.data(), 0);
EXPECT_EQ(result, OEMCrypto_ERROR_SIGNATURE_FAILURE)
<< "signature_length = 0";
// Vector key, pointer others.
result = HmacSha256Verify(kEmptyVector, message.data(), message.size(),
signature.data(), signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key = <empty>";
result = HmacSha256Verify(key, nullptr, message.size(), signature.data(),
signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message = nullptr";
result = HmacSha256Verify(key, message.data(), 0, signature.data(),
signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message_length = 0";
result = HmacSha256Verify(key, message.data(), message.size(), nullptr,
signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "signature = nullptr";
result = HmacSha256Verify(key, message.data(), message.size(),
signature.data(), 0);
EXPECT_EQ(result, OEMCrypto_ERROR_SIGNATURE_FAILURE)
<< "signature_length = 0";
// Vector only.
result = HmacSha256Verify(kEmptyVector, message, signature);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key = <empty>";
result = HmacSha256Verify(key, kEmptyVector, signature);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message = <empty>";
result = HmacSha256Verify(key, message, kEmptyVector);
EXPECT_EQ(result, OEMCrypto_ERROR_SIGNATURE_FAILURE) << "signature = <empty>";
// String message, vector others.
const std::string message_str(message.begin(), message.end());
result = HmacSha256Verify(kEmptyVector, message_str, signature);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "key = <empty>";
result = HmacSha256Verify(key, kEmptyString, signature);
EXPECT_EQ(result, OEMCrypto_ERROR_INVALID_CONTEXT) << "message = <empty>";
result = HmacSha256Verify(key, message_str, kEmptyVector);
EXPECT_EQ(result, OEMCrypto_ERROR_SIGNATURE_FAILURE) << "signature = <empty>";
}
class OEMCryptoHmacTest : public testing::TestWithParam<HmacTestVector> {
public:
void SetUp() override {
HmacTestVector v = GetParam();
key_ = std::move(v.key);
message_ = std::move(v.message);
expected_signature_ = std::move(v.signature);
expected_signature_sha1_ = std::move(v.signature_sha1);
ASSERT_FALSE(key_.empty()) << "Missing test key";
ASSERT_FALSE(message_.empty()) << "Missing test message";
ASSERT_EQ(expected_signature_.size(), kHmacSha256SignatureSize)
<< "Invalid test HMAC-SHA-256 signature";
ASSERT_EQ(expected_signature_sha1_.size(), kHmacSha1SignatureSize)
<< "Invalid test HMAC-SHA-1 signature";
}
void TearDown() override {
key_.clear();
message_.clear();
expected_signature_.clear();
expected_signature_sha1_.clear();
}
std::string GetStringMessage() const {
return std::string(message_.begin(), message_.end());
}
std::vector<uint8_t> GenerateBadSignature() const {
std::vector<uint8_t> bad_signature = expected_signature_;
bad_signature[kHmacSha256SignatureSize / 2] ^= 0x87;
return bad_signature;
}
std::vector<uint8_t> GenerateBadSignatureSha1() const {
std::vector<uint8_t> bad_signature = expected_signature_sha1_;
bad_signature[kHmacSha1SignatureSize / 2] ^= 0x87;
return bad_signature;
}
protected:
std::vector<uint8_t> key_;
std::vector<uint8_t> message_;
std::vector<uint8_t> expected_signature_;
std::vector<uint8_t> expected_signature_sha1_;
};
TEST_P(OEMCryptoHmacTest, GenerateSignatureSha1_PointersOnly) {
size_t signature_length = 0;
OEMCryptoResult result =
HmacSha1(key_.data(), key_.size(), message_.data(), message_.size(),
nullptr, &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_SHORT_BUFFER);
EXPECT_EQ(signature_length, kHmacSha1SignatureSize);
signature_length = kHmacSha1SignatureSize * 2;
std::vector<uint8_t> signature(signature_length);
result = HmacSha1(key_.data(), key_.size(), message_.data(), message_.size(),
signature.data(), &signature_length);
EXPECT_EQ(result, OEMCrypto_SUCCESS);
EXPECT_EQ(signature_length, kHmacSha1SignatureSize);
signature.resize(kHmacSha1SignatureSize);
EXPECT_EQ(signature, expected_signature_sha1_);
}
TEST_P(OEMCryptoHmacTest, GenerateSignatureSha1_VectorKeyPointerOther) {
size_t signature_length = 0;
OEMCryptoResult result = HmacSha1(key_, message_.data(), message_.size(),
nullptr, &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_SHORT_BUFFER);
EXPECT_EQ(signature_length, kHmacSha1SignatureSize);
signature_length = kHmacSha1SignatureSize * 2;
std::vector<uint8_t> signature(signature_length);
result = HmacSha1(key_, message_.data(), message_.size(), signature.data(),
&signature_length);
EXPECT_EQ(result, OEMCrypto_SUCCESS);
EXPECT_EQ(signature_length, kHmacSha1SignatureSize);
signature.resize(kHmacSha1SignatureSize);
EXPECT_EQ(signature, expected_signature_sha1_);
}
TEST_P(OEMCryptoHmacTest, GenerateSignatureSha1_VectorMessageVectorResult) {
const std::vector<uint8_t> signature = HmacSha1(key_, message_);
EXPECT_EQ(signature.size(), kHmacSha1SignatureSize);
EXPECT_EQ(signature, expected_signature_sha1_);
}
TEST_P(OEMCryptoHmacTest, GenerateSignature_PointersOnly) {
size_t signature_length = 0;
OEMCryptoResult result =
HmacSha256(key_.data(), key_.size(), message_.data(), message_.size(),
nullptr, &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_SHORT_BUFFER);
EXPECT_EQ(signature_length, kHmacSha256SignatureSize);
signature_length = kHmacSha256SignatureSize * 2;
std::vector<uint8_t> signature(signature_length);
result = HmacSha256(key_.data(), key_.size(), message_.data(),
message_.size(), signature.data(), &signature_length);
EXPECT_EQ(result, OEMCrypto_SUCCESS);
EXPECT_EQ(signature_length, kHmacSha256SignatureSize);
signature.resize(kHmacSha256SignatureSize);
EXPECT_EQ(signature, expected_signature_);
}
TEST_P(OEMCryptoHmacTest, GenerateSignature_VectorKeyPointerOther) {
size_t signature_length = 0;
OEMCryptoResult result = HmacSha256(key_, message_.data(), message_.size(),
nullptr, &signature_length);
EXPECT_EQ(result, OEMCrypto_ERROR_SHORT_BUFFER);
EXPECT_EQ(signature_length, kHmacSha256SignatureSize);
signature_length = kHmacSha256SignatureSize * 2;
std::vector<uint8_t> signature(signature_length);
result = HmacSha256(key_, message_.data(), message_.size(), signature.data(),
&signature_length);
EXPECT_EQ(result, OEMCrypto_SUCCESS);
EXPECT_EQ(signature_length, kHmacSha256SignatureSize);
signature.resize(kHmacSha256SignatureSize);
EXPECT_EQ(signature, expected_signature_);
}
TEST_P(OEMCryptoHmacTest, GenerateSignature_VectorMessageVectorOutputArgument) {
std::vector<uint8_t> signature;
EXPECT_TRUE(HmacSha256(key_, message_, &signature));
EXPECT_EQ(signature.size(), kHmacSha256SignatureSize);
EXPECT_EQ(signature, expected_signature_);
}
TEST_P(OEMCryptoHmacTest, GenerateSignature_StringMessageVectorOutputArgument) {
const std::string message_str = GetStringMessage();
std::vector<uint8_t> signature;
EXPECT_TRUE(HmacSha256(key_, message_str, &signature));
EXPECT_EQ(signature.size(), kHmacSha256SignatureSize);
EXPECT_EQ(signature, expected_signature_);
}
TEST_P(OEMCryptoHmacTest, GenerateSignature_PointerMessageVectorResult) {
const std::vector<uint8_t> signature =
HmacSha256(key_, message_.data(), message_.size());
EXPECT_EQ(signature.size(), kHmacSha256SignatureSize);
EXPECT_EQ(signature, expected_signature_);
}
TEST_P(OEMCryptoHmacTest, GenerateSignature_VectorMessageVectorResult) {
const std::vector<uint8_t> signature = HmacSha256(key_, message_);
EXPECT_EQ(signature.size(), kHmacSha256SignatureSize);
EXPECT_EQ(signature, expected_signature_);
}
TEST_P(OEMCryptoHmacTest, GenerateSignature_StringMessageVectorResult) {
const std::string message_str = GetStringMessage();
const std::vector<uint8_t> signature = HmacSha256(key_, message_str);
EXPECT_EQ(signature.size(), kHmacSha256SignatureSize);
EXPECT_EQ(signature, expected_signature_);
}
TEST_P(OEMCryptoHmacTest, VerifySignatureSha1_PointersOnly) {
OEMCryptoResult result = HmacSha1Verify(
key_.data(), key_.size(), message_.data(), message_.size(),
expected_signature_sha1_.data(), expected_signature_sha1_.size());
EXPECT_EQ(result, OEMCrypto_SUCCESS);
const std::vector<uint8_t> bad_signature = GenerateBadSignatureSha1();
result =
HmacSha1Verify(key_.data(), key_.size(), message_.data(), message_.size(),
bad_signature.data(), bad_signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_SIGNATURE_FAILURE);
}
TEST_P(OEMCryptoHmacTest, VerifySignatureSha1_VectorKeyPointerOther) {
OEMCryptoResult result = HmacSha1Verify(
key_, message_.data(), message_.size(), expected_signature_sha1_.data(),
expected_signature_sha1_.size());
EXPECT_EQ(result, OEMCrypto_SUCCESS);
const std::vector<uint8_t> bad_signature = GenerateBadSignatureSha1();
result = HmacSha1Verify(key_, message_.data(), message_.size(),
bad_signature.data(), bad_signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_SIGNATURE_FAILURE);
}
TEST_P(OEMCryptoHmacTest, VerifySignatureSha1_VectorsOnly) {
OEMCryptoResult result =
HmacSha1Verify(key_, message_, expected_signature_sha1_);
EXPECT_EQ(result, OEMCrypto_SUCCESS);
const std::vector<uint8_t> bad_signature = GenerateBadSignatureSha1();
result = HmacSha1Verify(key_, message_, bad_signature);
EXPECT_EQ(result, OEMCrypto_ERROR_SIGNATURE_FAILURE);
}
TEST_P(OEMCryptoHmacTest, VerifySignature_PointersOnly) {
OEMCryptoResult result = HmacSha256Verify(
key_.data(), key_.size(), message_.data(), message_.size(),
expected_signature_.data(), expected_signature_.size());
EXPECT_EQ(result, OEMCrypto_SUCCESS);
const std::vector<uint8_t> bad_signature = GenerateBadSignature();
result = HmacSha256Verify(key_.data(), key_.size(), message_.data(),
message_.size(), bad_signature.data(),
bad_signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_SIGNATURE_FAILURE);
}
TEST_P(OEMCryptoHmacTest, VerifySignature_VectorKeyPointerOther) {
OEMCryptoResult result =
HmacSha256Verify(key_, message_.data(), message_.size(),
expected_signature_.data(), expected_signature_.size());
EXPECT_EQ(result, OEMCrypto_SUCCESS);
const std::vector<uint8_t> bad_signature = GenerateBadSignature();
result = HmacSha256Verify(key_, message_.data(), message_.size(),
bad_signature.data(), bad_signature.size());
EXPECT_EQ(result, OEMCrypto_ERROR_SIGNATURE_FAILURE);
}
TEST_P(OEMCryptoHmacTest, VerifySignature_VectorsOnly) {
OEMCryptoResult result =
HmacSha256Verify(key_, message_, expected_signature_);
EXPECT_EQ(result, OEMCrypto_SUCCESS);
const std::vector<uint8_t> bad_signature = GenerateBadSignature();
result = HmacSha256Verify(key_, message_, bad_signature);
EXPECT_EQ(result, OEMCrypto_ERROR_SIGNATURE_FAILURE);
}
TEST_P(OEMCryptoHmacTest, VerifySignature_StringMessageVectorOther) {
const std::string message_str = GetStringMessage();
OEMCryptoResult result =
HmacSha256Verify(key_, message_str, expected_signature_);
EXPECT_EQ(result, OEMCrypto_SUCCESS);
const std::vector<uint8_t> bad_signature = GenerateBadSignature();
result = HmacSha256Verify(key_, message_str, bad_signature);
EXPECT_EQ(result, OEMCrypto_ERROR_SIGNATURE_FAILURE);
}
INSTANTIATE_TEST_SUITE_P(HmacVectors, OEMCryptoHmacTest,
testing::ValuesIn(kHmacTestVectorList));
} // namespace util
} // namespace wvoec

View File

@@ -0,0 +1,532 @@
// Copyright 2021 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine License
// Agreement.
#include "oem_cert.h"
namespace wvoec_ref {
namespace {
const uint32_t kTestOemSystemId = 7913;
// clang-format off
// OEM Certificate private key.
// RSA Private-Key: (2048 bit, 2 primes).
const uint8_t kTestOemPrivateKey[] = {
0x30, 0x82, 0x04, 0xbd, 0x02, 0x01, 0x00, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
0x04, 0xa7, 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01,
0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa8, 0x75,
0xd5, 0x3d, 0xd3, 0xf3, 0x59, 0xd1, 0x63, 0x0f,
0x5d, 0x5f, 0x2c, 0xaf, 0x80, 0x4e, 0x9a, 0xef,
0x9a, 0x8f, 0x88, 0x37, 0xe5, 0x56, 0xf8, 0x66,
0xcb, 0xa6, 0x61, 0xab, 0xc1, 0xa9, 0x04, 0xc2,
0x12, 0x9d, 0xa6, 0x0c, 0x2c, 0xcb, 0x42, 0x09,
0xd0, 0x36, 0xf0, 0x85, 0x01, 0xdf, 0xd5, 0xbd,
0xaf, 0x82, 0xbb, 0x25, 0xa1, 0x61, 0x17, 0xfe,
0xa1, 0x65, 0x34, 0xda, 0x91, 0xee, 0x91, 0x46,
0xd6, 0x63, 0x47, 0x6a, 0xa5, 0x32, 0x62, 0xe2,
0x4c, 0x7c, 0xf7, 0x76, 0x59, 0xe1, 0x2b, 0x47,
0x8d, 0x1c, 0xe6, 0xa0, 0xbd, 0xc3, 0xc9, 0x36,
0x0e, 0x90, 0x75, 0xba, 0x1c, 0xbd, 0xca, 0x85,
0x0a, 0x4e, 0xcc, 0xfe, 0x91, 0x3f, 0x22, 0x42,
0x96, 0xae, 0xa0, 0x87, 0x82, 0x63, 0x3b, 0x22,
0x54, 0xbc, 0x28, 0xa3, 0x45, 0x4b, 0x34, 0x12,
0x4e, 0xeb, 0x04, 0x4d, 0x29, 0xb3, 0x05, 0x62,
0x0d, 0x51, 0x16, 0x46, 0x98, 0x21, 0xc8, 0x59,
0x96, 0x53, 0x43, 0x38, 0x95, 0x1a, 0x42, 0x94,
0x8b, 0x49, 0x5d, 0x1b, 0x8a, 0xd5, 0x82, 0x6a,
0x32, 0x6f, 0x0e, 0x5a, 0x85, 0x3b, 0xd5, 0x42,
0xc0, 0x4c, 0x34, 0x43, 0x7c, 0x4f, 0xef, 0xca,
0x02, 0x99, 0x38, 0xf9, 0xa5, 0xc0, 0xd8, 0x1d,
0xe7, 0x9e, 0x8c, 0x4d, 0x9c, 0x40, 0xcd, 0x4b,
0x5e, 0x44, 0x37, 0x8d, 0xc5, 0x96, 0xd4, 0xf7,
0xb3, 0x37, 0x4c, 0x2e, 0x2d, 0x30, 0xca, 0x97,
0x39, 0xed, 0xe8, 0x73, 0xc5, 0xe7, 0xcb, 0x95,
0xf0, 0x84, 0x4a, 0x5a, 0x9e, 0x13, 0x19, 0x5f,
0x98, 0xe5, 0xbe, 0x31, 0x5b, 0xff, 0xed, 0x29,
0x26, 0xc4, 0x93, 0x54, 0x49, 0x84, 0xd2, 0xeb,
0x21, 0x40, 0x19, 0x5f, 0xf7, 0x32, 0x67, 0x93,
0xe0, 0xda, 0x77, 0xfc, 0xda, 0x5e, 0xc4, 0x5b,
0x95, 0x2e, 0x46, 0xf3, 0xce, 0xfd, 0x02, 0x03,
0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x01, 0x00,
0x9e, 0x6d, 0x82, 0xc8, 0x0c, 0xc6, 0xb5, 0xd7,
0xa7, 0xb3, 0xd1, 0x7a, 0x2a, 0x8a, 0x3a, 0xbe,
0xb2, 0x13, 0x58, 0x66, 0x58, 0x13, 0x49, 0x4a,
0x0b, 0x7e, 0x91, 0x53, 0xbe, 0x53, 0x4b, 0x63,
0xeb, 0x27, 0xa1, 0x5e, 0x45, 0xc4, 0xf9, 0x73,
0x86, 0x7d, 0xb8, 0x25, 0x92, 0xf9, 0x63, 0x93,
0xe0, 0x6d, 0xed, 0xdb, 0xa2, 0xa9, 0x77, 0x25,
0xda, 0xed, 0x0b, 0x58, 0x24, 0xe6, 0xd1, 0x8b,
0x6d, 0x71, 0x13, 0x3a, 0x76, 0xf5, 0xa2, 0xba,
0xca, 0x28, 0x4d, 0x0a, 0xd1, 0xa7, 0xaa, 0x4b,
0x8a, 0xea, 0x55, 0x99, 0xb2, 0x83, 0xc5, 0x33,
0x95, 0xcd, 0x92, 0xd0, 0xe5, 0x06, 0xcc, 0xf4,
0xe8, 0xbb, 0x49, 0xc0, 0x66, 0x25, 0x9a, 0xef,
0xa7, 0x06, 0xbc, 0xb3, 0x2a, 0x21, 0x86, 0xcc,
0x4f, 0xd6, 0xaf, 0x9d, 0xed, 0x11, 0xef, 0x9f,
0x14, 0x2f, 0x8b, 0xac, 0x96, 0x75, 0x03, 0x1a,
0xe4, 0x5c, 0x48, 0x81, 0x3a, 0x4b, 0x21, 0x6e,
0xad, 0xb3, 0x27, 0x51, 0xe9, 0x35, 0xbe, 0xed,
0x42, 0x5f, 0x8f, 0x83, 0xf0, 0x99, 0xb0, 0xaf,
0xa9, 0x9c, 0x2f, 0xee, 0x5f, 0xee, 0x39, 0x2b,
0x1d, 0xb0, 0xb1, 0xf8, 0x7b, 0x69, 0x38, 0x68,
0xae, 0xa0, 0x36, 0x2a, 0xf5, 0xed, 0x96, 0xfa,
0x7c, 0x1c, 0x59, 0x29, 0xbf, 0xb3, 0x9e, 0x14,
0x97, 0x06, 0xc2, 0x40, 0x30, 0x00, 0x6a, 0x95,
0xd3, 0x86, 0x86, 0xb9, 0x4c, 0xf5, 0x51, 0xa3,
0x6d, 0x5a, 0xd1, 0x46, 0x43, 0x24, 0xa4, 0xa9,
0x59, 0xcf, 0xa2, 0xa7, 0x4e, 0x50, 0x7a, 0xa3,
0x14, 0xe4, 0x4e, 0x32, 0x4d, 0xd4, 0xc2, 0xcf,
0x2d, 0x74, 0xfb, 0x51, 0x34, 0x98, 0x68, 0xc3,
0xd2, 0xb1, 0xd9, 0x38, 0x94, 0x91, 0x28, 0xb1,
0x69, 0x9a, 0xbf, 0xbf, 0x1a, 0xdf, 0xd3, 0xb6,
0x21, 0x38, 0x94, 0x1b, 0x81, 0x00, 0xb5, 0x39,
0x02, 0x81, 0x81, 0x00, 0xdb, 0xe4, 0x83, 0xc5,
0x7a, 0xe0, 0xcf, 0xeb, 0x07, 0x37, 0xfb, 0xf6,
0xfe, 0xb3, 0x62, 0x72, 0x86, 0xd0, 0x12, 0x96,
0x9d, 0xf4, 0x93, 0x90, 0xdc, 0xf6, 0xc6, 0x03,
0x0c, 0x46, 0xb8, 0x66, 0x60, 0xf3, 0x46, 0x5b,
0xab, 0x9f, 0x9d, 0x81, 0xac, 0x26, 0x8f, 0xd7,
0xa3, 0xbd, 0x16, 0xbb, 0xb4, 0x4e, 0xf6, 0xc0,
0x12, 0xb6, 0x99, 0x4a, 0xf5, 0xc1, 0x6c, 0x40,
0x72, 0x18, 0x71, 0x02, 0x65, 0x77, 0xb1, 0xfb,
0xec, 0x19, 0xbb, 0x8c, 0x03, 0xea, 0x7b, 0x17,
0x63, 0xc9, 0xb9, 0x3b, 0x10, 0x56, 0x19, 0xef,
0x86, 0x69, 0x4d, 0x61, 0x03, 0xac, 0x30, 0x65,
0x63, 0xe5, 0xe1, 0x0f, 0xd6, 0xf6, 0x5b, 0xc9,
0x7c, 0xde, 0x9b, 0x26, 0xca, 0x98, 0xda, 0x0c,
0x5b, 0x6f, 0x91, 0x88, 0xbf, 0x98, 0xc3, 0xbc,
0x72, 0x21, 0xa0, 0x07, 0x0a, 0x5e, 0xc7, 0x61,
0x4a, 0xb3, 0x32, 0xc7, 0x02, 0x81, 0x81, 0x00,
0xc4, 0x1f, 0x4a, 0x23, 0xa6, 0x0b, 0xb9, 0xd5,
0xc7, 0xe9, 0x1a, 0x24, 0xe8, 0x2b, 0xf2, 0x1f,
0x17, 0xc3, 0xe6, 0x14, 0x76, 0x71, 0x11, 0x76,
0x8f, 0xfc, 0x66, 0xb8, 0x8c, 0xe2, 0xf5, 0x46,
0x89, 0x0d, 0xd7, 0xe3, 0x56, 0x19, 0xd7, 0x1a,
0xfe, 0x1c, 0xd4, 0x0f, 0x8b, 0x72, 0xd1, 0x20,
0xb0, 0xa4, 0xbe, 0x6b, 0x6b, 0x01, 0x57, 0xe8,
0x6b, 0xdf, 0x89, 0x55, 0x3f, 0x10, 0x41, 0x63,
0xb0, 0x62, 0xa5, 0x7f, 0x4f, 0xe7, 0x42, 0x54,
0xe4, 0x0e, 0x55, 0xae, 0xa2, 0x53, 0x3d, 0xb8,
0x4a, 0xff, 0xeb, 0xe2, 0x8a, 0x71, 0x17, 0x54,
0x20, 0x05, 0x51, 0xed, 0xae, 0xb0, 0xca, 0x7e,
0xc6, 0xd7, 0x09, 0xa8, 0x39, 0x88, 0xac, 0x7f,
0x4b, 0xe0, 0x49, 0xd5, 0x6c, 0x89, 0xf0, 0xbc,
0xe4, 0xe9, 0xb0, 0x29, 0x73, 0x6c, 0x55, 0x7d,
0x8f, 0xbe, 0x32, 0x31, 0x14, 0xd2, 0xec, 0x1b,
0x02, 0x81, 0x80, 0x67, 0xf6, 0x55, 0x5a, 0xa3,
0xaa, 0xf0, 0x82, 0x75, 0x2a, 0x41, 0xe5, 0x58,
0x2c, 0x65, 0xaa, 0x32, 0x14, 0xe4, 0x04, 0xf3,
0xef, 0x33, 0x69, 0x75, 0x1e, 0xf3, 0x25, 0x73,
0xc3, 0x67, 0xe1, 0x77, 0x8a, 0xed, 0x43, 0xe0,
0x13, 0x99, 0xfb, 0x39, 0xf2, 0x0d, 0x65, 0xed,
0x93, 0x33, 0xd1, 0x51, 0x01, 0x58, 0x66, 0x1d,
0x32, 0xd9, 0xac, 0xf8, 0x1e, 0x17, 0xd9, 0x2c,
0x58, 0x63, 0xed, 0xb7, 0x1d, 0x6d, 0x37, 0xe7,
0x3b, 0x8f, 0x51, 0x36, 0x74, 0xc0, 0xf7, 0xa1,
0x05, 0x39, 0x9f, 0x34, 0x2d, 0x11, 0x1c, 0x0e,
0xd7, 0x70, 0x6f, 0x22, 0xb6, 0x61, 0x37, 0x3e,
0x90, 0xeb, 0xe4, 0x7a, 0x44, 0x85, 0xc6, 0xf0,
0x53, 0xaa, 0xd5, 0x1f, 0x4a, 0x3f, 0x25, 0x42,
0x81, 0xb0, 0x34, 0x10, 0x29, 0xe0, 0xb9, 0x12,
0xd8, 0xd4, 0xf9, 0x1f, 0x2d, 0x0a, 0x64, 0xf4,
0x55, 0x5e, 0xf7, 0x02, 0x81, 0x80, 0x3d, 0x06,
0x1f, 0x63, 0x88, 0x3f, 0x0d, 0xcb, 0xdf, 0x30,
0x40, 0xda, 0x4b, 0x03, 0xa1, 0x8a, 0xdb, 0x32,
0x31, 0x5d, 0x1c, 0x9d, 0x81, 0xf9, 0x8a, 0x43,
0xd7, 0x12, 0x85, 0x83, 0xf9, 0x1d, 0xc1, 0x77,
0x75, 0x3d, 0x5f, 0x85, 0x1a, 0xd1, 0x63, 0x50,
0x45, 0x0b, 0xb1, 0x30, 0x40, 0xb2, 0x13, 0x44,
0xaf, 0x9b, 0x6c, 0xe8, 0x36, 0x1a, 0x33, 0xb6,
0x92, 0x5c, 0xdc, 0x0a, 0x8a, 0xce, 0x22, 0x0c,
0x0f, 0xc2, 0xd5, 0x71, 0xf7, 0xc9, 0xc2, 0x4c,
0x53, 0x8c, 0xcb, 0x25, 0x6b, 0x86, 0xf4, 0x8f,
0x3d, 0x2e, 0x78, 0x35, 0x48, 0x34, 0xfc, 0xe1,
0xaa, 0xe4, 0x71, 0xfe, 0xc0, 0x83, 0x42, 0x0b,
0x97, 0x0d, 0xa9, 0x19, 0x45, 0xd3, 0x36, 0x20,
0xcb, 0xd8, 0x84, 0xb5, 0x47, 0x1a, 0xff, 0x7f,
0x57, 0x39, 0x0e, 0x99, 0x1e, 0xe0, 0xba, 0xe1,
0x4b, 0x6c, 0xca, 0x35, 0xf7, 0x11, 0x02, 0x81,
0x80, 0x5a, 0x59, 0xf0, 0x8e, 0x07, 0x9c, 0x1a,
0x83, 0x2b, 0x28, 0xc4, 0x82, 0xcc, 0xb7, 0x9e,
0x41, 0xa5, 0x15, 0xa2, 0x37, 0xa7, 0x0c, 0x77,
0x09, 0x73, 0xf5, 0xb1, 0x3f, 0x7a, 0x55, 0x9f,
0x15, 0x90, 0xa3, 0x5e, 0x6e, 0x19, 0x46, 0x6d,
0x1f, 0x28, 0x64, 0xad, 0xa0, 0xb5, 0xca, 0x7d,
0x06, 0x44, 0x88, 0xae, 0x2b, 0x80, 0x21, 0x84,
0x3d, 0x8d, 0xa5, 0x09, 0x4f, 0xa1, 0xd9, 0x7d,
0x7c, 0x9a, 0x8b, 0x64, 0x8f, 0xf6, 0xa5, 0xce,
0x56, 0x65, 0xba, 0xcb, 0x30, 0x38, 0x53, 0xf8,
0x1b, 0x89, 0x8f, 0xdf, 0xb5, 0xc3, 0x86, 0x3c,
0x24, 0xef, 0xbc, 0xc0, 0xfc, 0x6c, 0xa4, 0xc6,
0x74, 0xbb, 0xeb, 0x79, 0xa9, 0x8e, 0xe5, 0x25,
0xc0, 0x0a, 0xe5, 0x90, 0x08, 0x43, 0x82, 0xec,
0x17, 0x5e, 0x9e, 0xa2, 0x05, 0xc5, 0x03, 0x20,
0x12, 0xf7, 0x86, 0x2e, 0x7e, 0x8e, 0x11, 0xf7,
0x14
};
const size_t kTestOemPrivateKeySize = sizeof(kTestOemPrivateKey);
// OEM Certificate public cert data.
// Leaf (device) certificate:
// version: 2
// serialNumber: 61412119066269531030714093834591281593
// signature algorithm: sha256WithRSAEncryption (1.2.840.113549.1.1.11)
// issuer:
// C=US, ST=WA, L=Kirkland, O=Google, OU=Widevine, CN=system id: 7913
// validity:
// notBefore: Jan 27 15:55:47 2021 GMT
// notAfter: Jan 25 15:55:47 2031 GMT
// subject:
// CN=7913-leaf, C=US, ST=WA, L=Kirkland, O=Google, OU=Widevine
// key: RSA Public key
// extensions:
// - object: Widevine System Id (1.3.6.1.4.1.11129.4.1.1)
// critical: BOOL ABSENT
// value: 02 02 1e e9 (7913)
// sig_alg: sha256WithRSAEncryption (1.2.840.113549.1.1.11)
// signature: ...
//
// Intermediate (manufacturer) certificate:
// version: 2
// serialNumber: 4911737327617104025470773024969385060
// signature: sha256WithRSAEncryption (1.2.840.113549.1.1.11)
// issuer:
// C=US, ST=Washington, L=Kirkland, O=Google, OU=Widevine,
// CN=widevine.com/oem-root-prod
// validity:
// notBefore: Nov 18 01:13:35 2017 GMT
// notAfter: Nov 18 01:13:13 2027 GMT
// subject:
// C=US, ST=WA, L=Kirkland, O=Google, OU=Widevine, CN=system id: 7913
// key: RSA Public key
// extensions:
// - object: X509v3 Basic Constraints (2.5.29.19)
// critical: TRUE
// value: 30 06 01 01 ff 02 01 00
// - object: X509v3 Key Usage (2.5.29.15)
// critical: TRUE
// value: 03 02 02 04
// - object: X509v3 Subject Key Identifier (2.5.29.14)
// critical: BOOL ABSENT
// value:
// 04 14 4b cb df aa 02 de 8d c3 e7 e5 85 db 2e 8a be 75 6b 8a 67-58
// - object: X509v3 Authority Key Identifier (2.5.29.35)
// critical: BOOL ABSENT
// value: ...
// - object: Widevine System Id (1.3.6.1.4.1.11129.4.1.1)
// critical: BOOL ABSENT
// value: 02 02 1e e9 (7913)
// sig_alg: sha256WithRSAEncryption (1.2.840.113549.1.1.11)
// signature: ...
const uint8_t kTestOemPublicCert[] = {
0x30, 0x82, 0x09, 0x28, 0x06, 0x09, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0,
0x82, 0x09, 0x19, 0x30, 0x82, 0x09, 0x15, 0x02,
0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
0x01, 0xa0, 0x82, 0x08, 0xfd, 0x30, 0x82, 0x03,
0x70, 0x30, 0x82, 0x02, 0x58, 0xa0, 0x03, 0x02,
0x01, 0x02, 0x02, 0x10, 0x2e, 0x33, 0x8b, 0x3d,
0x69, 0x18, 0x4c, 0xf7, 0x78, 0x2e, 0x3b, 0x3b,
0x43, 0xb4, 0x21, 0xb9, 0x30, 0x0d, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
0x0b, 0x05, 0x00, 0x30, 0x6b, 0x31, 0x0b, 0x30,
0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
0x55, 0x04, 0x08, 0x0c, 0x02, 0x57, 0x41, 0x31,
0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07,
0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61,
0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03,
0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06,
0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x57, 0x69,
0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, 0x18,
0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
0x0f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20,
0x69, 0x64, 0x3a, 0x20, 0x37, 0x39, 0x31, 0x33,
0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x31,
0x32, 0x37, 0x31, 0x35, 0x35, 0x35, 0x34, 0x37,
0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x31, 0x32,
0x35, 0x31, 0x35, 0x35, 0x35, 0x34, 0x37, 0x5a,
0x30, 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
0x55, 0x04, 0x03, 0x0c, 0x09, 0x37, 0x39, 0x31,
0x33, 0x2d, 0x6c, 0x65, 0x61, 0x66, 0x31, 0x0b,
0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06,
0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x57, 0x41,
0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04,
0x07, 0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c,
0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06,
0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f,
0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x57,
0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x30,
0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00,
0xa8, 0x75, 0xd5, 0x3d, 0xd3, 0xf3, 0x59, 0xd1,
0x63, 0x0f, 0x5d, 0x5f, 0x2c, 0xaf, 0x80, 0x4e,
0x9a, 0xef, 0x9a, 0x8f, 0x88, 0x37, 0xe5, 0x56,
0xf8, 0x66, 0xcb, 0xa6, 0x61, 0xab, 0xc1, 0xa9,
0x04, 0xc2, 0x12, 0x9d, 0xa6, 0x0c, 0x2c, 0xcb,
0x42, 0x09, 0xd0, 0x36, 0xf0, 0x85, 0x01, 0xdf,
0xd5, 0xbd, 0xaf, 0x82, 0xbb, 0x25, 0xa1, 0x61,
0x17, 0xfe, 0xa1, 0x65, 0x34, 0xda, 0x91, 0xee,
0x91, 0x46, 0xd6, 0x63, 0x47, 0x6a, 0xa5, 0x32,
0x62, 0xe2, 0x4c, 0x7c, 0xf7, 0x76, 0x59, 0xe1,
0x2b, 0x47, 0x8d, 0x1c, 0xe6, 0xa0, 0xbd, 0xc3,
0xc9, 0x36, 0x0e, 0x90, 0x75, 0xba, 0x1c, 0xbd,
0xca, 0x85, 0x0a, 0x4e, 0xcc, 0xfe, 0x91, 0x3f,
0x22, 0x42, 0x96, 0xae, 0xa0, 0x87, 0x82, 0x63,
0x3b, 0x22, 0x54, 0xbc, 0x28, 0xa3, 0x45, 0x4b,
0x34, 0x12, 0x4e, 0xeb, 0x04, 0x4d, 0x29, 0xb3,
0x05, 0x62, 0x0d, 0x51, 0x16, 0x46, 0x98, 0x21,
0xc8, 0x59, 0x96, 0x53, 0x43, 0x38, 0x95, 0x1a,
0x42, 0x94, 0x8b, 0x49, 0x5d, 0x1b, 0x8a, 0xd5,
0x82, 0x6a, 0x32, 0x6f, 0x0e, 0x5a, 0x85, 0x3b,
0xd5, 0x42, 0xc0, 0x4c, 0x34, 0x43, 0x7c, 0x4f,
0xef, 0xca, 0x02, 0x99, 0x38, 0xf9, 0xa5, 0xc0,
0xd8, 0x1d, 0xe7, 0x9e, 0x8c, 0x4d, 0x9c, 0x40,
0xcd, 0x4b, 0x5e, 0x44, 0x37, 0x8d, 0xc5, 0x96,
0xd4, 0xf7, 0xb3, 0x37, 0x4c, 0x2e, 0x2d, 0x30,
0xca, 0x97, 0x39, 0xed, 0xe8, 0x73, 0xc5, 0xe7,
0xcb, 0x95, 0xf0, 0x84, 0x4a, 0x5a, 0x9e, 0x13,
0x19, 0x5f, 0x98, 0xe5, 0xbe, 0x31, 0x5b, 0xff,
0xed, 0x29, 0x26, 0xc4, 0x93, 0x54, 0x49, 0x84,
0xd2, 0xeb, 0x21, 0x40, 0x19, 0x5f, 0xf7, 0x32,
0x67, 0x93, 0xe0, 0xda, 0x77, 0xfc, 0xda, 0x5e,
0xc4, 0x5b, 0x95, 0x2e, 0x46, 0xf3, 0xce, 0xfd,
0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x16, 0x30,
0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01,
0x04, 0x01, 0xd6, 0x79, 0x04, 0x01, 0x01, 0x04,
0x04, 0x02, 0x02, 0x1e, 0xe9, 0x30, 0x0d, 0x06,
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
0x00, 0x04, 0x9e, 0xbb, 0x41, 0x3e, 0x1b, 0x35,
0xca, 0x24, 0xe3, 0xa7, 0x62, 0xf7, 0xbf, 0x54,
0x88, 0x1d, 0xa3, 0x6c, 0x30, 0x1f, 0xb7, 0xe4,
0x2b, 0x76, 0x54, 0x4f, 0xb1, 0x30, 0xba, 0x86,
0x21, 0x12, 0xc3, 0xd9, 0x25, 0xfd, 0x94, 0xab,
0x3c, 0x9d, 0x4d, 0xbc, 0x2b, 0xdc, 0x68, 0x01,
0x8d, 0x59, 0x4f, 0x81, 0xe8, 0x87, 0xbe, 0x05,
0x75, 0x3e, 0x24, 0xd9, 0xf1, 0x55, 0xe3, 0x56,
0x75, 0xa4, 0x7f, 0xb4, 0x50, 0x41, 0x4b, 0x88,
0x0e, 0x8f, 0x6e, 0x10, 0x13, 0x25, 0x24, 0xda,
0x4c, 0x97, 0x0a, 0xdc, 0xbf, 0x2a, 0x1d, 0x4d,
0x02, 0xb3, 0x4b, 0x6a, 0x96, 0xe6, 0x0e, 0xd1,
0x61, 0x80, 0x78, 0xab, 0xf0, 0x7b, 0x8b, 0x1e,
0x99, 0x48, 0x84, 0x31, 0xd2, 0xaf, 0x23, 0x32,
0x01, 0x5e, 0x11, 0x55, 0x06, 0x6e, 0x0e, 0xed,
0x69, 0x7b, 0xb8, 0x41, 0x63, 0x3b, 0x30, 0x05,
0x1e, 0xcd, 0x3e, 0x49, 0xb8, 0x0c, 0x83, 0x50,
0x26, 0x4e, 0xd8, 0x97, 0x9d, 0x89, 0x30, 0x15,
0xb9, 0x20, 0x20, 0xba, 0x5d, 0x8b, 0xad, 0x3d,
0x7f, 0x52, 0xcd, 0x1e, 0xc0, 0x0e, 0xe1, 0xdc,
0x21, 0x9b, 0xb0, 0x89, 0xa0, 0x20, 0xc6, 0x8c,
0x56, 0x39, 0xc3, 0x40, 0x30, 0x40, 0x52, 0x2f,
0x3b, 0x87, 0x96, 0xe2, 0x4d, 0x80, 0x57, 0xb3,
0xb3, 0xe0, 0xb7, 0x5c, 0x55, 0x6a, 0x0f, 0x44,
0x91, 0xe8, 0x98, 0xb3, 0xb4, 0xd3, 0x07, 0x8e,
0x85, 0x8e, 0xc0, 0xcb, 0x85, 0x92, 0x0e, 0xca,
0x7c, 0x03, 0x23, 0xa0, 0x1f, 0x4e, 0x75, 0x01,
0x95, 0x61, 0x2c, 0x21, 0x2f, 0x4f, 0x6d, 0x55,
0xa3, 0xcc, 0x23, 0x62, 0x7f, 0xcb, 0x0a, 0x8a,
0x8b, 0x82, 0xb5, 0x8c, 0x8a, 0xaa, 0x88, 0xb4,
0x65, 0x82, 0x6d, 0x12, 0x4a, 0x06, 0xe7, 0xde,
0xcd, 0x3c, 0xf9, 0x1c, 0x02, 0x9c, 0xf8, 0x21,
0x20, 0x30, 0x82, 0x05, 0x85, 0x30, 0x82, 0x03,
0x6d, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10,
0x03, 0xb1, 0xf7, 0x58, 0xdf, 0x1d, 0xe3, 0x25,
0x00, 0x0b, 0x10, 0x3d, 0xd5, 0xe6, 0xe4, 0x64,
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67,
0x74, 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06,
0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, 0x69,
0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f,
0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31,
0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b,
0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69,
0x6e, 0x65, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03,
0x55, 0x04, 0x03, 0x0c, 0x1a, 0x77, 0x69, 0x64,
0x65, 0x76, 0x69, 0x6e, 0x65, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x6f, 0x65, 0x6d, 0x2d, 0x72, 0x6f,
0x6f, 0x74, 0x2d, 0x70, 0x72, 0x6f, 0x64, 0x30,
0x1e, 0x17, 0x0d, 0x31, 0x37, 0x31, 0x31, 0x31,
0x38, 0x30, 0x31, 0x31, 0x33, 0x33, 0x35, 0x5a,
0x17, 0x0d, 0x32, 0x37, 0x31, 0x31, 0x31, 0x38,
0x30, 0x31, 0x31, 0x33, 0x31, 0x33, 0x5a, 0x30,
0x6b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b,
0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
0x02, 0x57, 0x41, 0x31, 0x11, 0x30, 0x0f, 0x06,
0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, 0x69,
0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f,
0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31,
0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b,
0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69,
0x6e, 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03,
0x55, 0x04, 0x03, 0x0c, 0x0f, 0x73, 0x79, 0x73,
0x74, 0x65, 0x6d, 0x20, 0x69, 0x64, 0x3a, 0x20,
0x37, 0x39, 0x31, 0x33, 0x30, 0x82, 0x01, 0x22,
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
0x02, 0x82, 0x01, 0x01, 0x00, 0xae, 0xc8, 0x71,
0xae, 0x08, 0x0c, 0x06, 0x06, 0x2d, 0x81, 0x7c,
0xa9, 0x8b, 0xb3, 0xd6, 0x66, 0xe4, 0xf6, 0x08,
0x5e, 0x5a, 0x75, 0xe8, 0x74, 0x61, 0x7a, 0x88,
0xca, 0x85, 0x14, 0x0d, 0x58, 0xa4, 0x09, 0x19,
0x6c, 0x60, 0xc9, 0xad, 0x91, 0x1c, 0xbf, 0x04,
0xb3, 0x47, 0x10, 0x63, 0x7f, 0x02, 0x58, 0xc2,
0x1e, 0xbd, 0xcc, 0x07, 0x77, 0xaa, 0x7e, 0x14,
0xa8, 0xc2, 0x01, 0xcd, 0xe8, 0x46, 0x60, 0x53,
0x6f, 0x2f, 0xda, 0x17, 0x2d, 0x4d, 0x9d, 0x0e,
0x5d, 0xb5, 0x50, 0x95, 0xae, 0xab, 0x6e, 0x43,
0xe3, 0xb0, 0x00, 0x12, 0xb4, 0x05, 0x82, 0x4a,
0x2b, 0x14, 0x63, 0x0d, 0x1f, 0x06, 0x12, 0xaa,
0xe1, 0x9d, 0xe7, 0xba, 0xda, 0xe3, 0xfc, 0x7c,
0x6c, 0x73, 0xae, 0x56, 0xf8, 0xab, 0xf7, 0x51,
0x93, 0x31, 0xef, 0x8f, 0xe4, 0xb6, 0x01, 0x2c,
0xeb, 0x7b, 0xe4, 0xd8, 0xb3, 0xea, 0x70, 0x37,
0x89, 0x05, 0xa9, 0x51, 0x57, 0x72, 0x98, 0x9e,
0xa8, 0x46, 0xdb, 0xeb, 0x7a, 0x38, 0x2b, 0x2f,
0xc0, 0x27, 0xb7, 0xc2, 0xe1, 0x9a, 0x17, 0xdf,
0xf5, 0xd6, 0x9c, 0xd5, 0x8c, 0xb8, 0x66, 0x42,
0xd5, 0x04, 0x1e, 0x7c, 0x36, 0x4c, 0x1e, 0x3e,
0x45, 0x51, 0x4d, 0x41, 0x72, 0x22, 0x53, 0x3d,
0xf4, 0x57, 0x7c, 0x6c, 0x33, 0x34, 0x24, 0x45,
0xdf, 0x84, 0x87, 0x4a, 0xa6, 0xcb, 0x7c, 0x03,
0xa3, 0xaa, 0x8e, 0x2d, 0x82, 0x01, 0x27, 0x87,
0x74, 0x82, 0x1a, 0xbc, 0x0f, 0x76, 0x69, 0xab,
0xe0, 0x4e, 0x70, 0xbe, 0x37, 0xfc, 0xc8, 0x2c,
0x91, 0x17, 0x4f, 0xd5, 0x26, 0x3b, 0x7b, 0x90,
0xb5, 0x2d, 0x64, 0xba, 0xf7, 0xd2, 0x8a, 0xb4,
0x8f, 0x38, 0x9d, 0x8e, 0xba, 0xe7, 0x5c, 0x52,
0xf1, 0x0a, 0xb8, 0xc0, 0x1b, 0xb6, 0xb1, 0x70,
0x7e, 0x47, 0x59, 0x94, 0x59, 0x02, 0x03, 0x01,
0x00, 0x01, 0xa3, 0x82, 0x01, 0x10, 0x30, 0x82,
0x01, 0x0c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d,
0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06,
0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e,
0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff,
0x04, 0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x1d,
0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
0x14, 0x4b, 0xcb, 0xdf, 0xaa, 0x02, 0xde, 0x8d,
0xc3, 0xe7, 0xe5, 0x85, 0xdb, 0x2e, 0x8a, 0xbe,
0x75, 0x6b, 0x8a, 0x67, 0x58, 0x30, 0x81, 0xb2,
0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xaa,
0x30, 0x81, 0xa7, 0x80, 0x14, 0x04, 0x94, 0x66,
0xaa, 0xf9, 0x61, 0x89, 0xb6, 0xdb, 0xb5, 0xf7,
0x13, 0x38, 0x3d, 0x62, 0x84, 0xb8, 0x18, 0x0a,
0x8f, 0xa1, 0x81, 0x83, 0xa4, 0x81, 0x80, 0x30,
0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67,
0x74, 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06,
0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, 0x69,
0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f,
0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31,
0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b,
0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69,
0x6e, 0x65, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03,
0x55, 0x04, 0x03, 0x0c, 0x1a, 0x77, 0x69, 0x64,
0x65, 0x76, 0x69, 0x6e, 0x65, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x6f, 0x65, 0x6d, 0x2d, 0x72, 0x6f,
0x6f, 0x74, 0x2d, 0x70, 0x72, 0x6f, 0x64, 0x82,
0x09, 0x00, 0xdf, 0x86, 0x05, 0x31, 0x01, 0xbe,
0x9a, 0x9a, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06,
0x01, 0x04, 0x01, 0xd6, 0x79, 0x04, 0x01, 0x01,
0x04, 0x04, 0x02, 0x02, 0x1e, 0xe9, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02,
0x01, 0x00, 0x61, 0x3f, 0x2f, 0x43, 0xe4, 0xbe,
0x66, 0x34, 0xef, 0x92, 0x06, 0xe9, 0x88, 0xba,
0x6a, 0x1d, 0x4f, 0x54, 0x5a, 0x97, 0xb1, 0x75,
0xd7, 0x93, 0xf8, 0x45, 0xc6, 0x83, 0x92, 0x36,
0xfd, 0x55, 0xa9, 0x21, 0x0b, 0xdc, 0xf6, 0xae,
0x11, 0xdc, 0x62, 0x21, 0x44, 0xbd, 0x04, 0x1d,
0x58, 0x2c, 0x03, 0xf8, 0xe4, 0xe2, 0x1e, 0xba,
0xe6, 0xdd, 0x19, 0xdd, 0x56, 0xfd, 0xce, 0x06,
0x73, 0x5f, 0x94, 0x1e, 0xb6, 0x03, 0xdb, 0x3d,
0x7b, 0xab, 0xab, 0x72, 0x64, 0x7b, 0xde, 0x7d,
0x4d, 0xcf, 0x7e, 0xf0, 0x91, 0x29, 0xc1, 0x77,
0x13, 0xc2, 0x6f, 0x80, 0xab, 0x7a, 0xa8, 0xce,
0xb0, 0x1c, 0x2a, 0xc5, 0x9c, 0xfb, 0x0b, 0xe5,
0x9f, 0x9c, 0x1b, 0xc9, 0x4b, 0x58, 0xdf, 0x96,
0x18, 0xf7, 0x67, 0x67, 0x89, 0xa4, 0xe9, 0x14,
0x48, 0xac, 0xfa, 0x9d, 0x86, 0x2a, 0xeb, 0x75,
0x2c, 0x2b, 0xbf, 0x63, 0x7d, 0xc7, 0x4e, 0x7e,
0xad, 0x39, 0x2d, 0xb4, 0x7c, 0x07, 0xa5, 0x5a,
0xe8, 0x3a, 0xd4, 0xf5, 0x0c, 0x4f, 0xf3, 0xa2,
0x9c, 0x3c, 0x32, 0xed, 0x9d, 0x4b, 0x49, 0x05,
0xbc, 0x1f, 0xa0, 0x13, 0xe6, 0xdd, 0x82, 0x79,
0x06, 0x31, 0x3b, 0xc6, 0x97, 0xec, 0x8d, 0xaa,
0x4f, 0xef, 0x14, 0x3c, 0x21, 0xf6, 0x72, 0xb2,
0x09, 0x42, 0xc7, 0x74, 0xfe, 0xef, 0x70, 0xbd,
0xe9, 0x85, 0x41, 0x30, 0x0b, 0xb3, 0x6b, 0x59,
0x0c, 0x0f, 0x11, 0x75, 0xd4, 0xbb, 0xb1, 0xdf,
0xb1, 0xdf, 0xb3, 0xfa, 0xb3, 0x3a, 0x43, 0x17,
0x7d, 0x8a, 0x82, 0xae, 0xa2, 0x07, 0xf8, 0x83,
0x51, 0xfb, 0x16, 0xfb, 0x64, 0xb6, 0x46, 0xda,
0xbe, 0x32, 0x2b, 0xc0, 0xee, 0x78, 0x2a, 0x84,
0xa9, 0x54, 0x0a, 0xf9, 0x2d, 0x61, 0x65, 0xde,
0xa5, 0x97, 0x66, 0x79, 0x02, 0xf8, 0x97, 0x17,
0xe2, 0xd4, 0x9f, 0x9e, 0xac, 0xcc, 0xae, 0x99,
0x9a, 0x03, 0x04, 0xbb, 0x45, 0xfe, 0xb2, 0xf5,
0x80, 0xba, 0xbf, 0xdd, 0x24, 0xe5, 0xe6, 0x1e,
0x5d, 0x36, 0xa5, 0x87, 0x0c, 0xdf, 0x60, 0x81,
0x6f, 0xb7, 0x5f, 0xb9, 0x1f, 0xca, 0x75, 0x3c,
0x1a, 0x63, 0xb0, 0xeb, 0xe6, 0x95, 0x86, 0x0d,
0xae, 0xa6, 0xc9, 0x2a, 0x94, 0xf1, 0xd0, 0xbe,
0x75, 0xc8, 0xf8, 0x07, 0xd7, 0x88, 0xff, 0xec,
0xf9, 0xcd, 0x49, 0xc6, 0xfe, 0x4d, 0x7f, 0x44,
0x1e, 0xd8, 0xaf, 0xa9, 0x72, 0x27, 0x98, 0xe2,
0x5a, 0x08, 0xea, 0x55, 0xd3, 0xb3, 0xea, 0xdc,
0x76, 0x69, 0x51, 0x10, 0x01, 0x46, 0x7d, 0x33,
0x94, 0x9c, 0x94, 0xef, 0xfe, 0x76, 0x1c, 0xc6,
0xd7, 0x15, 0x53, 0x3e, 0x8d, 0x3d, 0x29, 0x9a,
0x58, 0x6a, 0xf1, 0x75, 0x9e, 0xea, 0x1b, 0x4c,
0xf0, 0x47, 0x76, 0xac, 0xc6, 0xa2, 0x32, 0x44,
0x40, 0xdf, 0xfe, 0xff, 0x9d, 0xf4, 0xe2, 0xc2,
0xfa, 0xa1, 0x5f, 0x2e, 0x66, 0xe9, 0x97, 0xcb,
0x27, 0x26, 0x6e, 0x53, 0xe4, 0xe8, 0x86, 0x2c,
0xea, 0xd3, 0x69, 0x6c, 0x61, 0x4f, 0xfe, 0xc1,
0xc9, 0x8b, 0x05, 0x92, 0x6f, 0x47, 0x96, 0xce,
0xf0, 0x33, 0xfa, 0x7c, 0x78, 0x24, 0x9b, 0xd7,
0x8d, 0x36, 0x56, 0x37, 0x86, 0xbc, 0x72, 0x5a,
0xf9, 0xb9, 0xb0, 0x93, 0xf0, 0x81, 0x78, 0x10,
0xf2, 0xb0, 0xc2, 0x79, 0x91, 0x5e, 0xcf, 0xbc,
0x8c, 0xf2, 0x32, 0x0f, 0xf7, 0x2d, 0x30, 0xd8,
0x13, 0x77, 0x4f, 0x78, 0x9e, 0x40, 0x8d, 0xe6,
0x3a, 0x98, 0xb2, 0xaa, 0x13, 0x4d, 0x25, 0x49,
0x34, 0x6c, 0x80, 0x9e, 0x19, 0x03, 0xdb, 0xcd,
0xf5, 0xb1, 0x54, 0x74, 0x1b, 0x67, 0x3c, 0x46,
0xac, 0x3e, 0x5d, 0xa2, 0xd9, 0x13, 0x83, 0x30,
0xeb, 0x82, 0x3b, 0x06, 0xab, 0x3c, 0x39, 0x7d,
0xd0, 0x68, 0x31, 0x00
};
// clang-format on
} // namespace
const size_t kTestOemPublicCertSize = sizeof(kTestOemPublicCert);
const uint32_t kOEMSystemId = kTestOemSystemId;
const uint8_t* kOEMPrivateKey = kTestOemPrivateKey;
const uint8_t* kOEMPublicCert = kTestOemPublicCert;
const size_t kOEMPrivateKeySize = kTestOemPrivateKeySize;
const size_t kOEMPublicCertSize = kTestOemPublicCertSize;
} // namespace wvoec_ref

View File

@@ -0,0 +1,258 @@
// 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 utilities of OEMCrypto APIs
//
#include <gtest/gtest.h>
#include "OEMCryptoCENCCommon.h"
#include "oemcrypto_ecc_key.h"
#include "oemcrypto_ref_test_utils.h"
namespace wvoec {
namespace util {
constexpr size_t kMessageSize = 4 * 1024; // 4 kB
class OEMCryptoEccKeyTest : public ::testing::TestWithParam<EccCurve> {
public:
void SetUp() override {
key_ = EccPrivateKey::New(GetParam());
ASSERT_TRUE(key_) << "Key initialization failed: key = "
<< EccCurveToString(GetParam());
}
void TearDown() override { key_.reset(); }
protected:
std::unique_ptr<EccPrivateKey> key_;
};
// Basic verification of ECC private key generation.
TEST_P(OEMCryptoEccKeyTest, KeyProperties) {
const EccCurve expected_curve = GetParam();
EXPECT_EQ(key_->curve(), expected_curve);
EXPECT_NE(nullptr, key_->GetEcKey());
}
// Checks that the private key serialization APIs are compatible
// and performing in a manner that is similar to other OEMCrypto methods
// that retrieve data.
TEST_P(OEMCryptoEccKeyTest, SerializePrivateKey) {
constexpr size_t kInitialBufferSize = 10; // Definitely too small.
size_t buffer_size = kInitialBufferSize;
std::vector<uint8_t> buffer(buffer_size);
EXPECT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
key_->Serialize(buffer.data(), &buffer_size));
EXPECT_GT(buffer_size, kInitialBufferSize);
buffer.resize(buffer_size);
EXPECT_EQ(OEMCrypto_SUCCESS, key_->Serialize(buffer.data(), &buffer_size));
buffer.resize(buffer_size);
const std::vector<uint8_t> direct_key_data = key_->Serialize();
EXPECT_FALSE(direct_key_data.empty());
ASSERT_EQ(buffer.size(), direct_key_data.size());
for (size_t i = 0; i < buffer.size(); i++) {
ASSERT_EQ(buffer[i], direct_key_data[i]) << "i = " << i;
}
}
// Checks that a private key that is serialized can be deserialized and
// reload. Also checks that the serialization of a key produces the
// same data to ensure consistency.
TEST_P(OEMCryptoEccKeyTest, SerializeAndReloadPrivateKey) {
const std::vector<uint8_t> key_data = key_->Serialize();
std::unique_ptr<EccPrivateKey> loaded_key = EccPrivateKey::Load(key_data);
ASSERT_TRUE(loaded_key);
EXPECT_EQ(key_->curve(), loaded_key->curve());
const std::vector<uint8_t> loaded_key_data = loaded_key->Serialize();
ASSERT_EQ(key_data.size(), loaded_key_data.size());
for (size_t i = 0; i < key_data.size(); i++) {
ASSERT_EQ(key_data[i], loaded_key_data[i]) << "i = " << i;
}
}
// Checks that a private key can be serialized as a public key, and
// that the serialized public key and be reloaded.
TEST_P(OEMCryptoEccKeyTest, SerializePrivateKeyAsPublicKey) {
const std::vector<uint8_t> key_data = key_->SerializeAsPublicKey();
ASSERT_FALSE(key_data.empty()) << "Failed to serialize as public key";
auto loaded_key = EccPublicKey::Load(key_data);
ASSERT_TRUE(loaded_key) << "Failed to deserialize public key";
EXPECT_TRUE(key_->IsMatchingPublicKey(*loaded_key));
EXPECT_TRUE(loaded_key->IsMatchingPrivateKey(*key_));
}
// Checks that a public key can be initialized from a ASN.1 DER encoded
// PrivateKeyInfo message.
TEST_P(OEMCryptoEccKeyTest, SerializePrivateKeyAndReloadAsPublicKey) {
const std::vector<uint8_t> key_data = key_->Serialize();
ASSERT_FALSE(key_data.empty()) << "Failed to serialize as private key";
auto key_by_buffer =
EccPublicKey::LoadPrivateKeyInfo(key_data.data(), key_data.size());
ASSERT_TRUE(key_by_buffer)
<< "Failed to deserialize private key into public key";
EXPECT_TRUE(key_->IsMatchingPublicKey(*key_by_buffer));
key_by_buffer.reset();
auto key_by_vector = EccPublicKey::LoadPrivateKeyInfo(key_data);
ASSERT_TRUE(key_by_vector)
<< "Failed to deserialize private key into public key";
EXPECT_TRUE(key_->IsMatchingPublicKey(*key_by_vector));
key_by_vector.reset();
const std::string key_data_str(key_data.begin(), key_data.end());
auto key_by_string = EccPublicKey::LoadPrivateKeyInfo(key_data_str);
ASSERT_TRUE(key_by_string)
<< "Failed to deserialize private key into public key";
EXPECT_TRUE(key_->IsMatchingPublicKey(*key_by_string));
}
// Checks that a public key can be created from the private key.
TEST_P(OEMCryptoEccKeyTest, DerivePublicKey) {
std::unique_ptr<EccPublicKey> pub_key = key_->MakePublicKey();
ASSERT_TRUE(pub_key);
EXPECT_TRUE(key_->IsMatchingPublicKey(*pub_key));
}
// Checks that a public key that is serialized can be deserialized and
// reload. Also checks that the serialization of a key produces the
// same data to ensure consistency.
TEST_P(OEMCryptoEccKeyTest, SerializePublicKey) {
std::unique_ptr<EccPublicKey> pub_key = key_->MakePublicKey();
ASSERT_TRUE(pub_key);
constexpr size_t kInitialBufferSize = 10; // Definitely too small.
size_t buffer_size = kInitialBufferSize;
std::vector<uint8_t> buffer(buffer_size);
EXPECT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
pub_key->Serialize(buffer.data(), &buffer_size));
EXPECT_GT(buffer_size, kInitialBufferSize);
buffer.resize(buffer_size);
EXPECT_EQ(OEMCrypto_SUCCESS, pub_key->Serialize(buffer.data(), &buffer_size));
buffer.resize(buffer_size);
const std::vector<uint8_t> direct_key_data = pub_key->Serialize();
EXPECT_FALSE(direct_key_data.empty());
ASSERT_EQ(buffer.size(), direct_key_data.size());
for (size_t i = 0; i < buffer.size(); i++) {
ASSERT_EQ(buffer[i], direct_key_data[i]) << "i = " << i;
}
}
// Checks that a public key that is serialized can be deserialized and
// reload. Also checks that the serialization of a key produces the
// same data to ensure consistency.
// It is anticipated that OEMCrypto will need to parse the licensing
// server's ephemerial key when deriving the session key.
TEST_P(OEMCryptoEccKeyTest, SerializeAndReloadPublicKey) {
std::unique_ptr<EccPublicKey> pub_key = key_->MakePublicKey();
ASSERT_TRUE(pub_key);
const std::vector<uint8_t> key_data = pub_key->Serialize();
std::unique_ptr<EccPublicKey> loaded_key = EccPublicKey::Load(key_data);
ASSERT_TRUE(loaded_key);
EXPECT_EQ(pub_key->curve(), loaded_key->curve());
const std::vector<uint8_t> loaded_key_data = loaded_key->Serialize();
ASSERT_EQ(key_data.size(), loaded_key_data.size());
for (size_t i = 0; i < key_data.size(); i++) {
ASSERT_EQ(key_data[i], loaded_key_data[i]) << "i = " << i;
}
}
// Checks that the ECC signature generating API operates similar to
// existing signature generation functions.
TEST_P(OEMCryptoEccKeyTest, GenerateSignature) {
const std::vector<uint8_t> message = RandomData(kMessageSize);
ASSERT_FALSE(message.empty()) << "CdmRandom failed";
constexpr size_t kInitialBufferSize = 10; // Definitely too small.
size_t signature_size = kInitialBufferSize;
std::vector<uint8_t> signature(signature_size);
EXPECT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
key_->GenerateSignature(message.data(), message.size(),
signature.data(), &signature_size));
EXPECT_GT(signature_size, kInitialBufferSize);
signature.resize(signature_size);
EXPECT_EQ(OEMCrypto_SUCCESS,
key_->GenerateSignature(message.data(), message.size(),
signature.data(), &signature_size));
signature.resize(signature_size);
EXPECT_LE(signature_size, key_->SignatureSize());
}
// Checks that ECC signatures can be verified by an ECC public key.
TEST_P(OEMCryptoEccKeyTest, VerifySignature) {
const std::vector<uint8_t> message = RandomData(kMessageSize);
ASSERT_FALSE(message.empty()) << "CdmRandom failed";
const std::vector<uint8_t> signature = key_->GenerateSignature(message);
std::unique_ptr<EccPublicKey> pub_key = key_->MakePublicKey();
ASSERT_TRUE(pub_key);
EXPECT_EQ(OEMCrypto_SUCCESS, pub_key->VerifySignature(message, signature));
// Check with different message.
const std::vector<uint8_t> message_two = RandomData(kMessageSize);
EXPECT_EQ(OEMCrypto_ERROR_SIGNATURE_FAILURE,
pub_key->VerifySignature(message_two, signature));
// Check with bad signature.
const std::vector<uint8_t> bad_signature = RandomData(signature.size());
EXPECT_EQ(OEMCrypto_ERROR_SIGNATURE_FAILURE,
pub_key->VerifySignature(message, bad_signature));
}
// Verifies the session key exchange protocol used by the licensing
// server.
TEST_P(OEMCryptoEccKeyTest, DeriveSessionKey) {
// Set up Alice.
EccPrivateKey* alice_private_key = key_.get();
std::unique_ptr<EccPublicKey> alice_public_key =
alice_private_key->MakePublicKey();
ASSERT_TRUE(alice_public_key);
// Set up Bob.
std::unique_ptr<EccPrivateKey> bob_private_key =
EccPrivateKey::New(alice_private_key->curve());
ASSERT_TRUE(bob_private_key);
std::unique_ptr<EccPublicKey> bob_public_key =
bob_private_key->MakePublicKey();
ASSERT_TRUE(bob_public_key);
const size_t session_key_length = alice_private_key->SessionKeyLength();
EXPECT_EQ(session_key_length, bob_private_key->SessionKeyLength());
// From Alice's perspective.
const std::vector<uint8_t> alice_session_key =
alice_private_key->DeriveSessionKey(*bob_public_key);
// From Bob's perspective.
const std::vector<uint8_t> bob_session_key =
bob_private_key->DeriveSessionKey(*alice_public_key);
// Both should have the same session key.
ASSERT_EQ(session_key_length, alice_session_key.size());
ASSERT_EQ(session_key_length, bob_session_key.size());
for (size_t i = 0; i < session_key_length; i++) {
ASSERT_EQ(alice_session_key[i], bob_session_key[i]) << "i = " << i;
}
}
INSTANTIATE_TEST_SUITE_P(AllCurves, OEMCryptoEccKeyTest,
::testing::Values(kEccSecp256r1, kEccSecp384r1,
kEccSecp521r1));
} // namespace util
} // namespace wvoec

View File

@@ -0,0 +1,124 @@
// 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 utilities of OEMCrypto APIs
//
#include <gtest/gtest.h>
#include "OEMCryptoCENCCommon.h"
#include "oem_cert.h"
#include "oemcrypto_oem_cert.h"
#include "oemcrypto_rsa_key.h"
namespace wvoec {
namespace util {
using wvoec_ref::kOEMPrivateKey;
using wvoec_ref::kOEMPrivateKeySize;
using wvoec_ref::kOEMPublicCert;
using wvoec_ref::kOEMPublicCertSize;
namespace {
const std::vector<uint8_t> kOEMPrivateKeyVector(kOEMPrivateKey,
kOEMPrivateKey +
kOEMPrivateKeySize);
const std::vector<uint8_t> kOEMPublicCertVector(kOEMPublicCert,
kOEMPublicCert +
kOEMPublicCertSize);
} // namespace
// Creates an OemCertificate wrapper around the built-in reference
// OEM cert.
// Creating the OemCertificate should succeed so long as the data
// is well-formed.
// Validating the OEM cert should succeed (assuming built-in cert+key
// are valid).
TEST(OEMCryptoOemCertTest, CreateFromArray) {
std::unique_ptr<OemCertificate> oem_cert = OemCertificate::Create(
kOEMPrivateKey, kOEMPrivateKeySize, kOEMPublicCert, kOEMPublicCertSize);
ASSERT_TRUE(oem_cert);
EXPECT_EQ(OemCertificate::kRsa, oem_cert->key_type());
const std::vector<uint8_t> private_key = oem_cert->GetPrivateKey();
EXPECT_EQ(kOEMPrivateKeyVector, private_key);
size_t public_cert_size = 10;
std::vector<uint8_t> public_cert(public_cert_size, 0);
EXPECT_EQ(
OEMCrypto_ERROR_SHORT_BUFFER,
oem_cert->GetPublicCertificate(public_cert.data(), &public_cert_size));
public_cert.resize(public_cert_size);
EXPECT_EQ(OEMCrypto_SUCCESS, oem_cert->GetPublicCertificate(
public_cert.data(), &public_cert_size));
EXPECT_EQ(kOEMPublicCertSize, public_cert_size);
EXPECT_EQ(kOEMPublicCertVector, public_cert);
EXPECT_EQ(OEMCrypto_SUCCESS, oem_cert->IsCertificateValid());
}
TEST(OEMCryptoOemCertTest, CreateFromVector) {
std::unique_ptr<OemCertificate> oem_cert =
OemCertificate::Create(kOEMPrivateKeyVector, kOEMPublicCertVector);
ASSERT_TRUE(oem_cert);
EXPECT_EQ(OemCertificate::kRsa, oem_cert->key_type());
const std::vector<uint8_t> private_key = oem_cert->GetPrivateKey();
EXPECT_EQ(kOEMPrivateKeyVector, private_key);
const std::vector<uint8_t> public_cert = oem_cert->GetPublicCertificate();
EXPECT_EQ(kOEMPublicCertVector, public_cert);
EXPECT_EQ(OEMCrypto_SUCCESS, oem_cert->IsCertificateValid());
}
// Creation of OemCertificate wrapper should fail if the provided
// key is not well-formed.
TEST(OEMCryptoOemCertTest, CreateWithABadPrivateKey) {
static const uint8_t kBadPrivateKeyData[] = {'n', 'o', 't', ' ', 'a', ' ',
'p', 'r', 'i', 'v', 'a', 't',
'e', 'k', 'e', 'y'};
std::unique_ptr<OemCertificate> oem_cert =
OemCertificate::Create(kBadPrivateKeyData, sizeof(kBadPrivateKeyData),
kOEMPublicCert, kOEMPublicCertSize);
EXPECT_FALSE(oem_cert);
}
// Creation of OemCertificate wrapper should fail if the provided
// OEM Public Cert is not well-formed.
TEST(OEMCryptoOemCertTest, CreateWithABadPublicCert) {
static const uint8_t kBadPublicCert[] = {'n', 'o', 't', ' ', 'a', ' ', 'o',
'e', 'm', ' ', 'p', 'u', 'b', 'l',
'i', 'c', ' ', 'c', 'e', 'r', 't'};
std::unique_ptr<OemCertificate> oem_cert =
OemCertificate::Create(kOEMPrivateKey, kOEMPrivateKeySize, kBadPublicCert,
sizeof(kBadPublicCert));
EXPECT_FALSE(oem_cert);
}
// It is possible to create an OEM Certificate using a non-matching
// public-private key pair so long as the key types are the same.
// However, OEM Cert validation should catch the problem.
TEST(OEMCryptoOemCertTest, CreateWithDifferentPrivateRsaKey) {
std::unique_ptr<RsaPrivateKey> key = RsaPrivateKey::New(kRsa2048Bit);
ASSERT_TRUE(key);
const std::vector<uint8_t> private_key = key->Serialize();
ASSERT_FALSE(private_key.empty());
// Creating the OEM Certificate should succeed.
std::unique_ptr<OemCertificate> oem_cert =
OemCertificate::Create(private_key, kOEMPublicCertVector);
ASSERT_TRUE(oem_cert);
EXPECT_EQ(OemCertificate::kRsa, oem_cert->key_type());
// Validating key should return an error.
OEMCryptoResult status = oem_cert->IsCertificateValid();
// Test still allows deprecated error.
if (status != OEMCrypto_ERROR_INVALID_RSA_KEY) {
EXPECT_EQ(OEMCrypto_ERROR_INVALID_KEY, status);
}
}
} // namespace util
} // namespace wvoec

View File

@@ -0,0 +1,20 @@
// 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 utilities of OEMCrypto APIs
//
#include "oemcrypto_ref_test_utils.h"
#include <string>
#include "cdm_random.h"
namespace wvoec {
namespace util {
std::vector<uint8_t> RandomData(size_t length) {
const std::string data = wvutil::CdmRandom::RandomData(length);
return std::vector<uint8_t>(data.begin(), data.end());
}
} // namespace util
} // namespace wvoec

View File

@@ -0,0 +1,21 @@
// 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 utilities of OEMCrypto APIs
//
#ifndef WVOEC_UTIL_REF_TEST_UTILS_H_
#define WVOEC_UTIL_REF_TEST_UTILS_H_
#include <stddef.h>
#include <stdint.h>
#include <vector>
namespace wvoec {
namespace util {
// Returns a vector of random bytes.
std::vector<uint8_t> RandomData(size_t length);
} // namespace util
} // namespace wvoec
#endif // WVOEC_UTIL_REF_TEST_UTILS_H_

View File

@@ -0,0 +1,417 @@
// 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 utilities of OEMCrypto APIs
//
#include <stdlib.h>
#include <mutex>
#include <gtest/gtest.h>
#include "OEMCryptoCENC.h"
#include "log.h"
#include "oemcrypto_ref_test_utils.h"
#include "oemcrypto_rsa_key.h"
namespace wvoec {
namespace util {
constexpr size_t kMessageSize = 4 * 1024; // 4 kB
constexpr size_t kCastMessageSize = 83; // Special max size.
class OEMCryptoRsaKeyTest : public ::testing::TestWithParam<RsaFieldSize> {
public:
void SetUp() override {
// RSA key generation is slow (~2 seconds) compared to the
// operations they perform (<50 ms). Each key type is generated
// once and globally stored in serialized form.
// Caching the instance may result in test failures for
// memory-leak detection.
const RsaFieldSize field_size = GetParam();
std::lock_guard<std::mutex> rsa_key_lock(rsa_key_mutex_);
// Use of a switch case is intentional to cause compiler warnings
// if a new field size is introduced without updating the test.
switch (field_size) {
case kRsa2048Bit: {
if (!rsa_2048_key_data_.empty()) {
key_ = RsaPrivateKey::Load(rsa_2048_key_data_);
}
if (!key_) {
key_ = RsaPrivateKey::New(kRsa2048Bit);
}
if (rsa_2048_key_data_.empty() && key_) {
rsa_2048_key_data_ = key_->Serialize();
}
} break;
case kRsa3072Bit: {
if (!rsa_3072_key_data_.empty()) {
key_ = RsaPrivateKey::Load(rsa_3072_key_data_);
}
if (!key_) {
key_ = RsaPrivateKey::New(kRsa3072Bit);
}
if (rsa_3072_key_data_.empty() && key_) {
rsa_3072_key_data_ = key_->Serialize();
}
} break;
case kRsaFieldUnknown: // Suppress compiler warnings
LOGE("RSA test was incorrectly instantiation");
exit(EXIT_FAILURE);
break;
}
ASSERT_TRUE(key_) << "Key initialization failed "
<< RsaFieldSizeToString(field_size);
}
void TearDown() override { key_.reset(); }
protected:
std::unique_ptr<RsaPrivateKey> key_;
static std::mutex rsa_key_mutex_;
static std::vector<uint8_t> rsa_2048_key_data_;
static std::vector<uint8_t> rsa_3072_key_data_;
};
std::mutex OEMCryptoRsaKeyTest::rsa_key_mutex_;
std::vector<uint8_t> OEMCryptoRsaKeyTest::rsa_2048_key_data_;
std::vector<uint8_t> OEMCryptoRsaKeyTest::rsa_3072_key_data_;
// Basic verification of RSA private key generation.
TEST_P(OEMCryptoRsaKeyTest, KeyProperties) {
const RsaFieldSize expected_field_size = GetParam();
EXPECT_EQ(key_->field_size(), expected_field_size);
EXPECT_NE(nullptr, key_->GetRsaKey());
}
// Checks that the private key serialization APIs are compatible
// and performing in a manner that is similar to other OEMCrypto methods
// that retrieve data.
TEST_P(OEMCryptoRsaKeyTest, SerializePrivateKey) {
constexpr size_t kInitialBufferSize = 10; // Definitely too small.
size_t buffer_size = kInitialBufferSize;
std::vector<uint8_t> buffer(buffer_size);
EXPECT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
key_->Serialize(buffer.data(), &buffer_size));
EXPECT_GT(buffer_size, kInitialBufferSize);
buffer.resize(buffer_size);
EXPECT_EQ(OEMCrypto_SUCCESS, key_->Serialize(buffer.data(), &buffer_size));
buffer.resize(buffer_size);
const std::vector<uint8_t> direct_key_data = key_->Serialize();
EXPECT_FALSE(direct_key_data.empty());
ASSERT_EQ(buffer.size(), direct_key_data.size());
for (size_t i = 0; i < buffer.size(); i++) {
ASSERT_EQ(buffer[i], direct_key_data[i]) << "i = " << std::to_string(i);
}
}
// Checks that a private key that is serialized can be deserialized and
// reload. Also checks that the serialization of a key produces the
// same data to ensure consistency.
TEST_P(OEMCryptoRsaKeyTest, SerializeAndReloadPrivateKey) {
const std::vector<uint8_t> key_data = key_->Serialize();
std::unique_ptr<RsaPrivateKey> loaded_key = RsaPrivateKey::Load(key_data);
ASSERT_TRUE(loaded_key);
EXPECT_EQ(key_->field_size(), loaded_key->field_size());
const std::vector<uint8_t> loaded_key_data = loaded_key->Serialize();
ASSERT_EQ(key_data.size(), loaded_key_data.size());
for (size_t i = 0; i < key_data.size(); i++) {
ASSERT_EQ(key_data[i], loaded_key_data[i]) << "i = " << std::to_string(i);
}
}
// Checks that a private key with explicitly indicated schemes include
// the scheme fields in the reserialized key.
TEST_P(OEMCryptoRsaKeyTest, SerializeAndReloadPrivateKeyWithAllowedSchemes) {
const std::vector<uint8_t> raw_key_data = key_->Serialize();
std::vector<uint8_t> key_data = {'S', 'I', 'G', 'N', 0x00, 0x00, 0x00, 0x03};
key_data.insert(key_data.end(), raw_key_data.begin(), raw_key_data.end());
std::unique_ptr<RsaPrivateKey> explicit_key = RsaPrivateKey::Load(key_data);
ASSERT_TRUE(explicit_key);
EXPECT_EQ(key_->field_size(), explicit_key->field_size());
const uint32_t kExpectedSchemes = 0x03;
EXPECT_EQ(explicit_key->allowed_schemes(), kExpectedSchemes);
const std::vector<uint8_t> explicit_key_data = explicit_key->Serialize();
ASSERT_EQ(key_data.size(), explicit_key_data.size());
ASSERT_EQ(key_data, explicit_key_data);
}
// Checks that a public key can be created from the private key.
TEST_P(OEMCryptoRsaKeyTest, DerivePublicKey) {
std::unique_ptr<RsaPublicKey> pub_key = key_->MakePublicKey();
ASSERT_TRUE(pub_key);
EXPECT_TRUE(key_->IsMatchingPublicKey(*pub_key));
}
// Checks that the public key serialization APIs are compatible
// and performing in a manner that is similar to other OEMCrypto methods
// that retrieve data.
TEST_P(OEMCryptoRsaKeyTest, SerializePublicKey) {
std::unique_ptr<RsaPublicKey> pub_key = key_->MakePublicKey();
ASSERT_TRUE(pub_key);
constexpr size_t kInitialBufferSize = 10; // Definitely too small.
size_t buffer_size = kInitialBufferSize;
std::vector<uint8_t> buffer(buffer_size);
EXPECT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
pub_key->Serialize(buffer.data(), &buffer_size));
EXPECT_GT(buffer_size, kInitialBufferSize);
buffer.resize(buffer_size);
EXPECT_EQ(OEMCrypto_SUCCESS, pub_key->Serialize(buffer.data(), &buffer_size));
buffer.resize(buffer_size);
const std::vector<uint8_t> direct_key_data = pub_key->Serialize();
EXPECT_FALSE(direct_key_data.empty());
ASSERT_EQ(buffer.size(), direct_key_data.size());
for (size_t i = 0; i < buffer.size(); i++) {
ASSERT_EQ(buffer[i], direct_key_data[i]) << "i = " << std::to_string(i);
}
}
// Checks that a public key that is serialized can be deserialized and
// reload. Also checks that the serialization of a key produces the
// same data to ensure consistency.
TEST_P(OEMCryptoRsaKeyTest, SerializeAndReloadPublicKey) {
std::unique_ptr<RsaPublicKey> pub_key = key_->MakePublicKey();
ASSERT_TRUE(pub_key);
const std::vector<uint8_t> key_data = pub_key->Serialize();
std::unique_ptr<RsaPublicKey> loaded_key = RsaPublicKey::Load(key_data);
ASSERT_TRUE(loaded_key);
EXPECT_EQ(pub_key->field_size(), loaded_key->field_size());
EXPECT_EQ(pub_key->allowed_schemes(), loaded_key->allowed_schemes());
const std::vector<uint8_t> loaded_key_data = loaded_key->Serialize();
ASSERT_EQ(key_data.size(), loaded_key_data.size());
for (size_t i = 0; i < key_data.size(); i++) {
ASSERT_EQ(key_data[i], loaded_key_data[i]) << "i = " << std::to_string(i);
}
}
// Checks that a public key can be initialized from a ASN.1 DER encoded
// PrivateKeyInfo message.
TEST_P(OEMCryptoRsaKeyTest, SerializePrivateKeyAndReloadAsPublicKey) {
const std::vector<uint8_t> key_data = key_->Serialize();
ASSERT_FALSE(key_data.empty()) << "Failed to serialize as private key";
auto key_by_buffer =
RsaPublicKey::LoadPrivateKeyInfo(key_data.data(), key_data.size());
ASSERT_TRUE(key_by_buffer)
<< "Failed to deserialize private key into public key";
EXPECT_TRUE(key_->IsMatchingPublicKey(*key_by_buffer));
key_by_buffer.reset();
auto key_by_vector = RsaPublicKey::LoadPrivateKeyInfo(key_data);
ASSERT_TRUE(key_by_vector)
<< "Failed to deserialize private key into public key";
EXPECT_TRUE(key_->IsMatchingPublicKey(*key_by_vector));
key_by_vector.reset();
const std::string key_data_str(key_data.begin(), key_data.end());
auto key_by_string = RsaPublicKey::LoadPrivateKeyInfo(key_data_str);
ASSERT_TRUE(key_by_string)
<< "Failed to deserialize private key into public key";
EXPECT_TRUE(key_->IsMatchingPublicKey(*key_by_string));
}
// Checks that the RSA signature generating API operates similar to
// existing signature generation functions.
TEST_P(OEMCryptoRsaKeyTest, GenerateSignature) {
const std::vector<uint8_t> message = RandomData(kMessageSize);
ASSERT_FALSE(message.empty()) << "CdmRandom failed";
constexpr size_t kInitialBufferSize = 10; // Definitely too small.
size_t signature_size = kInitialBufferSize;
std::vector<uint8_t> signature(signature_size);
EXPECT_EQ(
OEMCrypto_ERROR_SHORT_BUFFER,
key_->GenerateSignature(message.data(), message.size(), kRsaPssDefault,
signature.data(), &signature_size));
EXPECT_GT(signature_size, kInitialBufferSize);
signature.resize(signature_size);
EXPECT_EQ(
OEMCrypto_SUCCESS,
key_->GenerateSignature(message.data(), message.size(), kRsaPssDefault,
signature.data(), &signature_size));
signature.resize(signature_size);
EXPECT_LE(signature_size, key_->SignatureSize());
}
// Checks that RSA signatures can be verified by an RSA public key.
TEST_P(OEMCryptoRsaKeyTest, VerifySignature) {
const std::vector<uint8_t> message = RandomData(kMessageSize);
ASSERT_FALSE(message.empty()) << "CdmRandom failed";
const std::vector<uint8_t> signature = key_->GenerateSignature(message);
std::unique_ptr<RsaPublicKey> pub_key = key_->MakePublicKey();
ASSERT_TRUE(pub_key);
EXPECT_EQ(OEMCrypto_SUCCESS, pub_key->VerifySignature(message, signature));
// Check with different message.
const std::vector<uint8_t> message_two = RandomData(kMessageSize);
EXPECT_EQ(OEMCrypto_ERROR_SIGNATURE_FAILURE,
pub_key->VerifySignature(message_two, signature));
// Check with bad signature.
const std::vector<uint8_t> bad_signature = RandomData(signature.size());
EXPECT_EQ(OEMCrypto_ERROR_SIGNATURE_FAILURE,
pub_key->VerifySignature(message, bad_signature));
}
// Checks that the special CAST receiver signature scheme works
// to the degree that it is possible to test.
TEST_P(OEMCryptoRsaKeyTest, GenerateAndVerifyRsaSignature) {
// Key must be enabled for PKCS1 Block 1 padding scheme.
// To do so, the key is serialized and the padding scheme is
// added to the key data.
const std::vector<uint8_t> key_data = key_->Serialize();
ASSERT_FALSE(key_data.empty());
std::vector<uint8_t> pkcs_enabled_key_data = {
'S', 'I', 'G', 'N', 0x00, 0x00, 0x00, kSign_PKCS1_Block1};
pkcs_enabled_key_data.insert(pkcs_enabled_key_data.end(), key_data.begin(),
key_data.end());
std::unique_ptr<RsaPrivateKey> pkcs_enabled_key =
RsaPrivateKey::Load(pkcs_enabled_key_data);
ASSERT_TRUE(pkcs_enabled_key);
// The actual cast message is a domain specific hash of the message,
// however, random data works for testing purposes.
const std::vector<uint8_t> message = RandomData(kCastMessageSize);
// Generate signature.
constexpr size_t kInitialBufferSize = 10; // Definitely too small.
size_t signature_size = kInitialBufferSize;
std::vector<uint8_t> signature(signature_size);
EXPECT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
pkcs_enabled_key->GenerateSignature(message.data(), message.size(),
kRsaPkcs1Cast, signature.data(),
&signature_size));
EXPECT_GT(signature_size, kInitialBufferSize);
signature.resize(signature_size);
EXPECT_EQ(OEMCrypto_SUCCESS,
pkcs_enabled_key->GenerateSignature(message.data(), message.size(),
kRsaPkcs1Cast, signature.data(),
&signature_size));
signature.resize(signature_size);
EXPECT_LE(signature_size, pkcs_enabled_key->SignatureSize());
// Verify signature.
std::unique_ptr<RsaPublicKey> pub_key = pkcs_enabled_key->MakePublicKey();
ASSERT_TRUE(pub_key);
EXPECT_EQ(OEMCrypto_SUCCESS,
pub_key->VerifySignature(message, signature, kRsaPkcs1Cast));
}
// Verifies the session key exchange protocol used by the licensing
// server.
TEST_P(OEMCryptoRsaKeyTest, ShareSessionKey) {
constexpr size_t kSessionKeySize = 16;
std::unique_ptr<RsaPublicKey> public_key = key_->MakePublicKey();
ASSERT_TRUE(public_key);
// Generate session key.
const std::vector<uint8_t> session_key = RandomData(kSessionKeySize);
ASSERT_FALSE(session_key.empty());
// Server's perspective.
constexpr size_t kInitialBufferSize = 10; // Definitely too small.
size_t enc_session_key_size = kInitialBufferSize;
std::vector<uint8_t> enc_session_key(enc_session_key_size);
OEMCryptoResult result = public_key->EncryptSessionKey(
session_key.data(), session_key.size(), enc_session_key.data(),
&enc_session_key_size);
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, result);
enc_session_key.resize(enc_session_key_size);
result = public_key->EncryptSessionKey(session_key.data(), session_key.size(),
enc_session_key.data(),
&enc_session_key_size);
ASSERT_EQ(OEMCrypto_SUCCESS, result);
enc_session_key.resize(enc_session_key_size);
// Client's perspective.
size_t received_session_key_size = kInitialBufferSize;
std::vector<uint8_t> received_session_key(received_session_key_size);
result = key_->DecryptSessionKey(
enc_session_key.data(), enc_session_key.size(),
received_session_key.data(), &received_session_key_size);
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, result);
received_session_key.resize(received_session_key_size);
result = key_->DecryptSessionKey(
enc_session_key.data(), enc_session_key.size(),
received_session_key.data(), &received_session_key_size);
ASSERT_EQ(OEMCrypto_SUCCESS, result);
received_session_key.resize(received_session_key_size);
// Compare keys.
ASSERT_EQ(session_key.size(), received_session_key.size());
ASSERT_EQ(session_key, received_session_key);
}
// Verifies the encryption key exchange protocol used by the licensing
// server.
TEST_P(OEMCryptoRsaKeyTest, ShareEncryptionKey) {
constexpr size_t kEncryptionKeySize = 16;
std::unique_ptr<RsaPublicKey> public_key = key_->MakePublicKey();
ASSERT_TRUE(public_key);
// Generate session key.
const std::vector<uint8_t> encryption_key = RandomData(kEncryptionKeySize);
ASSERT_FALSE(encryption_key.empty());
// Server's perspective.
constexpr size_t kInitialBufferSize = 10; // Definitely too small.
size_t enc_encryption_key_size = kInitialBufferSize;
std::vector<uint8_t> enc_encryption_key(enc_encryption_key_size);
OEMCryptoResult result = public_key->EncryptEncryptionKey(
encryption_key.data(), encryption_key.size(), enc_encryption_key.data(),
&enc_encryption_key_size);
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, result);
enc_encryption_key.resize(enc_encryption_key_size);
result = public_key->EncryptEncryptionKey(
encryption_key.data(), encryption_key.size(), enc_encryption_key.data(),
&enc_encryption_key_size);
ASSERT_EQ(OEMCrypto_SUCCESS, result);
enc_encryption_key.resize(enc_encryption_key_size);
// Client's perspective.
size_t received_encryption_key_size = kInitialBufferSize;
std::vector<uint8_t> received_encryption_key(received_encryption_key_size);
result = key_->DecryptEncryptionKey(
enc_encryption_key.data(), enc_encryption_key.size(),
received_encryption_key.data(), &received_encryption_key_size);
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, result);
received_encryption_key.resize(received_encryption_key_size);
result = key_->DecryptEncryptionKey(
enc_encryption_key.data(), enc_encryption_key.size(),
received_encryption_key.data(), &received_encryption_key_size);
ASSERT_EQ(OEMCrypto_SUCCESS, result);
received_encryption_key.resize(received_encryption_key_size);
// Compare keys.
ASSERT_EQ(encryption_key.size(), received_encryption_key.size());
ASSERT_EQ(encryption_key, received_encryption_key);
}
INSTANTIATE_TEST_SUITE_P(AllFieldSizes, OEMCryptoRsaKeyTest,
::testing::Values(kRsa2048Bit, kRsa3072Bit));
} // namespace util
} // namespace wvoec

View File

@@ -0,0 +1,74 @@
// 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 utilities of OEMCrypto APIs
//
#include <gtest/gtest.h>
#include "wvcrc32.h"
namespace wvoec {
namespace util {
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(0xF88AC628u, ComputeCrc32("abcdefg"));
EXPECT_EQ(0xDF520F72u, ComputeCrc32("Widevine"));
EXPECT_EQ(0x0376E6E7u, ComputeCrc32("123456789"));
EXPECT_EQ(0xBA62119Eu,
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(0xBA62119Eu, 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 util
} // namespace wvoec