Implemented AES-CBC with Ciphertext Stealing for WVM decryption.

Change-Id: I4a1ba4247bb6f055905663568699b06d7c18a968
This commit is contained in:
Thomas Inskip 2014-09-09 15:56:02 -07:00 committed by Ramji Chandramouli
parent 3114ee945d
commit fd35084722
5 changed files with 463 additions and 48 deletions

View File

@ -143,10 +143,10 @@ bool AesCtrEncryptor::SetIv(const std::vector<uint8>& iv) {
return true;
}
AesCbcEncryptor::AesCbcEncryptor() {}
AesCbcEncryptor::~AesCbcEncryptor() {}
AesCbcPkcs5Encryptor::AesCbcPkcs5Encryptor() {}
AesCbcPkcs5Encryptor::~AesCbcPkcs5Encryptor() {}
bool AesCbcEncryptor::InitializeWithIv(const std::vector<uint8>& key,
bool AesCbcPkcs5Encryptor::InitializeWithIv(const std::vector<uint8>& key,
const std::vector<uint8>& iv) {
if (!IsKeySizeValidForAes(key.size())) {
LOG(ERROR) << "Invalid AES key size: " << key.size();
@ -164,7 +164,7 @@ bool AesCbcEncryptor::InitializeWithIv(const std::vector<uint8>& key,
return true;
}
void AesCbcEncryptor::Encrypt(const std::string& plaintext,
void AesCbcPkcs5Encryptor::Encrypt(const std::string& plaintext,
std::string* ciphertext) {
DCHECK(ciphertext);
DCHECK(encrypt_key_);
@ -185,7 +185,7 @@ void AesCbcEncryptor::Encrypt(const std::string& plaintext,
AES_ENCRYPT);
}
bool AesCbcEncryptor::SetIv(const std::vector<uint8>& iv) {
bool AesCbcPkcs5Encryptor::SetIv(const std::vector<uint8>& iv) {
if (iv.size() != AES_BLOCK_SIZE) {
LOG(ERROR) << "Invalid IV size: " << iv.size();
return false;
@ -195,10 +195,10 @@ bool AesCbcEncryptor::SetIv(const std::vector<uint8>& iv) {
return true;
}
AesCbcDecryptor::AesCbcDecryptor() {}
AesCbcDecryptor::~AesCbcDecryptor() {}
AesCbcPkcs5Decryptor::AesCbcPkcs5Decryptor() {}
AesCbcPkcs5Decryptor::~AesCbcPkcs5Decryptor() {}
bool AesCbcDecryptor::InitializeWithIv(const std::vector<uint8>& key,
bool AesCbcPkcs5Decryptor::InitializeWithIv(const std::vector<uint8>& key,
const std::vector<uint8>& iv) {
if (!IsKeySizeValidForAes(key.size())) {
LOG(ERROR) << "Invalid AES key size: " << key.size();
@ -216,7 +216,7 @@ bool AesCbcDecryptor::InitializeWithIv(const std::vector<uint8>& key,
return true;
}
bool AesCbcDecryptor::Decrypt(const std::string& ciphertext,
bool AesCbcPkcs5Decryptor::Decrypt(const std::string& ciphertext,
std::string* plaintext) {
if ((ciphertext.size() % AES_BLOCK_SIZE) != 0) {
LOG(ERROR) << "Expecting cipher text size to be multiple of "
@ -246,7 +246,226 @@ bool AesCbcDecryptor::Decrypt(const std::string& ciphertext,
return true;
}
bool AesCbcDecryptor::SetIv(const std::vector<uint8>& iv) {
bool AesCbcPkcs5Decryptor::SetIv(const std::vector<uint8>& iv) {
if (iv.size() != AES_BLOCK_SIZE) {
LOG(ERROR) << "Invalid IV size: " << iv.size();
return false;
}
iv_ = iv;
return true;
}
AesCbcCtsEncryptor::AesCbcCtsEncryptor() {}
AesCbcCtsEncryptor::~AesCbcCtsEncryptor() {}
bool AesCbcCtsEncryptor::InitializeWithIv(const std::vector<uint8>& key,
const std::vector<uint8>& iv) {
if (!IsKeySizeValidForAes(key.size())) {
LOG(ERROR) << "Invalid AES key size: " << key.size();
return false;
}
if (iv.size() != AES_BLOCK_SIZE) {
LOG(ERROR) << "Invalid IV size: " << iv.size();
return false;
}
encrypt_key_.reset(new AES_KEY());
CHECK_EQ(AES_set_encrypt_key(&key[0], key.size() * 8, encrypt_key_.get()), 0);
iv_ = iv;
return true;
}
void AesCbcCtsEncryptor::Encrypt(const uint8* plaintext,
size_t size,
uint8* ciphertext) {
DCHECK(plaintext);
DCHECK(ciphertext);
if (size < AES_BLOCK_SIZE) {
// Don't have a full block, leave unencrypted.
memcpy(ciphertext, plaintext, size);
return;
}
std::vector<uint8> iv(iv_);
size_t residual_block_size = size % AES_BLOCK_SIZE;
size_t cbc_size = size - residual_block_size;
// Encrypt everything but the residual block using CBC.
AES_cbc_encrypt(plaintext,
ciphertext,
cbc_size,
encrypt_key_.get(),
&iv[0],
AES_ENCRYPT);
if (residual_block_size == 0) {
// No residual block. No need to do ciphertext stealing.
return;
}
// Zero-pad the residual block and encrypt using CBC.
std::vector<uint8> residual_block(plaintext + size - residual_block_size,
plaintext + size);
residual_block.resize(AES_BLOCK_SIZE, 0);
AES_cbc_encrypt(&residual_block[0],
&residual_block[0],
AES_BLOCK_SIZE,
encrypt_key_.get(),
&iv[0],
AES_ENCRYPT);
// Replace the last full block with the zero-padded, encrypted residual block,
// and replace the residual block with the equivalent portion of the last full
// encrypted block. It may appear that some encrypted bits of the last full
// block are lost, but they are not, as they were used as the IV when
// encrypting the zero-padded residual block.
uint8* residual_ciphertext_block = ciphertext + size - residual_block_size;
memcpy(residual_ciphertext_block,
residual_ciphertext_block - AES_BLOCK_SIZE,
residual_block_size);
memcpy(residual_ciphertext_block - AES_BLOCK_SIZE,
residual_block.data(),
AES_BLOCK_SIZE);
}
void AesCbcCtsEncryptor::Encrypt(const std::vector<uint8>& plaintext,
std::vector<uint8>* ciphertext) {
DCHECK(ciphertext);
ciphertext->resize(plaintext.size(), 0);
if (plaintext.empty())
return;
return Encrypt(plaintext.data(), plaintext.size(), &(*ciphertext)[0]);
}
bool AesCbcCtsEncryptor::SetIv(const std::vector<uint8>& iv) {
if (iv.size() != AES_BLOCK_SIZE) {
LOG(ERROR) << "Invalid IV size: " << iv.size();
return false;
}
iv_ = iv;
return true;
}
AesCbcCtsDecryptor::AesCbcCtsDecryptor() {}
AesCbcCtsDecryptor::~AesCbcCtsDecryptor() {}
bool AesCbcCtsDecryptor::InitializeWithIv(const std::vector<uint8>& key,
const std::vector<uint8>& iv) {
if (!IsKeySizeValidForAes(key.size())) {
LOG(ERROR) << "Invalid AES key size: " << key.size();
return false;
}
if (iv.size() != AES_BLOCK_SIZE) {
LOG(ERROR) << "Invalid IV size: " << iv.size();
return false;
}
decrypt_key_.reset(new AES_KEY());
CHECK_EQ(AES_set_decrypt_key(&key[0], key.size() * 8, decrypt_key_.get()), 0);
iv_ = iv;
return true;
}
void AesCbcCtsDecryptor::Decrypt(const uint8* ciphertext,
size_t size,
uint8* plaintext) {
DCHECK(ciphertext);
DCHECK(plaintext);
if (size < AES_BLOCK_SIZE) {
// Don't have a full block, leave unencrypted.
memcpy(plaintext, ciphertext, size);
return;
}
std::vector<uint8> iv(iv_);
size_t residual_block_size = size % AES_BLOCK_SIZE;
if (residual_block_size == 0) {
// No residual block. No need to do ciphertext stealing.
AES_cbc_encrypt(ciphertext,
plaintext,
size,
decrypt_key_.get(),
&iv[0],
AES_DECRYPT);
return;
}
// AES-CBC decrypt everything up to the next-to-last full block.
size_t cbc_size = size - residual_block_size;
if (cbc_size > AES_BLOCK_SIZE) {
AES_cbc_encrypt(ciphertext,
plaintext,
cbc_size - AES_BLOCK_SIZE,
decrypt_key_.get(),
&iv[0],
AES_DECRYPT);
}
// Determine what the last IV should be so that we can "skip ahead" in the
// CBC decryption.
std::vector<uint8> last_iv(ciphertext + size - residual_block_size,
ciphertext + size);
last_iv.resize(AES_BLOCK_SIZE, 0);
// Decrypt the next-to-last block using the IV determined above. This decrypts
// the residual block bits.
AES_cbc_encrypt(ciphertext + size - residual_block_size - AES_BLOCK_SIZE,
plaintext + size - residual_block_size - AES_BLOCK_SIZE,
AES_BLOCK_SIZE,
decrypt_key_.get(),
&last_iv[0],
AES_DECRYPT);
// Swap back the residual block bits and the next-to-last full block.
if (plaintext == ciphertext) {
uint8* ptr1 = plaintext + size - residual_block_size;
uint8* ptr2 = plaintext + size - residual_block_size - AES_BLOCK_SIZE;
for (size_t i = 0; i < residual_block_size; ++i) {
uint8 temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
++ptr1;
++ptr2;
}
} else {
uint8* residual_plaintext_block = plaintext + size - residual_block_size;
memcpy(residual_plaintext_block,
residual_plaintext_block - AES_BLOCK_SIZE,
residual_block_size);
memcpy(residual_plaintext_block - AES_BLOCK_SIZE,
ciphertext + size - residual_block_size,
residual_block_size);
}
// Decrypt the last full block.
AES_cbc_encrypt(plaintext + size - residual_block_size - AES_BLOCK_SIZE,
plaintext + size - residual_block_size - AES_BLOCK_SIZE,
AES_BLOCK_SIZE,
decrypt_key_.get(),
&iv[0],
AES_DECRYPT);
}
void AesCbcCtsDecryptor::Decrypt(const std::vector<uint8>& ciphertext,
std::vector<uint8>* plaintext) {
DCHECK(plaintext);
plaintext->resize(ciphertext.size(), 0);
if (ciphertext.empty())
return;
return Decrypt(ciphertext.data(), ciphertext.size(), &(*plaintext)[0]);
}
bool AesCbcCtsDecryptor::SetIv(const std::vector<uint8>& iv) {
if (iv.size() != AES_BLOCK_SIZE) {
LOG(ERROR) << "Invalid IV size: " << iv.size();
return false;

View File

@ -21,6 +21,7 @@ typedef struct aes_key_st AES_KEY;
namespace edash_packager {
namespace media {
// Class which implements AES-CTR counter-mode encryption/decryption.
class AesCtrEncryptor {
public:
AesCtrEncryptor();
@ -109,10 +110,12 @@ class AesCtrEncryptor {
DISALLOW_COPY_AND_ASSIGN(AesCtrEncryptor);
};
class AesCbcEncryptor {
// Class which implements AES-CBC (Cipher block chaining) encryption with
// PKCS#5 padding.
class AesCbcPkcs5Encryptor {
public:
AesCbcEncryptor();
~AesCbcEncryptor();
AesCbcPkcs5Encryptor();
~AesCbcPkcs5Encryptor();
/// Initialize the encryptor with specified key and IV.
/// @param key should be 128 bits or 192 bits or 256 bits in size as defined
@ -135,13 +138,15 @@ class AesCbcEncryptor {
std::vector<uint8> iv_;
scoped_ptr<AES_KEY> encrypt_key_;
DISALLOW_COPY_AND_ASSIGN(AesCbcEncryptor);
DISALLOW_COPY_AND_ASSIGN(AesCbcPkcs5Encryptor);
};
class AesCbcDecryptor {
// Class which implements AES-CBC (Cipher block chaining) decryption with
// PKCS#5 padding.
class AesCbcPkcs5Decryptor {
public:
AesCbcDecryptor();
~AesCbcDecryptor();
AesCbcPkcs5Decryptor();
~AesCbcPkcs5Decryptor();
/// Initialize the decryptor with specified key and IV.
/// @param key should be 128 bits or 192 bits or 256 bits in size as defined
@ -165,7 +170,92 @@ class AesCbcDecryptor {
std::vector<uint8> iv_;
scoped_ptr<AES_KEY> decrypt_key_;
DISALLOW_COPY_AND_ASSIGN(AesCbcDecryptor);
DISALLOW_COPY_AND_ASSIGN(AesCbcPkcs5Decryptor);
};
// Class which implements AES-CBC (Cipher block chaining) encryption with
// Ciphertext stealing.
class AesCbcCtsEncryptor {
public:
AesCbcCtsEncryptor();
~AesCbcCtsEncryptor();
/// Initialize the encryptor with specified key and IV.
/// @param key should be 128 bits or 192 bits or 256 bits in size as defined
/// in AES spec.
/// @param iv should be 16 bytes in size.
/// @return true on successful initialization, false otherwise.
bool InitializeWithIv(const std::vector<uint8>& key,
const std::vector<uint8>& iv);
/// @param plaintext points to the data to be encrypted.
/// @param size is the number of bytes to be encrypted. If less than 16
/// bytes, it will be copied in the clear.
/// @param ciphertext should not be NULL. The buffer should be at least
/// @a size bytes in length.
void Encrypt(const uint8* plaintext,
size_t size,
uint8* ciphertext);
/// @param plaintext contains the data to be encrypted. If less than 16
/// bytes in size, it will be copied in the clear.
/// @param ciphertext should not be NULL. Caller retains ownership.
void Encrypt(const std::vector<uint8>& plaintext,
std::vector<uint8>* ciphertext);
/// @param iv is the initialization vector. Should be 16 bytes in size.
/// @return true if successful, false if the input is invalid.
bool SetIv(const std::vector<uint8>& iv);
const std::vector<uint8>& iv() const { return iv_; }
private:
std::vector<uint8> iv_;
scoped_ptr<AES_KEY> encrypt_key_;
DISALLOW_COPY_AND_ASSIGN(AesCbcCtsEncryptor);
};
// Class which implements AES-CBC (Cipher block chaining) decryption with
// Ciphertext stealing.
class AesCbcCtsDecryptor {
public:
AesCbcCtsDecryptor();
~AesCbcCtsDecryptor();
/// Initialize the decryptor with specified key and IV.
/// @param key should be 128 bits or 192 bits or 256 bits in size as defined
/// in AES spec.
/// @param iv should be 16 bytes in size.
/// @return true on successful initialization, false otherwise.
bool InitializeWithIv(const std::vector<uint8>& key,
const std::vector<uint8>& iv);
/// @param ciphertext points to the data to be decrypted.
/// @param size is the number of bytes to be decrypted. If less than 16
/// bytes, it will be copied in the clear.
/// @param plaintext should not be NULL. The buffer should be at least
/// @a size bytes in length.
void Decrypt(const uint8* ciphertext,
size_t size,
uint8* plaintext);
/// @param ciphertext contains the data to be decrypted. If less than 16
/// bytes in size, it will be copied in the clear.
/// @param plaintext should not be NULL. Caller retains ownership.
void Decrypt(const std::vector<uint8>& ciphertext,
std::vector<uint8>* plaintext);
/// @return true if successful, false if the input is invalid.
bool SetIv(const std::vector<uint8>& iv);
const std::vector<uint8>& iv() const { return iv_; }
private:
std::vector<uint8> iv_;
scoped_ptr<AES_KEY> decrypt_key_;
DISALLOW_COPY_AND_ASSIGN(AesCbcCtsDecryptor);
};
} // namespace media

View File

@ -17,10 +17,10 @@ const uint32 kAesBlockSize = 16;
// From NIST SP 800-38a test case: - F.5.1 CTR-AES128.Encrypt
// http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
const uint8 kAesCtrKey[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
const uint8 kAesKey[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
const uint8 kAesCtrIv[] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
const uint8 kAesIv[] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
const uint8 kAesCtrPlaintext[] = {
@ -136,8 +136,8 @@ namespace media {
class AesCtrEncryptorTest : public testing::Test {
public:
virtual void SetUp() {
key_.assign(kAesCtrKey, kAesCtrKey + arraysize(kAesCtrKey));
iv_.assign(kAesCtrIv, kAesCtrIv + arraysize(kAesCtrIv));
key_.assign(kAesKey, kAesKey + arraysize(kAesKey));
iv_.assign(kAesIv, kAesIv + arraysize(kAesIv));
plaintext_.assign(kAesCtrPlaintext,
kAesCtrPlaintext + arraysize(kAesCtrPlaintext));
ciphertext_.assign(kAesCtrCiphertext,
@ -298,13 +298,13 @@ INSTANTIATE_TEST_CASE_P(IvTestCases,
AesCtrEncryptorIvTest,
::testing::ValuesIn(kIvTestCases));
class AesCbcEncryptorTestEncryptionDecryption : public testing::Test {
class AesCbcPkcs5EncryptorTestEncryptionDecryption : public testing::Test {
public:
void TestEncryptionDecryption(const std::vector<uint8>& key,
const std::vector<uint8>& iv,
const std::string& plaintext,
const std::string& expected_ciphertext_hex) {
AesCbcEncryptor encryptor;
AesCbcPkcs5Encryptor encryptor;
EXPECT_TRUE(encryptor.InitializeWithIv(key, iv));
std::string ciphertext;
@ -312,7 +312,7 @@ class AesCbcEncryptorTestEncryptionDecryption : public testing::Test {
EXPECT_EQ(expected_ciphertext_hex,
base::HexEncode(ciphertext.data(), ciphertext.size()));
AesCbcDecryptor decryptor;
AesCbcPkcs5Decryptor decryptor;
ASSERT_TRUE(decryptor.InitializeWithIv(key, iv));
std::string decrypted;
@ -321,7 +321,7 @@ class AesCbcEncryptorTestEncryptionDecryption : public testing::Test {
}
};
TEST_F(AesCbcEncryptorTestEncryptionDecryption, EncryptAES256CBC) {
TEST_F(AesCbcPkcs5EncryptorTestEncryptionDecryption, EncryptAES256CBC) {
// NIST SP 800-38A test vector F.2.5 CBC-AES256.Encrypt.
static const uint8 kAesCbcKey[] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae,
@ -370,7 +370,7 @@ TEST_F(AesCbcEncryptorTestEncryptionDecryption, EncryptAES256CBC) {
TestEncryptionDecryption(key, iv, plaintext, expected_ciphertext_hex);
}
TEST_F(AesCbcEncryptorTestEncryptionDecryption, EncryptAES128CBCRegression) {
TEST_F(AesCbcPkcs5EncryptorTestEncryptionDecryption, EncryptAES128CBCRegression) {
const std::string kKey = "128=SixteenBytes";
const std::string kIv = "Sweet Sixteen IV";
const std::string kPlaintext =
@ -385,7 +385,7 @@ TEST_F(AesCbcEncryptorTestEncryptionDecryption, EncryptAES128CBCRegression) {
TestEncryptionDecryption(key, iv, kPlaintext, kExpectedCiphertextHex);
}
TEST_F(AesCbcEncryptorTestEncryptionDecryption, EncryptAES192CBCRegression) {
TEST_F(AesCbcPkcs5EncryptorTestEncryptionDecryption, EncryptAES192CBCRegression) {
const std::string kKey = "192bitsIsTwentyFourByte!";
const std::string kIv = "Sweet Sixteen IV";
const std::string kPlaintext = "Small text";
@ -397,7 +397,7 @@ TEST_F(AesCbcEncryptorTestEncryptionDecryption, EncryptAES192CBCRegression) {
TestEncryptionDecryption(key, iv, kPlaintext, kExpectedCiphertextHex);
}
class AesCbcEncryptorTest : public testing::Test {
class AesCbcPkcs5EncryptorTest : public testing::Test {
public:
virtual void SetUp() {
const std::string kKey = "128=SixteenBytes";
@ -411,18 +411,18 @@ class AesCbcEncryptorTest : public testing::Test {
std::vector<uint8> iv_;
};
TEST_F(AesCbcEncryptorTest, UnsupportedKeySize) {
AesCbcEncryptor encryptor;
TEST_F(AesCbcPkcs5EncryptorTest, UnsupportedKeySize) {
AesCbcPkcs5Encryptor encryptor;
EXPECT_FALSE(encryptor.InitializeWithIv(std::vector<uint8>(15, 0), iv_));
}
TEST_F(AesCbcEncryptorTest, UnsupportedIvSize) {
AesCbcEncryptor encryptor;
TEST_F(AesCbcPkcs5EncryptorTest, UnsupportedIvSize) {
AesCbcPkcs5Encryptor encryptor;
EXPECT_FALSE(encryptor.InitializeWithIv(key_, std::vector<uint8>(14, 0)));
}
TEST_F(AesCbcEncryptorTest, EmptyEncrypt) {
AesCbcEncryptor encryptor;
TEST_F(AesCbcPkcs5EncryptorTest, EmptyEncrypt) {
AesCbcPkcs5Encryptor encryptor;
ASSERT_TRUE(encryptor.InitializeWithIv(key_, iv_));
std::string ciphertext;
@ -432,13 +432,119 @@ TEST_F(AesCbcEncryptorTest, EmptyEncrypt) {
base::HexEncode(ciphertext.data(), ciphertext.size()));
}
TEST_F(AesCbcEncryptorTest, CipherTextNotMultipleOfBlockSize) {
AesCbcDecryptor decryptor;
TEST_F(AesCbcPkcs5EncryptorTest, CipherTextNotMultipleOfBlockSize) {
AesCbcPkcs5Decryptor decryptor;
ASSERT_TRUE(decryptor.InitializeWithIv(key_, iv_));
std::string plaintext;
EXPECT_FALSE(decryptor.Decrypt("1", &plaintext));
}
class AesCbcCtsEncryptorDecryptorTest : public testing::Test {
public:
virtual void SetUp() {
key_.assign(kAesKey, kAesKey + arraysize(kAesKey));
iv_.assign(kAesIv, kAesIv + arraysize(kAesIv));
}
void TestEncryptDecryptSeparateBuffers(
const std::vector<uint8>& plaintext,
const std::vector<uint8>& expected_ciphertext) {
ASSERT_TRUE(encryptor_.InitializeWithIv(key_, iv_));
ASSERT_TRUE(decryptor_.InitializeWithIv(key_, iv_));
std::vector<uint8> encrypted;
encryptor_.Encrypt(plaintext, &encrypted);
EXPECT_EQ(expected_ciphertext, encrypted);
std::vector<uint8> decrypted;
decryptor_.Decrypt(encrypted, &decrypted);
EXPECT_EQ(plaintext, decrypted);
}
void TestEncryptDecryptInPlace(
const std::vector<uint8>& plaintext,
const std::vector<uint8>& expected_ciphertext) {
ASSERT_TRUE(encryptor_.InitializeWithIv(key_, iv_));
ASSERT_TRUE(decryptor_.InitializeWithIv(key_, iv_));
std::vector<uint8> buffer(plaintext);
encryptor_.Encrypt(buffer, &buffer);
EXPECT_EQ(expected_ciphertext, buffer);
decryptor_.Decrypt(buffer, &buffer);
EXPECT_EQ(plaintext, buffer);
}
protected:
std::vector<uint8> key_;
std::vector<uint8> iv_;
AesCbcCtsEncryptor encryptor_;
AesCbcCtsDecryptor decryptor_;
};
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestWithResidualBytes) {
std::vector<uint8> plaintext;
ASSERT_TRUE(base::HexStringToBytes(
"e0818f2dc7caaa9edf09285a0c1fca98d39e9b08a47ab6911c4bbdf27d94"
"f917cdffc9ebb307141f23b0d3921e0ed7f86eb09381286f8e7a4f",
&plaintext));
std::vector<uint8> ciphertext;
ASSERT_TRUE(base::HexStringToBytes(
"b40a0b8704c74e22e8030cad6f272b34ace54cc7c9c64b2018bbcf23df018"
"39b14899441cf74a9fb2f2b229a609146f31be8e8a826eb6e857e",
&ciphertext));
TestEncryptDecryptSeparateBuffers(plaintext, ciphertext);
TestEncryptDecryptInPlace(plaintext, ciphertext);
}
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestEvenBlocks) {
std::vector<uint8> plaintext;
ASSERT_TRUE(base::HexStringToBytes(
"3f593e7a204a5e70f2814dca05aa49d36f2daddc9a24e0515802c539efc3"
"1094b3ad6c26d6f5c0e387545ce6a4c2c14d",
&plaintext));
std::vector<uint8> ciphertext;
ASSERT_TRUE(base::HexStringToBytes(
"5f32cd0504b27b25ee04090d88d37d340c9c0a9fa50b05358b98fad4302ea"
"480148d8aa091f4e7d186a7223df153f6f7",
&ciphertext));
TestEncryptDecryptSeparateBuffers(plaintext, ciphertext);
TestEncryptDecryptInPlace(plaintext, ciphertext);
}
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestOneBlockAndAHalf) {
std::vector<uint8> plaintext;
ASSERT_TRUE(base::HexStringToBytes(
"3f593e7a204a5e70f2814dca05aa49d36f2daddc9a4302ea",
&plaintext));
std::vector<uint8> ciphertext;
ASSERT_TRUE(base::HexStringToBytes(
"623fc113fe02ce85628deb58d652c6995f32cd0504b27b25",
&ciphertext));
TestEncryptDecryptSeparateBuffers(plaintext, ciphertext);
TestEncryptDecryptInPlace(plaintext, ciphertext);
}
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestZeroEncryptedBlocks) {
std::vector<uint8> plaintext;
ASSERT_TRUE(base::HexStringToBytes("3f593e7a204a5e70f2", &plaintext));
TestEncryptDecryptSeparateBuffers(plaintext, plaintext);
TestEncryptDecryptInPlace(plaintext, plaintext);
}
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestZeroBytes) {
std::vector<uint8> plaintext;
TestEncryptDecryptSeparateBuffers(plaintext, plaintext);
TestEncryptDecryptInPlace(plaintext, plaintext);
}
} // namespace media
} // namespace edash_packager

View File

@ -19,7 +19,7 @@ RequestSigner::RequestSigner(const std::string& signer_name)
RequestSigner::~RequestSigner() {}
AesRequestSigner::AesRequestSigner(const std::string& signer_name,
scoped_ptr<AesCbcEncryptor> encryptor)
scoped_ptr<AesCbcPkcs5Encryptor> encryptor)
: RequestSigner(signer_name), aes_cbc_encryptor_(encryptor.Pass()) {
DCHECK(aes_cbc_encryptor_);
}
@ -39,7 +39,7 @@ AesRequestSigner* AesRequestSigner::CreateSigner(const std::string& signer_name,
return NULL;
}
scoped_ptr<AesCbcEncryptor> encryptor(new AesCbcEncryptor());
scoped_ptr<AesCbcPkcs5Encryptor> encryptor(new AesCbcPkcs5Encryptor());
if (!encryptor->InitializeWithIv(aes_key, iv))
return NULL;
return new AesRequestSigner(signer_name, encryptor.Pass());

View File

@ -15,7 +15,7 @@
namespace edash_packager {
namespace media {
class AesCbcEncryptor;
class AesCbcPkcs5Encryptor;
class RsaPrivateKey;
/// Abstract class used for signature generation.
@ -57,9 +57,9 @@ class AesRequestSigner : public RequestSigner {
private:
AesRequestSigner(const std::string& signer_name,
scoped_ptr<AesCbcEncryptor> encryptor);
scoped_ptr<AesCbcPkcs5Encryptor> encryptor);
scoped_ptr<AesCbcEncryptor> aes_cbc_encryptor_;
scoped_ptr<AesCbcPkcs5Encryptor> aes_cbc_encryptor_;
DISALLOW_COPY_AND_ASSIGN(AesRequestSigner);
};