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/common/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/net/cast_transport_defines.h" 11 12 namespace { 13 14 // Crypto. 15 const size_t kAesBlockSize = 16; 16 const size_t kAesKeySize = 16; 17 18 std::string GetAesNonce(uint32 frame_id, const std::string& iv_mask) { 19 std::string aes_nonce(kAesBlockSize, 0); 20 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; 27 28 for (size_t i = 0; i < kAesBlockSize; ++i) { 29 aes_nonce[i] ^= iv_mask[i]; 30 } 31 return aes_nonce; 32 } 33 34 } // namespace 35 36 namespace media { 37 namespace cast { 38 39 TransportEncryptionHandler::TransportEncryptionHandler() 40 : key_(), encryptor_(), iv_mask_(), is_activated_(false) {} 41 42 TransportEncryptionHandler::~TransportEncryptionHandler() {} 43 44 bool TransportEncryptionHandler::Initialize(std::string aes_key, 45 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; 49 key_.reset( 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()); 53 is_activated_ = true; 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"; 59 return false; 60 } 61 return true; 62 } 63 64 bool TransportEncryptionHandler::Encrypt(uint32 frame_id, 65 const base::StringPiece& data, 66 std::string* encrypted_data) { 67 if (!is_activated_) 68 return false; 69 if (!encryptor_->SetCounter(GetAesNonce(frame_id, iv_mask_))) { 70 NOTREACHED() << "Failed to set counter"; 71 return false; 72 } 73 if (!encryptor_->Encrypt(data, encrypted_data)) { 74 NOTREACHED() << "Encrypt error"; 75 return false; 76 } 77 return true; 78 } 79 80 bool TransportEncryptionHandler::Decrypt(uint32 frame_id, 81 const base::StringPiece& ciphertext, 82 std::string* plaintext) { 83 if (!is_activated_) { 84 return false; 85 } 86 if (!encryptor_->SetCounter(GetAesNonce(frame_id, iv_mask_))) { 87 NOTREACHED() << "Failed to set counter"; 88 return false; 89 } 90 if (!encryptor_->Decrypt(ciphertext, plaintext)) { 91 VLOG(1) << "Decryption error"; 92 return false; 93 } 94 return true; 95 } 96 97 } // namespace cast 98 } // namespace media 99