1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #include "mozilla/Unused.h"
6 #include "SinfParser.h"
7 #include "AtomType.h"
8 #include "Box.h"
9 #include "ByteStream.h"
10
11 namespace mozilla {
12
Sinf(Box & aBox)13 Sinf::Sinf(Box& aBox) : mDefaultIVSize(0), mDefaultEncryptionType() {
14 SinfParser parser(aBox);
15 if (parser.GetSinf().IsValid()) {
16 *this = parser.GetSinf();
17 }
18 }
19
SinfParser(Box & aBox)20 SinfParser::SinfParser(Box& aBox) {
21 for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
22 if (box.IsType("schm")) {
23 mozilla::Unused << ParseSchm(box);
24 } else if (box.IsType("schi")) {
25 mozilla::Unused << ParseSchi(box);
26 }
27 }
28 }
29
ParseSchm(Box & aBox)30 Result<Ok, nsresult> SinfParser::ParseSchm(Box& aBox) {
31 BoxReader reader(aBox);
32
33 if (reader->Remaining() < 8) {
34 return Err(NS_ERROR_FAILURE);
35 }
36
37 MOZ_TRY(reader->ReadU32()); // flags -- ignore
38 MOZ_TRY_VAR(mSinf.mDefaultEncryptionType, reader->ReadU32());
39 return Ok();
40 }
41
ParseSchi(Box & aBox)42 Result<Ok, nsresult> SinfParser::ParseSchi(Box& aBox) {
43 for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) {
44 if (box.IsType("tenc") && ParseTenc(box).isErr()) {
45 return Err(NS_ERROR_FAILURE);
46 }
47 }
48 return Ok();
49 }
50
ParseTenc(Box & aBox)51 Result<Ok, nsresult> SinfParser::ParseTenc(Box& aBox) {
52 BoxReader reader(aBox);
53
54 if (reader->Remaining() < 24) {
55 return Err(NS_ERROR_FAILURE);
56 }
57
58 uint32_t flags;
59 MOZ_TRY_VAR(flags, reader->ReadU32());
60 uint8_t version = flags >> 24;
61
62 // Skip reserved byte
63 MOZ_TRY(reader->ReadU8());
64 if (version >= 1) {
65 uint8_t pattern;
66 MOZ_TRY_VAR(pattern, reader->ReadU8());
67 mSinf.mDefaultCryptByteBlock = pattern >> 4;
68 mSinf.mDefaultSkipByteBlock = pattern & 0x0f;
69 } else {
70 // Reserved if version is less than 1
71 MOZ_TRY(reader->ReadU8());
72 mSinf.mDefaultCryptByteBlock = 0;
73 mSinf.mDefaultSkipByteBlock = 0;
74 }
75
76 uint8_t isEncrypted;
77 MOZ_TRY_VAR(isEncrypted, reader->ReadU8());
78 MOZ_TRY_VAR(mSinf.mDefaultIVSize, reader->ReadU8());
79 memcpy(mSinf.mDefaultKeyID, reader->Read(16), 16);
80
81 if (isEncrypted && mSinf.mDefaultIVSize == 0) {
82 uint8_t defaultConstantIVSize;
83 MOZ_TRY_VAR(defaultConstantIVSize, reader->ReadU8());
84 if (!mSinf.mDefaultConstantIV.SetLength(defaultConstantIVSize,
85 mozilla::fallible)) {
86 return Err(NS_ERROR_FAILURE);
87 }
88 for (uint8_t i = 0; i < defaultConstantIVSize; i++) {
89 MOZ_TRY_VAR(mSinf.mDefaultConstantIV.ElementAt(i), reader->ReadU8());
90 }
91 }
92 return Ok();
93 }
94
95 } // namespace mozilla
96