Home | History | Annotate | Download | only in cdm
      1 // Copyright 2013 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 #ifndef MEDIA_CRYPTO_AES_DECRYPTOR_H_
      6 #define MEDIA_CRYPTO_AES_DECRYPTOR_H_
      7 
      8 #include <set>
      9 #include <string>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/containers/scoped_ptr_hash_map.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/synchronization/lock.h"
     16 #include "media/base/decryptor.h"
     17 #include "media/base/media_export.h"
     18 #include "media/base/media_keys.h"
     19 
     20 namespace crypto {
     21 class SymmetricKey;
     22 }
     23 
     24 namespace media {
     25 
     26 // Decrypts an AES encrypted buffer into an unencrypted buffer. The AES
     27 // encryption must be CTR with a key size of 128bits.
     28 class MEDIA_EXPORT AesDecryptor : public MediaKeys, public Decryptor {
     29  public:
     30   AesDecryptor(const SessionMessageCB& session_message_cb,
     31                const SessionClosedCB& session_closed_cb);
     32   virtual ~AesDecryptor();
     33 
     34   // MediaKeys implementation.
     35   virtual void CreateSession(const std::string& init_data_type,
     36                              const uint8* init_data,
     37                              int init_data_length,
     38                              SessionType session_type,
     39                              scoped_ptr<NewSessionCdmPromise> promise) OVERRIDE;
     40   virtual void LoadSession(const std::string& web_session_id,
     41                            scoped_ptr<NewSessionCdmPromise> promise) OVERRIDE;
     42   virtual void UpdateSession(const std::string& web_session_id,
     43                              const uint8* response,
     44                              int response_length,
     45                              scoped_ptr<SimpleCdmPromise> promise) OVERRIDE;
     46   virtual void ReleaseSession(const std::string& web_session_id,
     47                               scoped_ptr<SimpleCdmPromise> promise) OVERRIDE;
     48   virtual Decryptor* GetDecryptor() OVERRIDE;
     49 
     50   // Decryptor implementation.
     51   virtual void RegisterNewKeyCB(StreamType stream_type,
     52                                 const NewKeyCB& key_added_cb) OVERRIDE;
     53   virtual void Decrypt(StreamType stream_type,
     54                        const scoped_refptr<DecoderBuffer>& encrypted,
     55                        const DecryptCB& decrypt_cb) OVERRIDE;
     56   virtual void CancelDecrypt(StreamType stream_type) OVERRIDE;
     57   virtual void InitializeAudioDecoder(const AudioDecoderConfig& config,
     58                                       const DecoderInitCB& init_cb) OVERRIDE;
     59   virtual void InitializeVideoDecoder(const VideoDecoderConfig& config,
     60                                       const DecoderInitCB& init_cb) OVERRIDE;
     61   virtual void DecryptAndDecodeAudio(
     62       const scoped_refptr<DecoderBuffer>& encrypted,
     63       const AudioDecodeCB& audio_decode_cb) OVERRIDE;
     64   virtual void DecryptAndDecodeVideo(
     65       const scoped_refptr<DecoderBuffer>& encrypted,
     66       const VideoDecodeCB& video_decode_cb) OVERRIDE;
     67   virtual void ResetDecoder(StreamType stream_type) OVERRIDE;
     68   virtual void DeinitializeDecoder(StreamType stream_type) OVERRIDE;
     69 
     70  private:
     71   // TODO(fgalligan): Remove this and change KeyMap to use crypto::SymmetricKey
     72   // as there are no decryptors that are performing an integrity check.
     73   // Helper class that manages the decryption key.
     74   class DecryptionKey {
     75    public:
     76     explicit DecryptionKey(const std::string& secret);
     77     ~DecryptionKey();
     78 
     79     // Creates the encryption key.
     80     bool Init();
     81 
     82     crypto::SymmetricKey* decryption_key() { return decryption_key_.get(); }
     83 
     84    private:
     85     // The base secret that is used to create the decryption key.
     86     const std::string secret_;
     87 
     88     // The key used to decrypt the data.
     89     scoped_ptr<crypto::SymmetricKey> decryption_key_;
     90 
     91     DISALLOW_COPY_AND_ASSIGN(DecryptionKey);
     92   };
     93 
     94   // Keep track of the keys for a key ID. If multiple sessions specify keys
     95   // for the same key ID, then the last key inserted is used. The structure is
     96   // optimized so that Decrypt() has fast access, at the cost of slow deletion
     97   // of keys when a session is released.
     98   class SessionIdDecryptionKeyMap;
     99 
    100   // Key ID <-> SessionIdDecryptionKeyMap map.
    101   typedef base::ScopedPtrHashMap<std::string, SessionIdDecryptionKeyMap>
    102       KeyIdToSessionKeysMap;
    103 
    104   // Creates a DecryptionKey using |key_string| and associates it with |key_id|.
    105   // Returns true if successful.
    106   bool AddDecryptionKey(const std::string& web_session_id,
    107                         const std::string& key_id,
    108                         const std::string& key_string);
    109 
    110   // Gets a DecryptionKey associated with |key_id|. The AesDecryptor still owns
    111   // the key. Returns NULL if no key is associated with |key_id|.
    112   DecryptionKey* GetKey(const std::string& key_id) const;
    113 
    114   // Deletes all keys associated with |web_session_id|.
    115   void DeleteKeysForSession(const std::string& web_session_id);
    116 
    117   // Callbacks for firing session events.
    118   SessionMessageCB session_message_cb_;
    119   SessionClosedCB session_closed_cb_;
    120 
    121   // Since only Decrypt() is called off the renderer thread, we only need to
    122   // protect |key_map_|, the only member variable that is shared between
    123   // Decrypt() and other methods.
    124   KeyIdToSessionKeysMap key_map_;  // Protected by |key_map_lock_|.
    125   mutable base::Lock key_map_lock_;  // Protects the |key_map_|.
    126 
    127   // Keeps track of current valid sessions.
    128   std::set<std::string> valid_sessions_;
    129 
    130   // Make web session ID unique per renderer by making it static. Web session
    131   // IDs seen by the app will be "1", "2", etc.
    132   static uint32 next_web_session_id_;
    133 
    134   NewKeyCB new_audio_key_cb_;
    135   NewKeyCB new_video_key_cb_;
    136 
    137   // Protect |new_audio_key_cb_| and |new_video_key_cb_| as they are set on the
    138   // main thread but called on the media thread.
    139   mutable base::Lock new_key_cb_lock_;
    140 
    141   DISALLOW_COPY_AND_ASSIGN(AesDecryptor);
    142 };
    143 
    144 }  // namespace media
    145 
    146 #endif  // MEDIA_CRYPTO_AES_DECRYPTOR_H_
    147