aes_decryptor.h revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/containers/scoped_ptr_hash_map.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/decryptor.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/media_export.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "media/base/media_keys.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace crypto {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SymmetricKey;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Decrypts an AES encrypted buffer into an unencrypted buffer. The AES
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// encryption must be CTR with a key size of 128bits.
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class MEDIA_EXPORT AesDecryptor : public MediaKeys, public Decryptor {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AesDecryptor(const SessionCreatedCB& session_created_cb,
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               const SessionMessageCB& session_message_cb,
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               const SessionReadyCB& session_ready_cb,
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               const SessionClosedCB& session_closed_cb,
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               const SessionErrorCB& session_error_cb);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~AesDecryptor();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // MediaKeys implementation.
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual bool CreateSession(uint32 session_id,
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             const std::string& type,
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             const uint8* init_data,
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             int init_data_length) OVERRIDE;
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void UpdateSession(uint32 session_id,
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             const uint8* response,
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             int response_length) OVERRIDE;
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void ReleaseSession(uint32 session_id) OVERRIDE;
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual Decryptor* GetDecryptor() OVERRIDE;
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Decryptor implementation.
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void RegisterNewKeyCB(StreamType stream_type,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const NewKeyCB& key_added_cb) OVERRIDE;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Decrypt(StreamType stream_type,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const scoped_refptr<DecoderBuffer>& encrypted,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const DecryptCB& decrypt_cb) OVERRIDE;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CancelDecrypt(StreamType stream_type) OVERRIDE;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void InitializeAudioDecoder(const AudioDecoderConfig& config,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const DecoderInitCB& init_cb) OVERRIDE;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void InitializeVideoDecoder(const VideoDecoderConfig& config,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const DecoderInitCB& init_cb) OVERRIDE;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DecryptAndDecodeAudio(
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const scoped_refptr<DecoderBuffer>& encrypted,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const AudioDecodeCB& audio_decode_cb) OVERRIDE;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DecryptAndDecodeVideo(
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const scoped_refptr<DecoderBuffer>& encrypted,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const VideoDecodeCB& video_decode_cb) OVERRIDE;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ResetDecoder(StreamType stream_type) OVERRIDE;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DeinitializeDecoder(StreamType stream_type) OVERRIDE;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(fgalligan): Remove this and change KeyMap to use crypto::SymmetricKey
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as there are no decryptors that are performing an integrity check.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper class that manages the decryption key.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class DecryptionKey {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    explicit DecryptionKey(const std::string& secret);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~DecryptionKey();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Creates the encryption key.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool Init();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    crypto::SymmetricKey* decryption_key() { return decryption_key_.get(); }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The base secret that is used to create the decryption key.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string secret_;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The key used to decrypt the data.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<crypto::SymmetricKey> decryption_key_;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(DecryptionKey);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Keep track of the keys for a key ID. If multiple sessions specify keys
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // for the same key ID, then the last key inserted is used. The structure is
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // optimized so that Decrypt() has fast access, at the cost of slow deletion
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // of keys when a session is released.
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  class SessionIdDecryptionKeyMap;
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Key ID <-> SessionIdDecryptionKeyMap map.
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  typedef base::ScopedPtrHashMap<std::string, SessionIdDecryptionKeyMap>
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      KeyIdToSessionKeysMap;
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Creates a DecryptionKey using |key_string| and associates it with |key_id|.
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Returns true if successful.
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool AddDecryptionKey(const uint32 session_id,
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        const std::string& key_id,
10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        const std::string& key_string);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets a DecryptionKey associated with |key_id|. The AesDecryptor still owns
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the key. Returns NULL if no key is associated with |key_id|.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DecryptionKey* GetKey(const std::string& key_id) const;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Deletes all keys associated with |session_id|.
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void DeleteKeysForSession(const uint32 session_id);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Callbacks for firing session events.
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionCreatedCB session_created_cb_;
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionMessageCB session_message_cb_;
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionReadyCB session_ready_cb_;
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionClosedCB session_closed_cb_;
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SessionErrorCB session_error_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)
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Make web session ID unique per renderer by making it static. Web session
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // IDs seen by the app will be "1", "2", etc.
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static uint32 next_web_session_id_;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NewKeyCB new_audio_key_cb_;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NewKeyCB new_video_key_cb_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AesDecryptor);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // MEDIA_CRYPTO_AES_DECRYPTOR_H_
140