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) 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <set> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/containers/scoped_ptr_hash_map.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/decryptor.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/media_export.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "media/base/media_keys.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace crypto { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SymmetricKey; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Decrypts an AES encrypted buffer into an unencrypted buffer. The AES 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// encryption must be CTR with a key size of 128bits. 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class MEDIA_EXPORT AesDecryptor : public MediaKeys, public Decryptor { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AesDecryptor(const SessionMessageCB& session_message_cb, 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const SessionClosedCB& session_closed_cb, 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const SessionKeysChangeCB& session_keys_change_cb); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~AesDecryptor(); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // MediaKeys implementation. 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void SetServerCertificate( 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const uint8* certificate_data, 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int certificate_data_length, 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<SimpleCdmPromise> promise) OVERRIDE; 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual void CreateSession(const std::string& init_data_type, 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8* init_data, 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int init_data_length, 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SessionType session_type, 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<NewSessionCdmPromise> promise) OVERRIDE; 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual void LoadSession(const std::string& web_session_id, 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<NewSessionCdmPromise> promise) OVERRIDE; 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual void UpdateSession(const std::string& web_session_id, 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8* response, 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int response_length, 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<SimpleCdmPromise> promise) OVERRIDE; 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void CloseSession(const std::string& web_session_id, 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<SimpleCdmPromise> promise) OVERRIDE; 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void RemoveSession(const std::string& web_session_id, 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<SimpleCdmPromise> promise) OVERRIDE; 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void GetUsableKeyIds(const std::string& web_session_id, 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<KeyIdsPromise> promise) OVERRIDE; 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual Decryptor* GetDecryptor() OVERRIDE; 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Decryptor implementation. 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void RegisterNewKeyCB(StreamType stream_type, 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const NewKeyCB& key_added_cb) OVERRIDE; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Decrypt(StreamType stream_type, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<DecoderBuffer>& encrypted, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DecryptCB& decrypt_cb) OVERRIDE; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void CancelDecrypt(StreamType stream_type) OVERRIDE; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void InitializeAudioDecoder(const AudioDecoderConfig& config, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DecoderInitCB& init_cb) OVERRIDE; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void InitializeVideoDecoder(const VideoDecoderConfig& config, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DecoderInitCB& init_cb) OVERRIDE; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DecryptAndDecodeAudio( 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<DecoderBuffer>& encrypted, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AudioDecodeCB& audio_decode_cb) OVERRIDE; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DecryptAndDecodeVideo( 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<DecoderBuffer>& encrypted, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const VideoDecodeCB& video_decode_cb) OVERRIDE; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ResetDecoder(StreamType stream_type) OVERRIDE; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DeinitializeDecoder(StreamType stream_type) OVERRIDE; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(fgalligan): Remove this and change KeyMap to use crypto::SymmetricKey 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as there are no decryptors that are performing an integrity check. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper class that manages the decryption key. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class DecryptionKey { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit DecryptionKey(const std::string& secret); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~DecryptionKey(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates the encryption key. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Init(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crypto::SymmetricKey* decryption_key() { return decryption_key_.get(); } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The base secret that is used to create the decryption key. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string secret_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The key used to decrypt the data. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<crypto::SymmetricKey> decryption_key_; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DecryptionKey); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Keep track of the keys for a key ID. If multiple sessions specify keys 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // for the same key ID, then the last key inserted is used. The structure is 105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // optimized so that Decrypt() has fast access, at the cost of slow deletion 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // of keys when a session is released. 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) class SessionIdDecryptionKeyMap; 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Key ID <-> SessionIdDecryptionKeyMap map. 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef base::ScopedPtrHashMap<std::string, SessionIdDecryptionKeyMap> 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) KeyIdToSessionKeysMap; 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Creates a DecryptionKey using |key_string| and associates it with |key_id|. 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Returns true if successful. 115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool AddDecryptionKey(const std::string& web_session_id, 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& key_id, 11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& key_string); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets a DecryptionKey associated with |key_id|. The AesDecryptor still owns 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the key. Returns NULL if no key is associated with |key_id|. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecryptionKey* GetKey(const std::string& key_id) const; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Deletes all keys associated with |web_session_id|. 124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void DeleteKeysForSession(const std::string& web_session_id); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Callbacks for firing session events. 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SessionMessageCB session_message_cb_; 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SessionClosedCB session_closed_cb_; 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SessionKeysChangeCB session_keys_change_cb_; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since only Decrypt() is called off the renderer thread, we only need to 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // protect |key_map_|, the only member variable that is shared between 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Decrypt() and other methods. 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) KeyIdToSessionKeysMap key_map_; // Protected by |key_map_lock_|. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable base::Lock key_map_lock_; // Protects the |key_map_|. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Keeps track of current valid sessions. 138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::set<std::string> valid_sessions_; 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Make web session ID unique per renderer by making it static. Web session 141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // IDs seen by the app will be "1", "2", etc. 142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static uint32 next_web_session_id_; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NewKeyCB new_audio_key_cb_; 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NewKeyCB new_video_key_cb_; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Protect |new_audio_key_cb_| and |new_video_key_cb_| as they are set on the 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // main thread but called on the media thread. 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mutable base::Lock new_key_cb_lock_; 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AesDecryptor); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // MEDIA_CRYPTO_AES_DECRYPTOR_H_ 157