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