Change AesCbcEncryptor/AesCbcDecryptor kNoPadding behavior
Leave unaligned residual block in clear in stead of rejecting it. Change-Id: Id5452f32f6147e26ac68d9cddb948e8b4f77d107
This commit is contained in:
parent
e253747453
commit
c6445b749c
|
@ -553,6 +553,9 @@ const CbcTestCase kCbcTestCases[] = {
|
||||||
{kNoPadding,
|
{kNoPadding,
|
||||||
"6bc1bee22e409f96e93d7e117393172a6bc1bee22e409f96e93d7e117393172a",
|
"6bc1bee22e409f96e93d7e117393172a6bc1bee22e409f96e93d7e117393172a",
|
||||||
"77cde91fe6df9cbc5d0c98f96efd590bbddde439526f100c9545c274d4f7fd3f"},
|
"77cde91fe6df9cbc5d0c98f96efd590bbddde439526f100c9545c274d4f7fd3f"},
|
||||||
|
{kNoPadding,
|
||||||
|
"6bc1bee22e409f96e93d7e117393172a6bc1bee22e409f96e93d7e117393172a1234",
|
||||||
|
"77cde91fe6df9cbc5d0c98f96efd590bbddde439526f100c9545c274d4f7fd3f1234"},
|
||||||
// Pkcs5 padding with zero bytes.
|
// Pkcs5 padding with zero bytes.
|
||||||
{kPkcs5Padding, "", "f6a3569dea3cda208eb3d5792942612b"},
|
{kPkcs5Padding, "", "f6a3569dea3cda208eb3d5792942612b"},
|
||||||
// Cts Padding with zero bytes.
|
// Cts Padding with zero bytes.
|
||||||
|
|
|
@ -84,6 +84,7 @@ bool AesCbcDecryptor::CryptInternal(const uint8_t* ciphertext,
|
||||||
|
|
||||||
std::vector<uint8_t> local_iv(iv());
|
std::vector<uint8_t> local_iv(iv());
|
||||||
const size_t residual_block_size = ciphertext_size % AES_BLOCK_SIZE;
|
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) {
|
if (residual_block_size == 0) {
|
||||||
AES_cbc_encrypt(ciphertext, plaintext, ciphertext_size, aes_key(),
|
AES_cbc_encrypt(ciphertext, plaintext, ciphertext_size, aes_key(),
|
||||||
local_iv.data(), AES_DECRYPT);
|
local_iv.data(), AES_DECRYPT);
|
||||||
|
@ -101,6 +102,15 @@ bool AesCbcDecryptor::CryptInternal(const uint8_t* ciphertext,
|
||||||
}
|
}
|
||||||
*plaintext_size -= num_padding_bytes;
|
*plaintext_size -= num_padding_bytes;
|
||||||
return true;
|
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) {
|
} else if (padding_scheme_ != kCtsPadding) {
|
||||||
LOG(ERROR) << "Expecting cipher text size to be multiple of "
|
LOG(ERROR) << "Expecting cipher text size to be multiple of "
|
||||||
<< AES_BLOCK_SIZE << ", got " << ciphertext_size;
|
<< 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.
|
// 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) {
|
if (cbc_size > AES_BLOCK_SIZE) {
|
||||||
AES_cbc_encrypt(ciphertext, plaintext, cbc_size - AES_BLOCK_SIZE, aes_key(),
|
AES_cbc_encrypt(ciphertext, plaintext, cbc_size - AES_BLOCK_SIZE, aes_key(),
|
||||||
local_iv.data(), AES_DECRYPT);
|
local_iv.data(), AES_DECRYPT);
|
||||||
|
|
|
@ -171,12 +171,6 @@ bool AesCbcEncryptor::CryptInternal(const uint8_t* plaintext,
|
||||||
DCHECK(aes_key());
|
DCHECK(aes_key());
|
||||||
|
|
||||||
const size_t residual_block_size = plaintext_size % AES_BLOCK_SIZE;
|
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 num_padding_bytes = NumPaddingBytes(plaintext_size);
|
||||||
const size_t required_ciphertext_size = plaintext_size + num_padding_bytes;
|
const size_t required_ciphertext_size = plaintext_size + num_padding_bytes;
|
||||||
if (*ciphertext_size < required_ciphertext_size) {
|
if (*ciphertext_size < required_ciphertext_size) {
|
||||||
|
@ -205,6 +199,12 @@ bool AesCbcEncryptor::CryptInternal(const uint8_t* plaintext,
|
||||||
}
|
}
|
||||||
DCHECK(!chain_across_calls_);
|
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,
|
std::vector<uint8_t> residual_block(plaintext + cbc_size,
|
||||||
plaintext + plaintext_size);
|
plaintext + plaintext_size);
|
||||||
DCHECK_EQ(residual_block.size(), residual_block_size);
|
DCHECK_EQ(residual_block.size(), residual_block_size);
|
||||||
|
|
|
@ -71,8 +71,12 @@ class AesCtrEncryptor : public AesEncryptor {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CbcPaddingScheme {
|
enum CbcPaddingScheme {
|
||||||
|
// Residual block is left unencrypted.
|
||||||
kNoPadding,
|
kNoPadding,
|
||||||
|
// Residual block is padded with pkcs5 and encrypted.
|
||||||
kPkcs5Padding,
|
kPkcs5Padding,
|
||||||
|
// Residual block and the next-to-last block are encrypted using ciphertext
|
||||||
|
// stealing method.
|
||||||
kCtsPadding,
|
kCtsPadding,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -330,12 +330,7 @@ Status EncryptingFragmenter::EncryptSample(scoped_refptr<MediaSample> sample) {
|
||||||
traf()->auxiliary_size.sample_info_sizes.push_back(
|
traf()->auxiliary_size.sample_info_sizes.push_back(
|
||||||
sample_encryption_entry.ComputeSize());
|
sample_encryption_entry.ComputeSize());
|
||||||
} else {
|
} else {
|
||||||
uint64_t encryption_data_size = sample->data_size();
|
EncryptBytes(data, 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
traf()->sample_encryption.sample_encryption_entries.push_back(
|
traf()->sample_encryption.sample_encryption_entries.push_back(
|
||||||
|
|
Loading…
Reference in New Issue