aes_decryptor.h revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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