Shaka Packager SDK
aes_pattern_cryptor.cc
1 // Copyright 2016 Google LLC. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include <packager/media/base/aes_pattern_cryptor.h>
8 
9 #include <algorithm>
10 
11 #include <absl/log/check.h>
12 #include <absl/log/log.h>
13 
14 #include <packager/macros/crypto.h>
15 
16 namespace shaka {
17 namespace media {
18 
19 AesPatternCryptor::AesPatternCryptor(uint8_t crypt_byte_block,
20  uint8_t skip_byte_block,
21  PatternEncryptionMode encryption_mode,
22  ConstantIvFlag constant_iv_flag,
23  std::unique_ptr<AesCryptor> cryptor)
24  : AesCryptor(constant_iv_flag),
25  crypt_byte_block_(crypt_byte_block),
26  skip_byte_block_(skip_byte_block),
27  encryption_mode_(encryption_mode),
28  cryptor_(std::move(cryptor)) {
29  // Treat pattern 0:0 as 1:0.
30  if (crypt_byte_block_ == 0 && skip_byte_block_ == 0)
31  crypt_byte_block_ = 1;
32  DCHECK(cryptor_);
33  DCHECK(!cryptor_->use_constant_iv());
34 }
35 
36 AesPatternCryptor::~AesPatternCryptor() {}
37 
38 bool AesPatternCryptor::InitializeWithIv(const std::vector<uint8_t>& key,
39  const std::vector<uint8_t>& iv) {
40  return SetIv(iv) && cryptor_->InitializeWithIv(key, iv);
41 }
42 
43 bool AesPatternCryptor::CryptInternal(const uint8_t* text,
44  size_t text_size,
45  uint8_t* crypt_text,
46  size_t* crypt_text_size) {
47  // |crypt_text_size| is always the same as |text_size| for pattern encryption.
48  if (*crypt_text_size < text_size) {
49  LOG(ERROR) << "Expecting output size of at least " << text_size
50  << " bytes.";
51  return false;
52  }
53  *crypt_text_size = text_size;
54 
55  while (text_size > 0) {
56  const size_t crypt_byte_size = crypt_byte_block_ * AES_BLOCK_SIZE;
57 
58  if (text_size <= crypt_byte_size) {
59  const bool need_encrypt =
60  encryption_mode_ != kSkipIfCryptByteBlockRemaining &&
61  text_size >= AES_BLOCK_SIZE;
62  if (need_encrypt) {
63  // The partial pattern SHALL be followed with the partial 16-byte block
64  // remains unencrypted.
65  const size_t aligned_crypt_byte_size =
66  text_size / AES_BLOCK_SIZE * AES_BLOCK_SIZE;
67  if (!cryptor_->Crypt(text, aligned_crypt_byte_size, crypt_text))
68  return false;
69  text += aligned_crypt_byte_size;
70  text_size -= aligned_crypt_byte_size;
71  crypt_text += aligned_crypt_byte_size;
72  }
73 
74  // The remaining bytes are not encrypted.
75  memcpy(crypt_text, text, text_size);
76  return true;
77  }
78 
79  if (!cryptor_->Crypt(text, crypt_byte_size, crypt_text))
80  return false;
81  text += crypt_byte_size;
82  text_size -= crypt_byte_size;
83  crypt_text += crypt_byte_size;
84 
85  const size_t skip_byte_size = std::min(
86  static_cast<size_t>(skip_byte_block_ * AES_BLOCK_SIZE), text_size);
87  memcpy(crypt_text, text, skip_byte_size);
88  text += skip_byte_size;
89  text_size -= skip_byte_size;
90  crypt_text += skip_byte_size;
91  }
92  return true;
93 }
94 
95 void AesPatternCryptor::SetIvInternal() {
96  CHECK(cryptor_->SetIv(iv()));
97 }
98 
99 } // namespace media
100 } // namespace shaka
const std::vector< uint8_t > & iv() const
Definition: aes_cryptor.h:85
bool SetIv(const std::vector< uint8_t > &iv)
Definition: aes_cryptor.cc:70
AesPatternCryptor(uint8_t crypt_byte_block, uint8_t skip_byte_block, PatternEncryptionMode encryption_mode, ConstantIvFlag constant_iv_flag, std::unique_ptr< AesCryptor > cryptor)
bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
All the methods that are virtual are virtual for mocking.
Definition: crypto_flags.cc:66