Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <string> | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "base/sys_byteorder.h" | |
| 9 #include "media/base/decoder_buffer.h" | |
| 10 #include "media/base/decrypt_config.h" | |
| 11 #include "media/crypto/hmac_aes_decryptor.h" | |
| 12 #include "testing/gtest/include/gtest/gtest.h" | |
| 13 | |
| 14 namespace media { | |
| 15 | |
| 16 struct WebmEncryptedData { | |
| 17 uint8 plain_text[32]; | |
| 18 int plain_text_size; | |
| 19 uint8 key_id[32]; | |
| 20 int key_id_size; | |
| 21 uint8 key[32]; | |
| 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 "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf" | |
| 33 "\x10\x11\x12\x13", 20, | |
| 34 // key | |
| 35 "\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23", 16, | |
| 36 // encrypted_data | |
| 37 "\xfb\xe7\x1d\xbb\x4c\x23\xce\xba\xcc\xf8\xda\xc0\xff\xff\xff\xff" | |
|
xhwang
2012/06/14 19:42:27
FYI, I am switching to {0x00, 0x11, ...} style for
fgalligan1
2012/07/03 22:00:15
Done.
| |
| 38 "\xff\xff\xff\xff\x99\xaa\xff\xb7\x74\x2\x4e\x1c\x75\x3d\xee\xcb" | |
| 39 "\x64\xf7", 34 | |
| 40 }, | |
| 41 { | |
| 42 // plaintext | |
| 43 "Changed Original data.", 22, | |
| 44 // key_id | |
| 45 "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf" | |
| 46 "\x10\x11\x12\x13", 20, | |
| 47 // key | |
| 48 "\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23", 16, | |
| 49 // encrypted_data | |
| 50 "\x43\xe4\x78\x7a\x43\xe1\x49\xbb\x44\x38\xdf\xfc\x0\x0\x0\x0" | |
| 51 "\x0\x0\x0\x0\xec\x8e\x87\x21\xd3\xb9\x1c\x61\xf6\x5a\x60\xaa" | |
| 52 "\x7\xe\x96\xd0\x54\x5d\x35\x9a\x4a\xd3", 42 | |
| 53 }, | |
| 54 { | |
| 55 // plaintext | |
| 56 "Original data.", 14, | |
| 57 // key_id | |
| 58 "\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30", 13, | |
| 59 // key | |
| 60 "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40", 16, | |
| 61 // encrypted_data | |
| 62 "\xd9\x43\x30\xfd\x82\x77\x62\x4\x8\xc2\x48\x89\x0\x0\x0\x0" | |
| 63 "\x0\x0\x0\x1\x48\x5e\x4a\x41\x2a\x8b\xf4\xc6\x47\x54\x90\x34" | |
| 64 "\xf4\x8b", 34 | |
| 65 }, | |
| 66 }; | |
| 67 | |
| 68 static const int kKeySize = 16; | |
| 69 static const unsigned char kWrongKey[] = "I'm a wrong key."; | |
| 70 static const unsigned char kFrame0InvalidHmac[] = | |
| 71 "\xfc\xe7\x1d\xbb\x4c\x23\xce\xba\xcc\xf8\xda\xc0\xff\xff\xff\xff" | |
| 72 "\xff\xff\xff\xff\x99\xaa\xff\xb7\x74\x2\x4e\x1c\x75\x3d\xee\xcb" | |
| 73 "\x64\xf7"; | |
| 74 static const unsigned char kFrame0InvalidIv[] = | |
| 75 "\xfb\xe7\x1d\xbb\x4c\x23\xce\xba\xcc\xf8\xda\xc0\x0f\xff\xff\xff" | |
| 76 "\xff\xff\xff\xff\x99\xaa\xff\xb7\x74\x2\x4e\x1c\x75\x3d\xee\xcb" | |
| 77 "\x64\xf7"; | |
| 78 static const unsigned char kFrame0InvalidData[] = | |
| 79 "\xfb\xe7\x1d\xbb\x4c\x23\xce\xba\xcc\xf8\xda\xc0\xff\xff\xff\xff" | |
| 80 "\xff\xff\xff\xff\x99\xaa\xff\xb7\x74\x2\x4e\x1c\x75\x3d\xee\xcb" | |
| 81 "\x64\xf8"; | |
| 82 | |
| 83 class HmacAesDecryptorTest : public testing::Test { | |
| 84 public: | |
| 85 HmacAesDecryptorTest() {} | |
| 86 | |
| 87 protected: | |
| 88 scoped_refptr<DecoderBuffer> CreateEncryptedBuffer(const uint8* data, | |
| 89 int data_size, | |
| 90 const uint8* key_id, | |
| 91 int key_id_size) { | |
| 92 CHECK_GE(data_size, | |
| 93 DecryptConfig::kWebMIntegrityCheckSize + DecryptConfig::kIvSize); | |
| 94 scoped_refptr<DecoderBuffer> encrypted_buffer = DecoderBuffer::CopyFrom( | |
| 95 data, data_size); | |
| 96 CHECK(encrypted_buffer); | |
| 97 | |
| 98 // Every encrypted Block has an HMAC and IV prepended to it. Current WebM | |
| 99 // encrypted request for comments specification is here | |
| 100 // http://wiki.webmproject.org/encryption/webm-encryption-rfc. | |
| 101 uint64 network_iv; | |
| 102 memcpy(&network_iv, | |
| 103 data + DecryptConfig::kWebMIntegrityCheckSize, | |
| 104 sizeof(network_iv)); | |
| 105 const uint64 iv = base::NetToHost64(network_iv); | |
| 106 encrypted_buffer->SetDecryptConfig( | |
| 107 scoped_ptr<DecryptConfig>(new DecryptConfig( | |
| 108 data, DecryptConfig::kWebMIntegrityCheckSize, | |
| 109 iv, | |
| 110 key_id, key_id_size))); | |
| 111 return encrypted_buffer; | |
| 112 } | |
| 113 | |
| 114 void DecryptAndExpectToSucceed(const uint8* data, int data_size, | |
| 115 const uint8* plain_text, | |
| 116 int plain_text_size, | |
| 117 const uint8* key_id, int key_id_size) { | |
|
xhwang
2012/06/14 19:42:27
Since data, plain_text and key_id are all arrays a
fgalligan1
2012/07/03 22:00:15
I can't use the template function here because it
| |
| 118 scoped_refptr<DecoderBuffer> encrypted_data = | |
| 119 CreateEncryptedBuffer(data, data_size, key_id, key_id_size); | |
| 120 scoped_refptr<DecoderBuffer> decrypted = | |
| 121 decryptor_.Decrypt(encrypted_data); | |
| 122 ASSERT_TRUE(decrypted); | |
| 123 ASSERT_EQ(plain_text_size, decrypted->GetDataSize()); | |
| 124 EXPECT_EQ(0, memcmp(plain_text, decrypted->GetData(), plain_text_size)); | |
| 125 } | |
| 126 | |
| 127 void DecryptAndExpectToFail(const uint8* data, int data_size, | |
| 128 const uint8* plain_text, int plain_text_size, | |
| 129 const uint8* key_id, int key_id_size) { | |
| 130 scoped_refptr<DecoderBuffer> encrypted_data = | |
| 131 CreateEncryptedBuffer(data, data_size, key_id, key_id_size); | |
| 132 scoped_refptr<DecoderBuffer> decrypted = | |
| 133 decryptor_.Decrypt(encrypted_data); | |
| 134 EXPECT_FALSE(decrypted); | |
| 135 } | |
| 136 | |
| 137 HmacAesDecryptor decryptor_; | |
| 138 }; | |
| 139 | |
| 140 TEST_F(HmacAesDecryptorTest, NormalDecryption) { | |
| 141 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
| 142 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
| 143 frame.key, frame.key_size); | |
| 144 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, | |
| 145 frame.encrypted_data_size, | |
| 146 frame.plain_text, | |
| 147 frame.plain_text_size, | |
| 148 frame.key_id, | |
| 149 frame.key_id_size)); | |
| 150 } | |
| 151 | |
| 152 TEST_F(HmacAesDecryptorTest, WrongKey) { | |
| 153 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
| 154 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
| 155 kWrongKey, kKeySize); | |
| 156 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(frame.encrypted_data, | |
| 157 frame.encrypted_data_size, | |
| 158 frame.plain_text, | |
| 159 frame.plain_text_size, | |
| 160 frame.key_id, | |
| 161 frame.key_id_size)); | |
| 162 } | |
| 163 | |
| 164 TEST_F(HmacAesDecryptorTest, MultipleKeys) { | |
| 165 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
| 166 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
| 167 frame.key, frame.key_size); | |
| 168 const WebmEncryptedData& frame2 = kEncryptedFrames[2]; | |
| 169 decryptor_.AddKey(frame2.key_id, frame2.key_id_size, | |
| 170 frame2.key, frame2.key_size); | |
| 171 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, | |
| 172 frame.encrypted_data_size, | |
| 173 frame.plain_text, | |
| 174 frame.plain_text_size, | |
| 175 frame.key_id, | |
| 176 frame.key_id_size)); | |
| 177 } | |
| 178 | |
| 179 TEST_F(HmacAesDecryptorTest, KeyReplacement) { | |
| 180 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
| 181 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
| 182 kWrongKey, kKeySize); | |
| 183 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(frame.encrypted_data, | |
| 184 frame.encrypted_data_size, | |
| 185 frame.plain_text, | |
| 186 frame.plain_text_size, | |
| 187 frame.key_id, | |
| 188 frame.key_id_size)); | |
| 189 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
| 190 frame.key, frame.key_size); | |
| 191 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, | |
| 192 frame.encrypted_data_size, | |
| 193 frame.plain_text, | |
| 194 frame.plain_text_size, | |
| 195 frame.key_id, | |
| 196 frame.key_id_size)); | |
| 197 } | |
| 198 | |
| 199 TEST_F(HmacAesDecryptorTest, MultipleKeysAndFrames) { | |
| 200 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
| 201 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
| 202 frame.key, frame.key_size); | |
| 203 const WebmEncryptedData& frame2 = kEncryptedFrames[2]; | |
| 204 decryptor_.AddKey(frame2.key_id, frame2.key_id_size, | |
| 205 frame2.key, frame2.key_size); | |
| 206 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame.encrypted_data, | |
| 207 frame.encrypted_data_size, | |
| 208 frame.plain_text, | |
| 209 frame.plain_text_size, | |
| 210 frame.key_id, | |
| 211 frame.key_id_size)); | |
| 212 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToSucceed(frame2.encrypted_data, | |
| 213 frame2.encrypted_data_size, | |
| 214 frame2.plain_text, | |
| 215 frame2.plain_text_size, | |
| 216 frame2.key_id, | |
| 217 frame2.key_id_size)); | |
| 218 } | |
| 219 | |
| 220 TEST_F(HmacAesDecryptorTest, HmacCheckFailure) { | |
| 221 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
| 222 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
| 223 frame.key, frame.key_size); | |
| 224 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(kFrame0InvalidHmac, | |
| 225 frame.encrypted_data_size, | |
| 226 frame.plain_text, | |
| 227 frame.plain_text_size, | |
| 228 frame.key_id, | |
| 229 frame.key_id_size)); | |
| 230 } | |
| 231 | |
| 232 TEST_F(HmacAesDecryptorTest, IvCheckFailure) { | |
| 233 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
| 234 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
| 235 frame.key, frame.key_size); | |
| 236 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(kFrame0InvalidIv, | |
| 237 frame.encrypted_data_size, | |
| 238 frame.plain_text, | |
| 239 frame.plain_text_size, | |
| 240 frame.key_id, | |
| 241 frame.key_id_size)); | |
| 242 } | |
| 243 | |
| 244 TEST_F(HmacAesDecryptorTest, DataCheckFailure) { | |
| 245 const WebmEncryptedData& frame = kEncryptedFrames[0]; | |
| 246 decryptor_.AddKey(frame.key_id, frame.key_id_size, | |
| 247 frame.key, frame.key_size); | |
| 248 ASSERT_NO_FATAL_FAILURE(DecryptAndExpectToFail(kFrame0InvalidData, | |
| 249 frame.encrypted_data_size, | |
| 250 frame.plain_text, | |
| 251 frame.plain_text_size, | |
| 252 frame.key_id, | |
| 253 frame.key_id_size)); | |
| 254 } | |
| 255 | |
| 256 } // media | |
| OLD | NEW |