7 #include "packager/media/base/aes_decryptor.h"
9 #include <openssl/aes.h>
10 #include <openssl/err.h>
11 #include <openssl/rand.h>
13 #include "packager/base/logging.h"
18 bool IsKeySizeValidForAes(
size_t key_size) {
19 return key_size == 16 || key_size == 24 || key_size == 32;
24 namespace edash_packager {
27 AesDecryptor::AesDecryptor() {}
28 AesDecryptor::~AesDecryptor() {}
30 AesCtrDecryptor::AesCtrDecryptor() {}
32 AesCtrDecryptor::~AesCtrDecryptor() {}
34 bool AesCtrDecryptor::InitializeWithIv(
const std::vector<uint8_t>& key,
35 const std::vector<uint8_t>& iv) {
36 encryptor_.reset(
new AesCtrEncryptor);
37 return encryptor_->InitializeWithIv(key, iv);
41 bool AesCtrDecryptor::Decrypt(
const uint8_t* ciphertext,
42 size_t ciphertext_size,
45 return encryptor_->EncryptData(ciphertext, ciphertext_size, plaintext);
48 bool AesCtrDecryptor::Decrypt(
const std::vector<uint8_t>& ciphertext,
49 std::vector<uint8_t>* plaintext) {
51 return encryptor_->Encrypt(ciphertext, plaintext);
54 bool AesCtrDecryptor::Decrypt(
const std::string& ciphertext,
55 std::string* plaintext) {
57 return encryptor_->Encrypt(ciphertext, plaintext);
62 return encryptor_->SetIv(iv);
65 AesCbcPkcs5Decryptor::AesCbcPkcs5Decryptor() {}
66 AesCbcPkcs5Decryptor::~AesCbcPkcs5Decryptor() {}
68 bool AesCbcPkcs5Decryptor::InitializeWithIv(
const std::vector<uint8_t>& key,
69 const std::vector<uint8_t>& iv) {
70 if (!IsKeySizeValidForAes(key.size())) {
71 LOG(ERROR) <<
"Invalid AES key size: " << key.size();
74 if (iv.size() != AES_BLOCK_SIZE) {
75 LOG(ERROR) <<
"Invalid IV size: " << iv.size();
79 aes_key_.reset(
new AES_KEY());
80 CHECK_EQ(AES_set_decrypt_key(&key[0], key.size() * 8, aes_key_.get()), 0);
86 bool AesCbcPkcs5Decryptor::Decrypt(
const uint8_t* ciphertext,
87 size_t ciphertext_size,
93 bool AesCbcPkcs5Decryptor::Decrypt(
const std::vector<uint8_t>& ciphertext,
94 std::vector<uint8_t>* plaintext) {
99 bool AesCbcPkcs5Decryptor::Decrypt(
const std::string& ciphertext,
100 std::string* plaintext) {
101 if ((ciphertext.size() % AES_BLOCK_SIZE) != 0) {
102 LOG(ERROR) <<
"Expecting cipher text size to be multiple of "
103 << AES_BLOCK_SIZE <<
", got " << ciphertext.size();
110 plaintext->resize(ciphertext.size());
111 AES_cbc_encrypt(reinterpret_cast<const uint8_t*>(ciphertext.data()),
112 reinterpret_cast<uint8_t*>(string_as_array(plaintext)),
119 const uint8_t num_padding_bytes = (*plaintext)[plaintext->size() - 1];
120 if (num_padding_bytes > AES_BLOCK_SIZE) {
121 LOG(ERROR) <<
"Padding length is too large : "
122 <<
static_cast<int>(num_padding_bytes);
125 plaintext->resize(plaintext->size() - num_padding_bytes);
130 if (iv.size() != AES_BLOCK_SIZE) {
131 LOG(ERROR) <<
"Invalid IV size: " << iv.size();
139 AesCbcCtsDecryptor::AesCbcCtsDecryptor() {}
140 AesCbcCtsDecryptor::~AesCbcCtsDecryptor() {}
142 bool AesCbcCtsDecryptor::InitializeWithIv(
const std::vector<uint8_t>& key,
143 const std::vector<uint8_t>& iv) {
144 if (!IsKeySizeValidForAes(key.size())) {
145 LOG(ERROR) <<
"Invalid AES key size: " << key.size();
148 if (iv.size() != AES_BLOCK_SIZE) {
149 LOG(ERROR) <<
"Invalid IV size: " << iv.size();
153 aes_key_.reset(
new AES_KEY());
154 CHECK_EQ(AES_set_decrypt_key(&key[0], key.size() * 8, aes_key_.get()), 0);
160 bool AesCbcCtsDecryptor::Decrypt(
const uint8_t* ciphertext,
161 size_t ciphertext_size,
162 uint8_t* plaintext) {
166 if (ciphertext_size < AES_BLOCK_SIZE) {
168 memcpy(plaintext, ciphertext, ciphertext_size);
172 std::vector<uint8_t> iv(iv_);
173 size_t residual_block_size = ciphertext_size % AES_BLOCK_SIZE;
175 if (residual_block_size == 0) {
177 AES_cbc_encrypt(ciphertext,
187 size_t cbc_size = ciphertext_size - residual_block_size;
188 if (cbc_size > AES_BLOCK_SIZE) {
189 AES_cbc_encrypt(ciphertext,
191 cbc_size - AES_BLOCK_SIZE,
199 std::vector<uint8_t> last_iv(
200 ciphertext + ciphertext_size - residual_block_size,
201 ciphertext + ciphertext_size);
202 last_iv.resize(AES_BLOCK_SIZE, 0);
207 ciphertext + ciphertext_size - residual_block_size - AES_BLOCK_SIZE,
208 plaintext + ciphertext_size - residual_block_size - AES_BLOCK_SIZE,
209 AES_BLOCK_SIZE, aes_key_.get(), &last_iv[0], AES_DECRYPT);
212 if (plaintext == ciphertext) {
213 uint8_t* ptr1 = plaintext + ciphertext_size - residual_block_size;
214 uint8_t* ptr2 = plaintext + ciphertext_size - residual_block_size - AES_BLOCK_SIZE;
215 for (
size_t i = 0; i < residual_block_size; ++i) {
216 uint8_t temp = *ptr1;
223 uint8_t* residual_plaintext_block =
224 plaintext + ciphertext_size - residual_block_size;
225 memcpy(residual_plaintext_block, residual_plaintext_block - AES_BLOCK_SIZE,
226 residual_block_size);
227 memcpy(residual_plaintext_block - AES_BLOCK_SIZE,
228 ciphertext + ciphertext_size - residual_block_size,
229 residual_block_size);
234 plaintext + ciphertext_size - residual_block_size - AES_BLOCK_SIZE,
235 plaintext + ciphertext_size - residual_block_size - AES_BLOCK_SIZE,
236 AES_BLOCK_SIZE, aes_key_.get(), &iv[0], AES_DECRYPT);
240 bool AesCbcCtsDecryptor::Decrypt(
const std::vector<uint8_t>& ciphertext,
241 std::vector<uint8_t>* plaintext) {
244 plaintext->resize(ciphertext.size(), 0);
245 if (ciphertext.empty())
248 return Decrypt(ciphertext.data(), ciphertext.size(), &(*plaintext)[0]);
251 bool AesCbcCtsDecryptor::Decrypt(
const std::string& ciphertext,
252 std::string* plaintext) {
258 if (iv.size() != AES_BLOCK_SIZE) {
259 LOG(ERROR) <<
"Invalid IV size: " << iv.size();