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.
4
5#include "media/cast/transport/utility/transport_encryption_handler.h"
6
7#include "base/logging.h"
8#include "crypto/encryptor.h"
9#include "crypto/symmetric_key.h"
10#include "media/cast/transport/cast_transport_defines.h"
11
12namespace media {
13namespace cast {
14namespace transport {
15
16TransportEncryptionHandler::TransportEncryptionHandler()
17    : key_(), encryptor_(), iv_mask_(), initialized_(false) {}
18
19TransportEncryptionHandler::~TransportEncryptionHandler() {}
20
21bool TransportEncryptionHandler::Initialize(std::string aes_key,
22                                            std::string aes_iv_mask) {
23  initialized_ = false;
24  if (aes_iv_mask.size() == kAesKeySize && aes_key.size() == kAesKeySize) {
25    iv_mask_ = aes_iv_mask;
26    key_.reset(
27        crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, aes_key));
28    encryptor_.reset(new crypto::Encryptor());
29    encryptor_->Init(key_.get(), crypto::Encryptor::CTR, std::string());
30    initialized_ = true;
31  } else if (aes_iv_mask.size() != 0 || aes_key.size() != 0) {
32    DCHECK_EQ(aes_iv_mask.size(), 0u)
33        << "Invalid Crypto configuration: aes_iv_mask.size";
34    DCHECK_EQ(aes_key.size(), 0u)
35        << "Invalid Crypto configuration: aes_key.size";
36    return false;
37  }
38  return true;
39}
40
41bool TransportEncryptionHandler::Encrypt(uint32 frame_id,
42                                         const base::StringPiece& data,
43                                         std::string* encrypted_data) {
44  if (!initialized_)
45    return false;
46  if (!encryptor_->SetCounter(GetAesNonce(frame_id, iv_mask_))) {
47    NOTREACHED() << "Failed to set counter";
48    return false;
49  }
50  if (!encryptor_->Encrypt(data, encrypted_data)) {
51    NOTREACHED() << "Encrypt error";
52    return false;
53  }
54  return true;
55}
56
57bool TransportEncryptionHandler::Decrypt(uint32 frame_id,
58                                         const base::StringPiece& ciphertext,
59                                         std::string* plaintext) {
60  if (!initialized_) {
61    return false;
62  }
63  if (!encryptor_->SetCounter(transport::GetAesNonce(frame_id, iv_mask_))) {
64    NOTREACHED() << "Failed to set counter";
65    return false;
66  }
67  if (!encryptor_->Decrypt(ciphertext, plaintext)) {
68    VLOG(1) << "Decryption error";
69    return false;
70  }
71  return true;
72}
73
74}  // namespace transport
75}  // namespace cast
76}  // namespace media
77