Shaka Packager SDK
Loading...
Searching...
No Matches
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
16namespace shaka {
17namespace media {
18
19AesPatternCryptor::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
36AesPatternCryptor::~AesPatternCryptor() {}
37
38bool 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
43bool 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
95void AesPatternCryptor::SetIvInternal() {
96 CHECK(cryptor_->SetIv(iv()));
97}
98
99} // namespace media
100} // namespace shaka
bool SetIv(const std::vector< uint8_t > &iv)
const std::vector< uint8_t > & iv() const
Definition aes_cryptor.h:85
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.