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" |
| 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) { |
| 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 |