1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/cast/common/transport_encryption_handler.h"
7 #include "base/logging.h"
8 #include "crypto/encryptor.h"
9 #include "crypto/symmetric_key.h"
10 #include "media/cast/net/cast_transport_defines.h"
15 const size_t kAesBlockSize
= 16;
16 const size_t kAesKeySize
= 16;
18 std::string
GetAesNonce(uint32 frame_id
, const std::string
& iv_mask
) {
19 std::string
aes_nonce(kAesBlockSize
, 0);
21 // Serializing frame_id in big-endian order (aes_nonce[8] is the most
22 // significant byte of frame_id).
23 aes_nonce
[11] = frame_id
& 0xff;
24 aes_nonce
[10] = (frame_id
>> 8) & 0xff;
25 aes_nonce
[9] = (frame_id
>> 16) & 0xff;
26 aes_nonce
[8] = (frame_id
>> 24) & 0xff;
28 for (size_t i
= 0; i
< kAesBlockSize
; ++i
) {
29 aes_nonce
[i
] ^= iv_mask
[i
];
39 TransportEncryptionHandler::TransportEncryptionHandler()
40 : key_(), encryptor_(), iv_mask_(), is_activated_(false) {}
42 TransportEncryptionHandler::~TransportEncryptionHandler() {}
44 bool TransportEncryptionHandler::Initialize(const std::string
& aes_key
,
45 const std::string
& aes_iv_mask
) {
46 is_activated_
= false;
47 if (aes_iv_mask
.size() == kAesKeySize
&& aes_key
.size() == kAesKeySize
) {
48 iv_mask_
= aes_iv_mask
;
50 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES
, aes_key
));
51 encryptor_
.reset(new crypto::Encryptor());
52 encryptor_
->Init(key_
.get(), crypto::Encryptor::CTR
, std::string());
54 } else if (aes_iv_mask
.size() != 0 || aes_key
.size() != 0) {
55 DCHECK_EQ(aes_iv_mask
.size(), 0u)
56 << "Invalid Crypto configuration: aes_iv_mask.size";
57 DCHECK_EQ(aes_key
.size(), 0u)
58 << "Invalid Crypto configuration: aes_key.size";
64 bool TransportEncryptionHandler::Encrypt(uint32 frame_id
,
65 const base::StringPiece
& data
,
66 std::string
* encrypted_data
) {
69 if (!encryptor_
->SetCounter(GetAesNonce(frame_id
, iv_mask_
))) {
70 NOTREACHED() << "Failed to set counter";
73 if (!encryptor_
->Encrypt(data
, encrypted_data
)) {
74 NOTREACHED() << "Encrypt error";
80 bool TransportEncryptionHandler::Decrypt(uint32 frame_id
,
81 const base::StringPiece
& ciphertext
,
82 std::string
* plaintext
) {
86 if (!encryptor_
->SetCounter(GetAesNonce(frame_id
, iv_mask_
))) {
87 NOTREACHED() << "Failed to set counter";
90 if (!encryptor_
->Decrypt(ciphertext
, plaintext
)) {
91 VLOG(1) << "Decryption error";