166 lines
5.5 KiB
C++
166 lines
5.5 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
// Copyright 2016 Google LLC.
|
|
//
|
|
// This software is licensed under the terms defined in the Widevine Master
|
|
// License Agreement. For a copy of this agreement, please contact
|
|
// widevine-licensing@google.com.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "common/aes_cbc_util.h"
|
|
#include "testing/gmock.h"
|
|
#include "testing/gunit.h"
|
|
|
|
namespace {
|
|
|
|
const uint8_t kKey[] = {
|
|
0x87, 0x27, 0xa4, 0x0e, 0xbd, 0x82, 0x32, 0x9e,
|
|
0x6b, 0x3b, 0x4e, 0x29, 0xfa, 0x3b, 0x00, 0x4b,
|
|
};
|
|
|
|
const uint8_t kIv[] = {
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
|
};
|
|
|
|
} // namespace
|
|
|
|
namespace widevine {
|
|
namespace crypto_util {
|
|
|
|
TEST(CryptoUtilTest, EncryptAndDecryptAesCbc) {
|
|
std::string plain_text("Foo");
|
|
std::string ciphertext =
|
|
EncryptAesCbc(std::string(kKey, kKey + sizeof(kKey)),
|
|
std::string(kIv, kIv + sizeof(kIv)), plain_text);
|
|
std::string expected_ciphertext(
|
|
"\xCF\x1A\x3\x1C\x9C\x8C\xB9Z\xEC\xC0\x17\xDCRxX\xD7");
|
|
ASSERT_EQ(0, ciphertext.size() % 16);
|
|
ASSERT_GT(ciphertext.size(), plain_text.size());
|
|
ASSERT_EQ(expected_ciphertext, ciphertext);
|
|
|
|
std::string decrypted =
|
|
DecryptAesCbc(std::string(kKey, kKey + sizeof(kKey)),
|
|
std::string(kIv, kIv + sizeof(kIv)), ciphertext);
|
|
ASSERT_EQ(plain_text, decrypted);
|
|
}
|
|
|
|
TEST(CryptoUtilTest, DecryptAesCbcNoPad) {
|
|
const uint8_t kKey[] = {
|
|
0xdd, 0x71, 0x39, 0xea, 0xfa, 0xce, 0xed, 0x7c,
|
|
0xda, 0x9f, 0x25, 0xda, 0x8a, 0xa9, 0x15, 0xea,
|
|
};
|
|
const uint8_t kIv[] = {
|
|
0x5d, 0x16, 0x44, 0xea, 0xec, 0x11, 0xf9, 0x83,
|
|
0x14, 0x75, 0x41, 0xe4, 0x6e, 0xeb, 0x27, 0x74,
|
|
};
|
|
const uint8_t kCiphertext[] = {
|
|
0x6d, 0xa6, 0xda, 0xe4, 0xee, 0x40, 0x09, 0x17,
|
|
0x54, 0x7b, 0xba, 0xa5, 0x27, 0xb8, 0x82, 0x1b,
|
|
};
|
|
const uint8_t kExpectedPlaintext[] = {
|
|
0xb3, 0x49, 0xd4, 0x80, 0x9e, 0x91, 0x06, 0x87,
|
|
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10,
|
|
};
|
|
const uint8_t kExpectedPlaintextEmptyIv[] = {
|
|
0xee, 0x5f, 0x90, 0x6a, 0x72, 0x80, 0xff, 0x04,
|
|
0x14, 0x75, 0x41, 0xa4, 0x6e, 0xeb, 0x27, 0x64,
|
|
};
|
|
|
|
std::string decrypted = DecryptAesCbcNoPad(
|
|
std::string(kKey, kKey + sizeof(kKey)),
|
|
std::string(kIv, kIv + sizeof(kIv)),
|
|
std::string(kCiphertext, kCiphertext + sizeof(kCiphertext)));
|
|
ASSERT_EQ(std::string(kExpectedPlaintext,
|
|
kExpectedPlaintext + sizeof(kExpectedPlaintext)),
|
|
decrypted);
|
|
|
|
std::string dummy_iv;
|
|
decrypted = DecryptAesCbcNoPad(
|
|
std::string(kKey, kKey + sizeof(kKey)), dummy_iv,
|
|
std::string(kCiphertext, kCiphertext + sizeof(kCiphertext)));
|
|
ASSERT_EQ(std::string(
|
|
kExpectedPlaintextEmptyIv,
|
|
kExpectedPlaintextEmptyIv + sizeof(kExpectedPlaintextEmptyIv)),
|
|
decrypted);
|
|
}
|
|
|
|
TEST(CryptoUtilTest, TestFailedEncrypt) {
|
|
// Test with bogus initialization vector.
|
|
std::string plain_text("Foo");
|
|
std::string bogus_iv("bogus");
|
|
std::string ciphertext = EncryptAesCbc(std::string(kKey, kKey + sizeof(kKey)),
|
|
bogus_iv, plain_text);
|
|
ASSERT_EQ(ciphertext.size(), 0);
|
|
|
|
// Test with bogus key.
|
|
std::string bogus_key("bogus");
|
|
ciphertext =
|
|
EncryptAesCbc(bogus_key, std::string(kIv, kIv + sizeof(kIv)), plain_text);
|
|
ASSERT_EQ(ciphertext.size(), 0);
|
|
}
|
|
|
|
TEST(CryptoUtilTest, TestFailedEncryptNoPad) {
|
|
std::string plaintext("0123456789abcdef");
|
|
std::string key(kKey, kKey + sizeof(kKey));
|
|
std::string iv(kIv, kIv + sizeof(kIv));
|
|
|
|
// Control.
|
|
std::string ciphertext = EncryptAesCbcNoPad(key, iv, plaintext);
|
|
ASSERT_EQ(plaintext.size(), ciphertext.size());
|
|
|
|
// Bogus key.
|
|
std::string bogus_key("bogus");
|
|
ciphertext = EncryptAesCbcNoPad(bogus_key, iv, plaintext);
|
|
EXPECT_EQ(ciphertext.size(), 0);
|
|
|
|
// Bogus IV.
|
|
std::string bogus_iv("bogus");
|
|
ciphertext = EncryptAesCbcNoPad(key, bogus_iv, plaintext);
|
|
EXPECT_EQ(ciphertext.size(), 0);
|
|
|
|
// Incorrectly-sized plaintext.
|
|
std::string bad_plaintext("Foo");
|
|
ciphertext = EncryptAesCbcNoPad(key, iv, bad_plaintext);
|
|
EXPECT_EQ(ciphertext.size(), 0);
|
|
}
|
|
|
|
TEST(CryptoUtilTest, TestFailedDecrypt) {
|
|
// First, encrypt the data.
|
|
std::string plain_text("Foo");
|
|
std::string ciphertext =
|
|
EncryptAesCbc(std::string(kKey, kKey + sizeof(kKey)),
|
|
std::string(kIv, kIv + sizeof(kIv)), plain_text);
|
|
ASSERT_NE(ciphertext.size(), 0);
|
|
|
|
// Test Decrypt with bogus iv.
|
|
std::string bogus_iv("bogus");
|
|
plain_text = DecryptAesCbc(std::string(kKey, kKey + sizeof(kKey)), bogus_iv,
|
|
ciphertext);
|
|
ASSERT_EQ(plain_text.size(), 0);
|
|
|
|
// Test Decrypt with bogus key.
|
|
std::string bogus_key("bogus");
|
|
plain_text =
|
|
DecryptAesCbc(bogus_key, std::string(kIv, kIv + sizeof(kIv)), ciphertext);
|
|
ASSERT_EQ(plain_text.size(), 0);
|
|
}
|
|
|
|
TEST(CryptoUtilTest, TestEmptyEncrypt) {
|
|
EXPECT_EQ("\xDBx\xD9\x91\xE8\x1D\xD9\x19\x80r\x12\x89\xD7Kp\xEB",
|
|
EncryptAesCbc(std::string(kKey, kKey + sizeof(kKey)),
|
|
std::string(kIv, kIv + sizeof(kIv)), ""));
|
|
}
|
|
|
|
TEST(CryptoUtilTest, TestEmptyDecryptAesCbc) {
|
|
EXPECT_EQ("", DecryptAesCbc(std::string(kKey, kKey + sizeof(kKey)),
|
|
std::string(kIv, kIv + sizeof(kIv)), ""));
|
|
}
|
|
|
|
TEST(CryptoUtilTest, TestEmptyDecryptAesCbcNoPad) {
|
|
EXPECT_EQ("", DecryptAesCbcNoPad(std::string(kKey, kKey + sizeof(kKey)),
|
|
std::string(kIv, kIv + sizeof(kIv)), ""));
|
|
}
|
|
|
|
} // namespace crypto_util
|
|
} // namespace widevine
|