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, 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const SessionClosedCB& session_closed_cb); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~AesDecryptor(); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // MediaKeys implementation. 35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual void CreateSession(const std::string& init_data_type, 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8* init_data, 37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int init_data_length, 38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SessionType session_type, 39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<NewSessionCdmPromise> promise) OVERRIDE; 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual void LoadSession(const std::string& web_session_id, 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<NewSessionCdmPromise> promise) OVERRIDE; 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual void UpdateSession(const std::string& web_session_id, 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const uint8* response, 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int response_length, 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<SimpleCdmPromise> promise) OVERRIDE; 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual void ReleaseSession(const std::string& web_session_id, 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<SimpleCdmPromise> promise) OVERRIDE; 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual Decryptor* GetDecryptor() OVERRIDE; 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Decryptor implementation. 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void RegisterNewKeyCB(StreamType stream_type, 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const NewKeyCB& key_added_cb) OVERRIDE; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Decrypt(StreamType stream_type, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<DecoderBuffer>& encrypted, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DecryptCB& decrypt_cb) OVERRIDE; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void CancelDecrypt(StreamType stream_type) OVERRIDE; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void InitializeAudioDecoder(const AudioDecoderConfig& config, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DecoderInitCB& init_cb) OVERRIDE; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void InitializeVideoDecoder(const VideoDecoderConfig& config, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DecoderInitCB& init_cb) OVERRIDE; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DecryptAndDecodeAudio( 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<DecoderBuffer>& encrypted, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AudioDecodeCB& audio_decode_cb) OVERRIDE; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DecryptAndDecodeVideo( 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<DecoderBuffer>& encrypted, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const VideoDecodeCB& video_decode_cb) OVERRIDE; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ResetDecoder(StreamType stream_type) OVERRIDE; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DeinitializeDecoder(StreamType stream_type) OVERRIDE; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(fgalligan): Remove this and change KeyMap to use crypto::SymmetricKey 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as there are no decryptors that are performing an integrity check. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper class that manages the decryption key. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class DecryptionKey { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit DecryptionKey(const std::string& secret); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~DecryptionKey(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates the encryption key. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Init(); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crypto::SymmetricKey* decryption_key() { return decryption_key_.get(); } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The base secret that is used to create the decryption key. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string secret_; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The key used to decrypt the data. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<crypto::SymmetricKey> decryption_key_; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DecryptionKey); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Keep track of the keys for a key ID. If multiple sessions specify keys 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // for the same key ID, then the last key inserted is used. The structure is 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // optimized so that Decrypt() has fast access, at the cost of slow deletion 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // of keys when a session is released. 98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) class SessionIdDecryptionKeyMap; 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Key ID <-> SessionIdDecryptionKeyMap map. 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) typedef base::ScopedPtrHashMap<std::string, SessionIdDecryptionKeyMap> 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) KeyIdToSessionKeysMap; 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Creates a DecryptionKey using |key_string| and associates it with |key_id|. 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Returns true if successful. 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool AddDecryptionKey(const std::string& web_session_id, 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& key_id, 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& key_string); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets a DecryptionKey associated with |key_id|. The AesDecryptor still owns 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the key. Returns NULL if no key is associated with |key_id|. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DecryptionKey* GetKey(const std::string& key_id) const; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Deletes all keys associated with |web_session_id|. 115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void DeleteKeysForSession(const std::string& web_session_id); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Callbacks for firing session events. 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SessionMessageCB session_message_cb_; 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SessionClosedCB session_closed_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) 127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Keeps track of current valid sessions. 128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::set<std::string> valid_sessions_; 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Make web session ID unique per renderer by making it static. Web session 131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // IDs seen by the app will be "1", "2", etc. 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static uint32 next_web_session_id_; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NewKeyCB new_audio_key_cb_; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NewKeyCB new_video_key_cb_; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Protect |new_audio_key_cb_| and |new_video_key_cb_| as they are set on the 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // main thread but called on the media thread. 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mutable base::Lock new_key_cb_lock_; 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AesDecryptor); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // MEDIA_CRYPTO_AES_DECRYPTOR_H_ 147