aes_decryptor.h revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MEDIA_CRYPTO_AES_DECRYPTOR_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MEDIA_CRYPTO_AES_DECRYPTOR_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/containers/scoped_ptr_hash_map.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/decryptor.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/media_export.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "media/base/media_keys.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace crypto { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SymmetricKey; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Decrypts an AES encrypted buffer into an unencrypted buffer. The AES 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// encryption must be CTR with a key size of 128bits. 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class MEDIA_EXPORT AesDecryptor : public MediaKeys, public Decryptor { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AesDecryptor(const SessionCreatedCB& session_created_cb, 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const SessionMessageCB& session_message_cb, 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const SessionReadyCB& session_ready_cb, 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const SessionClosedCB& session_closed_cb, 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const SessionErrorCB& session_error_cb); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~AesDecryptor(); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // MediaKeys implementation. 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual bool CreateSession(uint32 session_id, 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& type, 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8* init_data, 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int init_data_length) OVERRIDE; 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void UpdateSession(uint32 session_id, 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8* response, 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int response_length) OVERRIDE; 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void ReleaseSession(uint32 session_id) OVERRIDE; 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual Decryptor* GetDecryptor() OVERRIDE; 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Decryptor implementation. 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void RegisterNewKeyCB(StreamType stream_type, 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const NewKeyCB& key_added_cb) OVERRIDE; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Decrypt(StreamType stream_type, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<DecoderBuffer>& encrypted, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DecryptCB& decrypt_cb) OVERRIDE; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void CancelDecrypt(StreamType stream_type) OVERRIDE; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void InitializeAudioDecoder(const AudioDecoderConfig& config, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DecoderInitCB& init_cb) OVERRIDE; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void InitializeVideoDecoder(const VideoDecoderConfig& config, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DecoderInitCB& init_cb) OVERRIDE; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DecryptAndDecodeAudio( 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<DecoderBuffer>& encrypted, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AudioDecodeCB& audio_decode_cb) OVERRIDE; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DecryptAndDecodeVideo( 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<DecoderBuffer>& encrypted, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const VideoDecodeCB& video_decode_cb) OVERRIDE; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ResetDecoder(StreamType stream_type) OVERRIDE; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DeinitializeDecoder(StreamType stream_type) OVERRIDE; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(fgalligan): Remove this and change KeyMap to use crypto::SymmetricKey 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as there are no decryptors that are performing an integrity check. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper class that manages the decryption key. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class DecryptionKey { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit DecryptionKey(const std::string& secret); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~DecryptionKey(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates the encryption key. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Init(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crypto::SymmetricKey* decryption_key() { return decryption_key_.get(); } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The base secret that is used to create the decryption key. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string secret_; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The key used to decrypt the data. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<crypto::SymmetricKey> decryption_key_; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DecryptionKey); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Keep track of the keys for a key ID. If multiple sessions specify keys 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // for the same key ID, then the last key inserted is used. The structure is 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // optimized so that Decrypt() has fast access, at the cost of slow deletion 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // of keys when a session is released. 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) class SessionIdDecryptionKeyMap; 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Key ID <-> SessionIdDecryptionKeyMap map. 98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef base::ScopedPtrHashMap<std::string, SessionIdDecryptionKeyMap> 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) KeyIdToSessionKeysMap; 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Creates a DecryptionKey using |key_string| and associates it with |key_id|. 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Returns true if successful. 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool AddDecryptionKey(const uint32 session_id, 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& key_id, 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& key_string); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets a DecryptionKey associated with |key_id|. The AesDecryptor still owns 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the key. Returns NULL if no key is associated with |key_id|. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecryptionKey* GetKey(const std::string& key_id) const; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Deletes all keys associated with |session_id|. 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void DeleteKeysForSession(const uint32 session_id); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Callbacks for firing session events. 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SessionCreatedCB session_created_cb_; 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SessionMessageCB session_message_cb_; 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SessionReadyCB session_ready_cb_; 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SessionClosedCB session_closed_cb_; 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SessionErrorCB session_error_cb_; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since only Decrypt() is called off the renderer thread, we only need to 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // protect |key_map_|, the only member variable that is shared between 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Decrypt() and other methods. 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) KeyIdToSessionKeysMap key_map_; // Protected by |key_map_lock_|. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable base::Lock key_map_lock_; // Protects the |key_map_|. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Make web session ID unique per renderer by making it static. Web session 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // IDs seen by the app will be "1", "2", etc. 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static uint32 next_web_session_id_; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NewKeyCB new_audio_key_cb_; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NewKeyCB new_video_key_cb_; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AesDecryptor); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // MEDIA_CRYPTO_AES_DECRYPTOR_H_ 140