Change AesCbcEncryptor/AesCbcDecryptor kNoPadding behavior

Leave unaligned residual block in clear in stead of rejecting it.

Change-Id: Id5452f32f6147e26ac68d9cddb948e8b4f77d107
This commit is contained in:
KongQun Yang 2016-04-13 16:43:55 -07:00
parent e253747453
commit c6445b749c
5 changed files with 24 additions and 13 deletions

View File

@ -553,6 +553,9 @@ const CbcTestCase kCbcTestCases[] = {
{kNoPadding,
"6bc1bee22e409f96e93d7e117393172a6bc1bee22e409f96e93d7e117393172a",
"77cde91fe6df9cbc5d0c98f96efd590bbddde439526f100c9545c274d4f7fd3f"},
{kNoPadding,
"6bc1bee22e409f96e93d7e117393172a6bc1bee22e409f96e93d7e117393172a1234",
"77cde91fe6df9cbc5d0c98f96efd590bbddde439526f100c9545c274d4f7fd3f1234"},
// Pkcs5 padding with zero bytes.
{kPkcs5Padding, "", "f6a3569dea3cda208eb3d5792942612b"},
// Cts Padding with zero bytes.

View File

@ -84,6 +84,7 @@ bool AesCbcDecryptor::CryptInternal(const uint8_t* ciphertext,
std::vector<uint8_t> local_iv(iv());
const size_t residual_block_size = ciphertext_size % AES_BLOCK_SIZE;
const size_t cbc_size = ciphertext_size - residual_block_size;
if (residual_block_size == 0) {
AES_cbc_encrypt(ciphertext, plaintext, ciphertext_size, aes_key(),
local_iv.data(), AES_DECRYPT);
@ -101,6 +102,15 @@ bool AesCbcDecryptor::CryptInternal(const uint8_t* ciphertext,
}
*plaintext_size -= num_padding_bytes;
return true;
} else if (padding_scheme_ == kNoPadding) {
AES_cbc_encrypt(ciphertext, plaintext, cbc_size, aes_key(), local_iv.data(),
AES_DECRYPT);
if (chain_across_calls_)
set_iv(local_iv);
// The residual block is not encrypted.
memcpy(plaintext + cbc_size, ciphertext + cbc_size, residual_block_size);
return true;
} else if (padding_scheme_ != kCtsPadding) {
LOG(ERROR) << "Expecting cipher text size to be multiple of "
<< AES_BLOCK_SIZE << ", got " << ciphertext_size;
@ -116,7 +126,6 @@ bool AesCbcDecryptor::CryptInternal(const uint8_t* ciphertext,
}
// AES-CBC decrypt everything up to the next-to-last full block.
const size_t cbc_size = ciphertext_size - residual_block_size;
if (cbc_size > AES_BLOCK_SIZE) {
AES_cbc_encrypt(ciphertext, plaintext, cbc_size - AES_BLOCK_SIZE, aes_key(),
local_iv.data(), AES_DECRYPT);

View File

@ -171,12 +171,6 @@ bool AesCbcEncryptor::CryptInternal(const uint8_t* plaintext,
DCHECK(aes_key());
const size_t residual_block_size = plaintext_size % AES_BLOCK_SIZE;
if (padding_scheme_ == kNoPadding && residual_block_size != 0) {
LOG(ERROR) << "Expecting input size to be multiple of " << AES_BLOCK_SIZE
<< ", got " << plaintext_size;
return false;
}
const size_t num_padding_bytes = NumPaddingBytes(plaintext_size);
const size_t required_ciphertext_size = plaintext_size + num_padding_bytes;
if (*ciphertext_size < required_ciphertext_size) {
@ -205,6 +199,12 @@ bool AesCbcEncryptor::CryptInternal(const uint8_t* plaintext,
}
DCHECK(!chain_across_calls_);
if (padding_scheme_ == kNoPadding) {
// The residual block is left unencrypted.
memcpy(ciphertext + cbc_size, plaintext + cbc_size, residual_block_size);
return true;
}
std::vector<uint8_t> residual_block(plaintext + cbc_size,
plaintext + plaintext_size);
DCHECK_EQ(residual_block.size(), residual_block_size);

View File

@ -71,8 +71,12 @@ class AesCtrEncryptor : public AesEncryptor {
};
enum CbcPaddingScheme {
// Residual block is left unencrypted.
kNoPadding,
// Residual block is padded with pkcs5 and encrypted.
kPkcs5Padding,
// Residual block and the next-to-last block are encrypted using ciphertext
// stealing method.
kCtsPadding,
};

View File

@ -330,12 +330,7 @@ Status EncryptingFragmenter::EncryptSample(scoped_refptr<MediaSample> sample) {
traf()->auxiliary_size.sample_info_sizes.push_back(
sample_encryption_entry.ComputeSize());
} else {
uint64_t encryption_data_size = sample->data_size();
// AES-CBC mode requires all encrypted cipher blocks to be 16 bytes. The
// partial blocks are left unencrypted.
if (protection_scheme_ == FOURCC_cbc1)
encryption_data_size -= encryption_data_size % kCencBlockSize;
EncryptBytes(data, encryption_data_size);
EncryptBytes(data, sample->data_size());
}
traf()->sample_encryption.sample_encryption_entries.push_back(