1 // Copyright 2015 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.
5 #include "media/cdm/cenc_utils.h"
7 #include "base/logging.h"
8 #include "testing/gtest/include/gtest/gtest.h"
12 const uint8_t kKey1Data
[] = {
13 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03,
14 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03
16 const uint8_t kKey2Data
[] = {
17 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04,
18 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04,
20 const uint8_t kKey3Data
[] = {
21 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x05,
22 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x05,
24 const uint8_t kKey4Data
[] = {
25 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x06,
26 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x06,
29 class CencUtilsTest
: public testing::Test
{
32 : key1_(kKey1Data
, kKey1Data
+ arraysize(kKey1Data
)),
33 key2_(kKey2Data
, kKey2Data
+ arraysize(kKey2Data
)),
34 key3_(kKey3Data
, kKey3Data
+ arraysize(kKey3Data
)),
35 key4_(kKey4Data
, kKey4Data
+ arraysize(kKey4Data
)) {}
38 // Initialize the start of the 'pssh' box (up to key_count)
39 void InitializePSSHBox(std::vector
<uint8_t>* box
,
42 DCHECK(box
->size() == 0);
56 box
->push_back(version
);
61 // Add Clear Key SystemID.
80 std::vector
<uint8_t> MakePSSHBox(uint8_t version
) {
81 std::vector
<uint8_t> box
;
82 uint8_t size
= (version
== 0) ? 32 : 36;
83 InitializePSSHBox(&box
, size
, version
);
85 // Add key_count (= 0).
91 // Add data_size (= 0).
99 std::vector
<uint8_t> MakePSSHBox(uint8_t version
,
100 const std::vector
<uint8_t>& key1
) {
102 DCHECK(key1
.size() == 16);
104 std::vector
<uint8_t> box
;
106 InitializePSSHBox(&box
, size
, version
);
108 // Add key_count (= 1).
115 for (int i
= 0; i
< 16; ++i
)
116 box
.push_back(key1
[i
]);
118 // Add data_size (= 0).
126 std::vector
<uint8_t> MakePSSHBox(uint8_t version
,
127 const std::vector
<uint8_t>& key1
,
128 const std::vector
<uint8_t>& key2
) {
130 DCHECK(key1
.size() == 16);
131 DCHECK(key2
.size() == 16);
133 std::vector
<uint8_t> box
;
135 InitializePSSHBox(&box
, size
, version
);
137 // Add key_count (= 2).
144 for (int i
= 0; i
< 16; ++i
)
145 box
.push_back(key1
[i
]);
148 for (int i
= 0; i
< 16; ++i
)
149 box
.push_back(key2
[i
]);
151 // Add data_size (= 0).
159 const std::vector
<uint8_t>& Key1() { return key1_
; }
160 const std::vector
<uint8_t>& Key2() { return key2_
; }
161 const std::vector
<uint8_t>& Key3() { return key3_
; }
162 const std::vector
<uint8_t>& Key4() { return key4_
; }
165 std::vector
<uint8_t> key1_
;
166 std::vector
<uint8_t> key2_
;
167 std::vector
<uint8_t> key3_
;
168 std::vector
<uint8_t> key4_
;
171 TEST_F(CencUtilsTest
, EmptyPSSH
) {
173 EXPECT_TRUE(ValidatePsshInput(std::vector
<uint8_t>()));
174 EXPECT_TRUE(GetKeyIdsForCommonSystemId(std::vector
<uint8_t>(), &key_ids
));
175 EXPECT_EQ(0u, key_ids
.size());
178 TEST_F(CencUtilsTest
, PSSHVersion0
) {
179 std::vector
<uint8_t> box
= MakePSSHBox(0);
181 EXPECT_TRUE(ValidatePsshInput(box
));
182 EXPECT_TRUE(GetKeyIdsForCommonSystemId(box
, &key_ids
));
183 EXPECT_EQ(0u, key_ids
.size());
186 TEST_F(CencUtilsTest
, PSSHVersion1WithNoKeys
) {
187 std::vector
<uint8_t> box
= MakePSSHBox(1);
189 EXPECT_TRUE(ValidatePsshInput(box
));
190 EXPECT_TRUE(GetKeyIdsForCommonSystemId(box
, &key_ids
));
191 EXPECT_EQ(0u, key_ids
.size());
194 TEST_F(CencUtilsTest
, PSSHVersion1WithOneKey
) {
195 std::vector
<uint8_t> box
= MakePSSHBox(1, Key1());
197 EXPECT_TRUE(ValidatePsshInput(box
));
198 EXPECT_TRUE(GetKeyIdsForCommonSystemId(box
, &key_ids
));
199 EXPECT_EQ(1u, key_ids
.size());
200 EXPECT_EQ(key_ids
[0], Key1());
203 TEST_F(CencUtilsTest
, PSSHVersion1WithTwoKeys
) {
204 std::vector
<uint8_t> box
= MakePSSHBox(1, Key1(), Key2());
206 EXPECT_TRUE(ValidatePsshInput(box
));
207 EXPECT_TRUE(GetKeyIdsForCommonSystemId(box
, &key_ids
));
208 EXPECT_EQ(2u, key_ids
.size());
209 EXPECT_EQ(key_ids
[0], Key1());
210 EXPECT_EQ(key_ids
[1], Key2());
213 TEST_F(CencUtilsTest
, PSSHVersion0Plus1
) {
214 std::vector
<uint8_t> box0
= MakePSSHBox(0);
215 std::vector
<uint8_t> box1
= MakePSSHBox(1, Key1());
217 // Concatentate box1 into box0.
218 for (const auto& value
: box1
)
219 box0
.push_back(value
);
222 EXPECT_TRUE(ValidatePsshInput(box0
));
223 EXPECT_TRUE(GetKeyIdsForCommonSystemId(box0
, &key_ids
));
224 EXPECT_EQ(1u, key_ids
.size());
225 EXPECT_EQ(key_ids
[0], Key1());
228 TEST_F(CencUtilsTest
, PSSHVersion1Plus0
) {
229 std::vector
<uint8_t> box0
= MakePSSHBox(0);
230 std::vector
<uint8_t> box1
= MakePSSHBox(1, Key1());
232 // Concatentate box0 into box1.
233 for (const auto& value
: box0
)
234 box1
.push_back(value
);
237 EXPECT_TRUE(ValidatePsshInput(box1
));
238 EXPECT_TRUE(GetKeyIdsForCommonSystemId(box1
, &key_ids
));
239 EXPECT_EQ(1u, key_ids
.size());
240 EXPECT_EQ(key_ids
[0], Key1());
243 TEST_F(CencUtilsTest
, MultiplePSSHVersion1
) {
244 std::vector
<uint8_t> box
= MakePSSHBox(1, Key1(), Key2());
245 std::vector
<uint8_t> box1
= MakePSSHBox(1, Key3());
246 std::vector
<uint8_t> box2
= MakePSSHBox(1, Key4());
248 // Concatentate box1 into box.
249 for (const auto& value
: box1
)
250 box
.push_back(value
);
251 // Concatentate box2 into box.
252 for (const auto& value
: box2
)
253 box
.push_back(value
);
256 EXPECT_TRUE(ValidatePsshInput(box
));
257 EXPECT_TRUE(GetKeyIdsForCommonSystemId(box
, &key_ids
));
258 EXPECT_EQ(4u, key_ids
.size());
259 EXPECT_EQ(key_ids
[0], Key1());
260 EXPECT_EQ(key_ids
[1], Key2());
261 EXPECT_EQ(key_ids
[2], Key3());
262 EXPECT_EQ(key_ids
[3], Key4());
265 TEST_F(CencUtilsTest
, InvalidPSSH
) {
266 std::vector
<uint8_t> box
= MakePSSHBox(1, Key1(), Key2());
268 for (uint32 i
= 1; i
< box
.size(); ++i
) {
269 // Modify size of data passed to be less than real size.
270 std::vector
<uint8_t> truncated(&box
[0], &box
[0] + i
);
271 EXPECT_FALSE(ValidatePsshInput(truncated
));
272 EXPECT_FALSE(GetKeyIdsForCommonSystemId(truncated
, &key_ids
));
273 // Modify starting point.
274 std::vector
<uint8_t> changed_offset(&box
[i
], &box
[i
] + box
.size() - i
);
275 EXPECT_FALSE(ValidatePsshInput(changed_offset
));
276 EXPECT_FALSE(GetKeyIdsForCommonSystemId(changed_offset
, &key_ids
));
280 TEST_F(CencUtilsTest
, InvalidSystemID
) {
281 std::vector
<uint8_t> box
= MakePSSHBox(1, Key1(), Key2());
283 // Modify the System ID.
287 EXPECT_TRUE(GetKeyIdsForCommonSystemId(box
, &key_ids
));
288 EXPECT_EQ(0u, key_ids
.size());
291 TEST_F(CencUtilsTest
, InvalidFlags
) {
292 std::vector
<uint8_t> box
= MakePSSHBox(1, Key1(), Key2());
298 // TODO(jrummell): This should fail as the 'pssh' box is skipped.
299 EXPECT_TRUE(GetKeyIdsForCommonSystemId(box
, &key_ids
));
300 EXPECT_EQ(0u, key_ids
.size());
303 TEST_F(CencUtilsTest
, LongSize
) {
304 const uint8_t data
[] = {
305 0x00, 0x00, 0x00, 0x01, // size = 1
306 0x70, 0x73, 0x73, 0x68, // 'pssh'
307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, // longsize
309 0x00, 0x00, 0x00, // flags
310 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, // SystemID
311 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B,
312 0x00, 0x00, 0x00, 0x02, // key count
313 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03, // key1
314 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03,
315 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04, // key2
316 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04,
317 0x00, 0x00, 0x00, 0x00 // datasize
322 ValidatePsshInput(std::vector
<uint8_t>(data
, data
+ arraysize(data
))));
323 EXPECT_TRUE(GetKeyIdsForCommonSystemId(
324 std::vector
<uint8_t>(data
, data
+ arraysize(data
)), &key_ids
));
325 EXPECT_EQ(2u, key_ids
.size());
328 TEST_F(CencUtilsTest
, NoSize
) {
329 const uint8_t data
[] = {
330 0x00, 0x00, 0x00, 0x00, // size = 0
331 0x70, 0x73, 0x73, 0x68, // 'pssh'
333 0x00, 0x00, 0x00, // flags
334 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, // SystemID
335 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B,
336 0x00, 0x00, 0x00, 0x02, // key count
337 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03, // key1
338 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03,
339 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04, // key2
340 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04,
341 0x00, 0x00, 0x00, 0x00 // datasize
346 ValidatePsshInput(std::vector
<uint8_t>(data
, data
+ arraysize(data
))));
347 EXPECT_TRUE(GetKeyIdsForCommonSystemId(
348 std::vector
<uint8_t>(data
, data
+ arraysize(data
)), &key_ids
));
349 EXPECT_EQ(2u, key_ids
.size());
352 TEST_F(CencUtilsTest
, HugeSize
) {
353 const uint8_t data
[] = {
354 0x00, 0x00, 0x00, 0x01, // size = 1
355 0x70, 0x73, 0x73, 0x68, // 'pssh'
356 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // longsize = big
358 0x00, 0x00, 0x00, // flags
359 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, // SystemID
360 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B,
361 0x00, 0x00, 0x00, 0x02, // key count
362 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03, // key1
363 0x7E, 0x57, 0x1D, 0x03, 0x7E, 0x57, 0x1D, 0x03,
364 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04, // key2
365 0x7E, 0x57, 0x1D, 0x04, 0x7E, 0x57, 0x1D, 0x04,
366 0x00, 0x00, 0x00, 0x00 // datasize
371 ValidatePsshInput(std::vector
<uint8_t>(data
, data
+ arraysize(data
))));
372 EXPECT_FALSE(GetKeyIdsForCommonSystemId(
373 std::vector
<uint8_t>(data
, data
+ arraysize(data
)), &key_ids
));