15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/cast/transport/utility/transport_encryption_handler.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "crypto/encryptor.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "crypto/symmetric_key.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/cast/transport/cast_transport_defines.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace media {
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace cast {
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace transport {
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TransportEncryptionHandler::TransportEncryptionHandler()
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : key_(), encryptor_(), iv_mask_(), initialized_(false) {}
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TransportEncryptionHandler::~TransportEncryptionHandler() {}
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool TransportEncryptionHandler::Initialize(std::string aes_key,
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                            std::string aes_iv_mask) {
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  initialized_ = false;
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (aes_iv_mask.size() == kAesKeySize && aes_key.size() == kAesKeySize) {
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    iv_mask_ = aes_iv_mask;
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    key_.reset(
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, aes_key));
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    encryptor_.reset(new crypto::Encryptor());
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    encryptor_->Init(key_.get(), crypto::Encryptor::CTR, std::string());
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    initialized_ = true;
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else if (aes_iv_mask.size() != 0 || aes_key.size() != 0) {
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK_EQ(aes_iv_mask.size(), 0u)
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        << "Invalid Crypto configuration: aes_iv_mask.size";
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK_EQ(aes_key.size(), 0u)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        << "Invalid Crypto configuration: aes_key.size";
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool TransportEncryptionHandler::Encrypt(uint32 frame_id,
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                         const base::StringPiece& data,
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                         std::string* encrypted_data) {
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!initialized_)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!encryptor_->SetCounter(GetAesNonce(frame_id, iv_mask_))) {
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED() << "Failed to set counter";
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!encryptor_->Encrypt(data, encrypted_data)) {
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED() << "Encrypt error";
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool TransportEncryptionHandler::Decrypt(uint32 frame_id,
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                         const base::StringPiece& ciphertext,
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                         std::string* plaintext) {
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!initialized_) {
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!encryptor_->SetCounter(transport::GetAesNonce(frame_id, iv_mask_))) {
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED() << "Failed to set counter";
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!encryptor_->Decrypt(ciphertext, plaintext)) {
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    VLOG(1) << "Decryption error";
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace transport
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace cast
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace media
77