OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <string> | 5 #include <string> |
6 | 6 |
| 7 #include "base/logging.h" |
| 8 #include "base/sys_byteorder.h" |
7 #include "media/base/decoder_buffer.h" | 9 #include "media/base/decoder_buffer.h" |
8 #include "media/base/decrypt_config.h" | 10 #include "media/base/decrypt_config.h" |
9 #include "media/crypto/aes_decryptor.h" | 11 #include "media/crypto/aes_decryptor.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
11 | 13 |
12 namespace media { | 14 namespace media { |
13 | 15 |
14 // |kEncryptedData| is encrypted from |kOriginalData| using |kRightKey|, whose | 16 struct WebmEncryptedData { |
15 // length is |kKeySize|. Modifying any of these independently would fail the | 17 uint8 plain_text[32]; |
16 // test. | 18 int plain_text_size; |
17 static const char kOriginalData[] = "Original data."; | 19 uint8 key_id[32]; |
18 static const int kEncryptedDataSize = 16; | 20 int key_id_size; |
19 static const unsigned char kEncryptedData[] = | 21 uint8 key[32]; |
20 "\x82\x3A\x76\x92\xEC\x7F\xF8\x85\xEC\x23\x52\xFB\x19\xB1\xB9\x09"; | 22 int key_size; |
| 23 uint8 encrypted_data[64]; |
| 24 int encrypted_data_size; |
| 25 }; |
| 26 |
| 27 const WebmEncryptedData kEncryptedFrames[] = { |
| 28 { |
| 29 // plaintext |
| 30 "Original data.", 14, |
| 31 // key_id |
| 32 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, |
| 33 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13}, 20, |
| 34 // key |
| 35 { 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, |
| 36 0x20, 0x21, 0x22, 0x23}, 16, |
| 37 // encrypted_data |
| 38 { 0xfb, 0xe7, 0x1d, 0xbb, 0x4c, 0x23, 0xce, 0xba, 0xcc, 0xf8, 0xda, 0xc0, |
| 39 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0xaa, 0xff, 0xb7, |
| 40 0x74, 0x02, 0x4e, 0x1c, 0x75, 0x3d, 0xee, 0xcb, 0x64, 0xf7}, 34 |
| 41 }, |
| 42 { |
| 43 // plaintext |
| 44 "Changed Original data.", 22, |
| 45 // key_id |
| 46 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, |
| 47 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13}, 20, |
| 48 // key |
| 49 { 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, |
| 50 0x20, 0x21, 0x22, 0x23}, 16, |
| 51 // encrypted_data |
| 52 { 0x43, 0xe4, 0x78, 0x7a, 0x43, 0xe1, 0x49, 0xbb, 0x44, 0x38, 0xdf, 0xfc, |
| 53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x8e, 0x87, 0x21, |
| 54 0xd3, 0xb9, 0x1c, 0x61, 0xf6, 0x5a, 0x60, 0xaa, 0x07, 0x0e, 0x96, 0xd0, |
| 55 0x54, 0x5d, 0x35, 0x9a, 0x4a, 0xd3}, 42 |
| 56 }, |
| 57 { |
| 58 // plaintext |
| 59 "Original data.", 14, |
| 60 // key_id |
| 61 { 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, |
| 62 0x30}, 13, |
| 63 // key |
| 64 { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, |
| 65 0x3d, 0x3e, 0x3f, 0x40}, 16, |
| 66 // encrypted_data |
| 67 { 0xd9, 0x43, 0x30, 0xfd, 0x82, 0x77, 0x62, 0x04, 0x08, 0xc2, 0x48, 0x89, |
| 68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x48, 0x5e, 0x4a, 0x41, |
| 69 0x2a, 0x8b, 0xf4, 0xc6, 0x47, 0x54, 0x90, 0x34, 0xf4, 0x8b}, 34 |
| 70 }, |
| 71 }; |
| 72 |
| 73 static const int kIntegrityCheckSize = 12; |
| 74 static const int kIvSize = 8; |
21 static const int kKeySize = 16; | 75 static const int kKeySize = 16; |
22 static const unsigned char kRightKey[] = "A wonderful key!"; | |
23 static const unsigned char kWrongKey[] = "I'm a wrong key."; | 76 static const unsigned char kWrongKey[] = "I'm a wrong key."; |
24 static const int kKeyIdSize = 9; | 77 static const unsigned char kFrame0InvalidHmac[] = { |
25 static const unsigned char kKeyId1[] = "Key ID 1."; | 78 0xfc, 0xe7, 0x1d, 0xbb, 0x4c, 0x23, 0xce, 0xba, 0xcc, 0xf8, 0xda, 0xc0, 0xff, |
26 static const unsigned char kKeyId2[] = "Key ID 2."; | 79 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0xaa, 0xff, 0xb7, 0x74, 0x02, |
27 | 80 0x4e, 0x1c, 0x75, 0x3d, 0xee, 0xcb, 0x64, 0xf7 |
28 class AesDecryptorTest : public testing::Test { | 81 }; |
| 82 static const unsigned char kFrame0InvalidIv[] = { |
| 83 0xfb, 0xe7, 0x1d, 0xbb, 0x4c, 0x23, 0xce, 0xba, 0xcc, 0xf8, 0xda, 0xc0, 0x0f, |
| 84 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0xaa, 0xff, 0xb7, 0x74, 0x02, |
| 85 0x4e, 0x1c, 0x75, 0x3d, 0xee, 0xcb, 0x64, 0xf7 |
| 86 }; |
| 87 static const unsigned char kFrame0InvalidData[] = { |
| 88 0xfb, 0xe7, 0x1d, 0xbb, 0x4c, 0x23, 0xce, 0xba, 0xcc, 0xf8, 0xda, 0xc0, 0xff, |
| 89 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, 0xaa, 0xff, 0xb7, 0x74, 0x02, |
| 90 0x4e, 0x1c, 0x75, 0x3d, 0xee, 0xcb, 0x64, 0xf8 |
| 91 }; |
| 92 |
| 93 class HmacAesDecryptorTest : public testing::Test { |
29 public: | 94 public: |
30 AesDecryptorTest() { | 95 HmacAesDecryptorTest() {} |
31 encrypted_data_ = DecoderBuffer::CopyFrom( | 96 |
32 kEncryptedData, kEncryptedDataSize); | 97 protected: |
| 98 scoped_refptr<DecoderBuffer> CreateEncryptedBuffer(const uint8* data, |
| 99 int data_size, |
| 100 const uint8* key_id, |
| 101 int key_id_size) { |
| 102 CHECK_GT(data_size, kIntegrityCheckSize + kIvSize); |
| 103 scoped_refptr<DecoderBuffer> encrypted_buffer = DecoderBuffer::CopyFrom( |
| 104 data + kIntegrityCheckSize, data_size - kIntegrityCheckSize); |
| 105 CHECK(encrypted_buffer); |
| 106 |
| 107 // Every encrypted Block has an HMAC and IV prepended to it. Current WebM |
| 108 // encrypted request for comments specification is here |
| 109 // http://wiki.webmproject.org/encryption/webm-encryption-rfc |
| 110 uint64 network_iv; |
| 111 memcpy(&network_iv, |
| 112 data + kIntegrityCheckSize, |
| 113 sizeof(network_iv)); |
| 114 const uint64 iv = base::NetToHost64(network_iv); |
| 115 encrypted_buffer->SetDecryptConfig( |
| 116 scoped_ptr<DecryptConfig>(new DecryptConfig( |
| 117 data, kIntegrityCheckSize, |
| 118 reinterpret_cast<const uint8*>(&iv), sizeof(iv), |
| 119 key_id, key_id_size, |
| 120 sizeof(iv)))); |
| 121 return encrypted_buffer; |
33 } | 122 } |
34 | 123 |
35 protected: | 124 void DecryptAndExpectToSucceed(const uint8* data, int data_size, |
36 void SetKeyIdForEncryptedData(const uint8* key_id, int key_id_size) { | 125 const uint8* plain_text, |
37 encrypted_data_->SetDecryptConfig( | 126 int plain_text_size, |
38 scoped_ptr<DecryptConfig>(new DecryptConfig(key_id, key_id_size))); | 127 const uint8* key_id, int key_id_size) { |
| 128 scoped_refptr<DecoderBuffer> encrypted_data = |
| 129 CreateEncryptedBuffer(data, data_size, key_id, key_id_size); |
| 130 scoped_refptr<DecoderBuffer> decrypted = |
| 131 decryptor_.Decrypt(encrypted_data); |
| 132 ASSERT_TRUE(decrypted); |
| 133 ASSERT_EQ(plain_text_size, decrypted->GetDataSize()); |
| 134 EXPECT_EQ(0, memcmp(plain_text, decrypted->GetData(), plain_text_size)); |
39 } | 135 } |
40 | 136 |
41 void DecryptAndExpectToSucceed() { | 137 void DecryptAndExpectToFail(const uint8* data, int data_size, |
| 138 const uint8* plain_text, int plain_text_size, |
| 139 const uint8* key_id, int key_id_size) { |
| 140 scoped_refptr<DecoderBuffer> encrypted_data = |
| 141 CreateEncryptedBuffer(data, data_size, key_id, key_id_size); |
42 scoped_refptr<DecoderBuffer> decrypted = | 142 scoped_refptr<DecoderBuffer> decrypted = |
43 decryptor_.Decrypt(encrypted_data_); | 143 decryptor_.Decrypt(encrypted_data); |
44 ASSERT_TRUE(decrypted); | |
45 int data_length = sizeof(kOriginalData) - 1; | |
46 ASSERT_EQ(data_length, decrypted->GetDataSize()); | |
47 EXPECT_EQ(0, memcmp(kOriginalData, decrypted->GetData(), data_length)); | |
48 } | |
49 | |
50 void DecryptAndExpectToFail() { | |
51 scoped_refptr<DecoderBuffer> decrypted = | |
52 decryptor_.Decrypt(encrypted_data_); | |
53 EXPECT_FALSE(decrypted); | 144 EXPECT_FALSE(decrypted); |
54 } | 145 } |
55 | 146 |
56 scoped_refptr<DecoderBuffer> encrypted_data_; | 147 HmacAesDecryptor decryptor_; |
57 AesDecryptor decryptor_; | 148 }; |
58 }; | 149 |
59 | 150 TEST_F(HmacAesDecryptorTest, NormalDecryption) { |
60 TEST_F(AesDecryptorTest, NormalDecryption) { | 151 const WebmEncryptedData& frame = kEncryptedFrames[0]; |
61 decryptor_.AddKey(kKeyId1, kKeyIdSize, kRightKey, kKeySize); | 152 decryptor_.AddKey(frame.key_id, frame.key_id_size, |
62 SetKeyIdForEncryptedData(kKeyId1, kKeyIdSize); | 153 frame.key, frame.key_size); |
63 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed()); | 154 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, |
64 } | 155 frame.encrypted_data_size, |
65 | 156 frame.plain_text, |
66 TEST_F(AesDecryptorTest, WrongKey) { | 157 frame.plain_text_size, |
67 decryptor_.AddKey(kKeyId1, kKeyIdSize, kWrongKey, kKeySize); | 158 frame.key_id, |
68 SetKeyIdForEncryptedData(kKeyId1, kKeyIdSize); | 159 frame.key_id_size)); |
69 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail()); | 160 } |
70 } | 161 |
71 | 162 TEST_F(HmacAesDecryptorTest, WrongKey) { |
72 TEST_F(AesDecryptorTest, MultipleKeys) { | 163 const WebmEncryptedData& frame = kEncryptedFrames[0]; |
73 decryptor_.AddKey(kKeyId1, kKeyIdSize, kRightKey, kKeySize); | 164 decryptor_.AddKey(frame.key_id, frame.key_id_size, |
74 decryptor_.AddKey(kKeyId2, kKeyIdSize, kWrongKey, kKeySize); | 165 kWrongKey, kKeySize); |
75 SetKeyIdForEncryptedData(kKeyId1, kKeyIdSize); | 166 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(frame.encrypted_data, |
76 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed()); | 167 frame.encrypted_data_size, |
77 } | 168 frame.plain_text, |
78 | 169 frame.plain_text_size, |
79 TEST_F(AesDecryptorTest, KeyReplacement) { | 170 frame.key_id, |
80 SetKeyIdForEncryptedData(kKeyId1, kKeyIdSize); | 171 frame.key_id_size)); |
81 decryptor_.AddKey(kKeyId1, kKeyIdSize, kWrongKey, kKeySize); | 172 } |
82 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail()); | 173 |
83 decryptor_.AddKey(kKeyId1, kKeyIdSize, kRightKey, kKeySize); | 174 TEST_F(HmacAesDecryptorTest, MultipleKeys) { |
84 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed()); | 175 const WebmEncryptedData& frame = kEncryptedFrames[0]; |
| 176 decryptor_.AddKey(frame.key_id, frame.key_id_size, |
| 177 frame.key, frame.key_size); |
| 178 const WebmEncryptedData& frame2 = kEncryptedFrames[2]; |
| 179 decryptor_.AddKey(frame2.key_id, frame2.key_id_size, |
| 180 frame2.key, frame2.key_size); |
| 181 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, |
| 182 frame.encrypted_data_size, |
| 183 frame.plain_text, |
| 184 frame.plain_text_size, |
| 185 frame.key_id, |
| 186 frame.key_id_size)); |
| 187 } |
| 188 |
| 189 TEST_F(HmacAesDecryptorTest, KeyReplacement) { |
| 190 const WebmEncryptedData& frame = kEncryptedFrames[0]; |
| 191 decryptor_.AddKey(frame.key_id, frame.key_id_size, |
| 192 kWrongKey, kKeySize); |
| 193 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(frame.encrypted_data, |
| 194 frame.encrypted_data_size, |
| 195 frame.plain_text, |
| 196 frame.plain_text_size, |
| 197 frame.key_id, |
| 198 frame.key_id_size)); |
| 199 decryptor_.AddKey(frame.key_id, frame.key_id_size, |
| 200 frame.key, frame.key_size); |
| 201 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, |
| 202 frame.encrypted_data_size, |
| 203 frame.plain_text, |
| 204 frame.plain_text_size, |
| 205 frame.key_id, |
| 206 frame.key_id_size)); |
| 207 } |
| 208 |
| 209 TEST_F(HmacAesDecryptorTest, MultipleKeysAndFrames) { |
| 210 const WebmEncryptedData& frame = kEncryptedFrames[0]; |
| 211 decryptor_.AddKey(frame.key_id, frame.key_id_size, |
| 212 frame.key, frame.key_size); |
| 213 const WebmEncryptedData& frame2 = kEncryptedFrames[2]; |
| 214 decryptor_.AddKey(frame2.key_id, frame2.key_id_size, |
| 215 frame2.key, frame2.key_size); |
| 216 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, |
| 217 frame.encrypted_data_size, |
| 218 frame.plain_text, |
| 219 frame.plain_text_size, |
| 220 frame.key_id, |
| 221 frame.key_id_size)); |
| 222 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame2.encrypted_data, |
| 223 frame2.encrypted_data_size, |
| 224 frame2.plain_text, |
| 225 frame2.plain_text_size, |
| 226 frame2.key_id, |
| 227 frame2.key_id_size)); |
| 228 } |
| 229 |
| 230 TEST_F(HmacAesDecryptorTest, HmacCheckFailure) { |
| 231 const WebmEncryptedData& frame = kEncryptedFrames[0]; |
| 232 decryptor_.AddKey(frame.key_id, frame.key_id_size, |
| 233 frame.key, frame.key_size); |
| 234 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(kFrame0InvalidHmac, |
| 235 frame.encrypted_data_size, |
| 236 frame.plain_text, |
| 237 frame.plain_text_size, |
| 238 frame.key_id, |
| 239 frame.key_id_size)); |
| 240 } |
| 241 |
| 242 TEST_F(HmacAesDecryptorTest, IvCheckFailure) { |
| 243 const WebmEncryptedData& frame = kEncryptedFrames[0]; |
| 244 decryptor_.AddKey(frame.key_id, frame.key_id_size, |
| 245 frame.key, frame.key_size); |
| 246 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(kFrame0InvalidIv, |
| 247 frame.encrypted_data_size, |
| 248 frame.plain_text, |
| 249 frame.plain_text_size, |
| 250 frame.key_id, |
| 251 frame.key_id_size)); |
| 252 } |
| 253 |
| 254 TEST_F(HmacAesDecryptorTest, DataCheckFailure) { |
| 255 const WebmEncryptedData& frame = kEncryptedFrames[0]; |
| 256 decryptor_.AddKey(frame.key_id, frame.key_id_size, |
| 257 frame.key, frame.key_size); |
| 258 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(kFrame0InvalidData, |
| 259 frame.encrypted_data_size, |
| 260 frame.plain_text, |
| 261 frame.plain_text_size, |
| 262 frame.key_id, |
| 263 frame.key_id_size)); |
85 } | 264 } |
86 | 265 |
87 } // media | 266 } // media |
OLD | NEW |