1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "HlsSampleDecryptor"
19
20 #include "HlsSampleDecryptor.h"
21
22 #include <media/stagefright/foundation/ABuffer.h>
23 #include <media/stagefright/foundation/ADebug.h>
24 #include <media/stagefright/Utils.h>
25
26
27 namespace android {
28
HlsSampleDecryptor()29 HlsSampleDecryptor::HlsSampleDecryptor()
30 : mValidKeyInfo(false) {
31 }
32
HlsSampleDecryptor(const sp<AMessage> & sampleAesKeyItem)33 HlsSampleDecryptor::HlsSampleDecryptor(const sp<AMessage> &sampleAesKeyItem)
34 : mValidKeyInfo(false) {
35
36 signalNewSampleAesKey(sampleAesKeyItem);
37 }
38
signalNewSampleAesKey(const sp<AMessage> & sampleAesKeyItem)39 void HlsSampleDecryptor::signalNewSampleAesKey(const sp<AMessage> &sampleAesKeyItem) {
40
41 if (sampleAesKeyItem == NULL) {
42 mValidKeyInfo = false;
43 ALOGW("signalNewSampleAesKey: sampleAesKeyItem is NULL");
44 return;
45 }
46
47 sp<ABuffer> keyDataBuffer, initVecBuffer;
48 sampleAesKeyItem->findBuffer("keyData", &keyDataBuffer);
49 sampleAesKeyItem->findBuffer("initVec", &initVecBuffer);
50
51 if (keyDataBuffer != NULL && keyDataBuffer->size() == AES_BLOCK_SIZE &&
52 initVecBuffer != NULL && initVecBuffer->size() == AES_BLOCK_SIZE) {
53
54 ALOGV("signalNewSampleAesKey: Key: %s IV: %s",
55 aesBlockToStr(keyDataBuffer->data()).c_str(),
56 aesBlockToStr(initVecBuffer->data()).c_str());
57
58 uint8_t KeyData[AES_BLOCK_SIZE];
59 memcpy(KeyData, keyDataBuffer->data(), AES_BLOCK_SIZE);
60 memcpy(mAESInitVec, initVecBuffer->data(), AES_BLOCK_SIZE);
61
62 mValidKeyInfo = (AES_set_decrypt_key(KeyData, 8*AES_BLOCK_SIZE/*128*/, &mAesKey) == 0);
63 if (!mValidKeyInfo) {
64 ALOGE("signalNewSampleAesKey: failed to set AES decryption key.");
65 }
66
67 } else {
68 // Media scanner might try extract/parse the TS files without knowing the key.
69 // Otherwise, shouldn't get here (unless an invalid playlist has swaped SAMPLE-AES with
70 // NONE method while still sample-encrypted stream is parsed).
71
72 mValidKeyInfo = false;
73 ALOGE("signalNewSampleAesKey Can't decrypt; keyDataBuffer: %p(%zu) initVecBuffer: %p(%zu)",
74 keyDataBuffer.get(), (keyDataBuffer.get() == NULL)? -1 : keyDataBuffer->size(),
75 initVecBuffer.get(), (initVecBuffer.get() == NULL)? -1 : initVecBuffer->size());
76 }
77 }
78
processNal(uint8_t * nalData,size_t nalSize)79 size_t HlsSampleDecryptor::processNal(uint8_t *nalData, size_t nalSize) {
80
81 unsigned nalType = nalData[0] & 0x1f;
82 if (!mValidKeyInfo) {
83 ALOGV("processNal[%d]: (%p)/%zu Skipping due to invalid key", nalType, nalData, nalSize);
84 return nalSize;
85 }
86
87 bool isEncrypted = (nalSize > VIDEO_CLEAR_LEAD + AES_BLOCK_SIZE);
88 ALOGV("processNal[%d]: (%p)/%zu isEncrypted: %d", nalType, nalData, nalSize, isEncrypted);
89
90 if (isEncrypted) {
91 // Encrypted NALUs have extra start code emulation prevention that must be
92 // stripped out before we can decrypt it.
93 size_t newSize = unescapeStream(nalData, nalSize);
94
95 ALOGV("processNal:unescapeStream[%d]: %zu -> %zu", nalType, nalSize, newSize);
96 nalSize = newSize;
97
98 //Encrypted_nal_unit () {
99 // nal_unit_type_byte // 1 byte
100 // unencrypted_leader // 31 bytes
101 // while (bytes_remaining() > 0) {
102 // if (bytes_remaining() > 16) {
103 // encrypted_block // 16 bytes
104 // }
105 // unencrypted_block // MIN(144, bytes_remaining()) bytes
106 // }
107 //}
108
109 size_t offset = VIDEO_CLEAR_LEAD;
110 size_t remainingBytes = nalSize - VIDEO_CLEAR_LEAD;
111
112 // a copy of initVec as decryptBlock updates it
113 unsigned char AESInitVec[AES_BLOCK_SIZE];
114 memcpy(AESInitVec, mAESInitVec, AES_BLOCK_SIZE);
115
116 while (remainingBytes > 0) {
117 // encrypted_block: protected block uses 10% skip encryption
118 if (remainingBytes > AES_BLOCK_SIZE) {
119 uint8_t *encrypted = nalData + offset;
120 status_t ret = decryptBlock(encrypted, AES_BLOCK_SIZE, AESInitVec);
121 if (ret != OK) {
122 ALOGE("processNal failed with %d", ret);
123 return nalSize; // revisit this
124 }
125
126 offset += AES_BLOCK_SIZE;
127 remainingBytes -= AES_BLOCK_SIZE;
128 }
129
130 // unencrypted_block
131 size_t clearBytes = std::min(remainingBytes, (size_t)(9 * AES_BLOCK_SIZE));
132
133 offset += clearBytes;
134 remainingBytes -= clearBytes;
135 } // while
136
137 } else { // isEncrypted == false
138 ALOGV("processNal[%d]: Unencrypted NALU (%p)/%zu", nalType, nalData, nalSize);
139 }
140
141 return nalSize;
142 }
143
processAAC(size_t adtsHdrSize,uint8_t * data,size_t size)144 void HlsSampleDecryptor::processAAC(size_t adtsHdrSize, uint8_t *data, size_t size) {
145
146 if (!mValidKeyInfo) {
147 ALOGV("processAAC: (%p)/%zu Skipping due to invalid key", data, size);
148 return;
149 }
150
151 // ADTS header is included in the size
152 if (size < adtsHdrSize) {
153 ALOGV("processAAC: size (%zu) < adtsHdrSize (%zu)", size, adtsHdrSize);
154 android_errorWriteLog(0x534e4554, "128433933");
155 return;
156 }
157 size_t offset = adtsHdrSize;
158 size_t remainingBytes = size - adtsHdrSize;
159
160 bool isEncrypted = (remainingBytes >= AUDIO_CLEAR_LEAD + AES_BLOCK_SIZE);
161 ALOGV("processAAC: header: %zu data: %p(%zu) isEncrypted: %d",
162 adtsHdrSize, data, size, isEncrypted);
163
164 //Encrypted_AAC_Frame () {
165 // ADTS_Header // 7 or 9 bytes
166 // unencrypted_leader // 16 bytes
167 // while (bytes_remaining() >= 16) {
168 // encrypted_block // 16 bytes
169 // }
170 // unencrypted_trailer // 0-15 bytes
171 //}
172
173 // with lead bytes
174 if (remainingBytes >= AUDIO_CLEAR_LEAD) {
175 offset += AUDIO_CLEAR_LEAD;
176 remainingBytes -= AUDIO_CLEAR_LEAD;
177
178 // encrypted_block
179 if (remainingBytes >= AES_BLOCK_SIZE) {
180
181 size_t encryptedBytes = (remainingBytes / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
182 unsigned char AESInitVec[AES_BLOCK_SIZE];
183 memcpy(AESInitVec, mAESInitVec, AES_BLOCK_SIZE);
184
185 // decrypting all blocks at once
186 uint8_t *encrypted = data + offset;
187 status_t ret = decryptBlock(encrypted, encryptedBytes, AESInitVec);
188 if (ret != OK) {
189 ALOGE("processAAC: decryptBlock failed with %d", ret);
190 return;
191 }
192
193 offset += encryptedBytes;
194 remainingBytes -= encryptedBytes;
195 } // encrypted
196
197 // unencrypted_trailer
198 size_t clearBytes = remainingBytes;
199 if (clearBytes > 0) {
200 CHECK(clearBytes < AES_BLOCK_SIZE);
201 }
202
203 } else { // without lead bytes
204 ALOGV("processAAC: Unencrypted frame (without lead bytes) size %zu = %zu (hdr) + %zu (rem)",
205 size, adtsHdrSize, remainingBytes);
206 }
207
208 }
209
processAC3(uint8_t * data,size_t size)210 void HlsSampleDecryptor::processAC3(uint8_t *data, size_t size) {
211
212 if (!mValidKeyInfo) {
213 ALOGV("processAC3: (%p)/%zu Skipping due to invalid key", data, size);
214 return;
215 }
216
217 bool isEncrypted = (size >= AUDIO_CLEAR_LEAD + AES_BLOCK_SIZE);
218 ALOGV("processAC3 %p(%zu) isEncrypted: %d", data, size, isEncrypted);
219
220 //Encrypted_AC3_Frame () {
221 // unencrypted_leader // 16 bytes
222 // while (bytes_remaining() >= 16) {
223 // encrypted_block // 16 bytes
224 // }
225 // unencrypted_trailer // 0-15 bytes
226 //}
227
228 if (size >= AUDIO_CLEAR_LEAD) {
229 // unencrypted_leader
230 size_t offset = AUDIO_CLEAR_LEAD;
231 size_t remainingBytes = size - AUDIO_CLEAR_LEAD;
232
233 if (remainingBytes >= AES_BLOCK_SIZE) {
234
235 size_t encryptedBytes = (remainingBytes / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
236
237 // encrypted_block
238 unsigned char AESInitVec[AES_BLOCK_SIZE];
239 memcpy(AESInitVec, mAESInitVec, AES_BLOCK_SIZE);
240
241 // decrypting all blocks at once
242 uint8_t *encrypted = data + offset;
243 status_t ret = decryptBlock(encrypted, encryptedBytes, AESInitVec);
244 if (ret != OK) {
245 ALOGE("processAC3: decryptBlock failed with %d", ret);
246 return;
247 }
248
249 offset += encryptedBytes;
250 remainingBytes -= encryptedBytes;
251 } // encrypted
252
253 // unencrypted_trailer
254 size_t clearBytes = remainingBytes;
255 if (clearBytes > 0) {
256 CHECK(clearBytes < AES_BLOCK_SIZE);
257 }
258
259 } else {
260 ALOGV("processAC3: Unencrypted frame (without lead bytes) size %zu", size);
261 }
262 }
263
264 // Unescapes data replacing occurrences of [0, 0, 3] with [0, 0] and returns the new size
unescapeStream(uint8_t * data,size_t limit) const265 size_t HlsSampleDecryptor::unescapeStream(uint8_t *data, size_t limit) const {
266 Vector<size_t> scratchEscapePositions;
267 size_t position = 0;
268
269 while (position < limit) {
270 position = findNextUnescapeIndex(data, position, limit);
271 if (position < limit) {
272 scratchEscapePositions.add(position);
273 position += 3;
274 }
275 }
276
277 size_t scratchEscapeCount = scratchEscapePositions.size();
278 size_t escapedPosition = 0; // The position being read from.
279 size_t unescapedPosition = 0; // The position being written to.
280 for (size_t i = 0; i < scratchEscapeCount; i++) {
281 size_t nextEscapePosition = scratchEscapePositions[i];
282 //TODO: add 2 and get rid of the later = 0 assignments
283 size_t copyLength = nextEscapePosition - escapedPosition;
284 memmove(data+unescapedPosition, data+escapedPosition, copyLength);
285 unescapedPosition += copyLength;
286 data[unescapedPosition++] = 0;
287 data[unescapedPosition++] = 0;
288 escapedPosition += copyLength + 3;
289 }
290
291 size_t unescapedLength = limit - scratchEscapeCount;
292 size_t remainingLength = unescapedLength - unescapedPosition;
293 memmove(data+unescapedPosition, data+escapedPosition, remainingLength);
294
295 return unescapedLength;
296 }
297
findNextUnescapeIndex(uint8_t * data,size_t offset,size_t limit) const298 size_t HlsSampleDecryptor::findNextUnescapeIndex(uint8_t *data, size_t offset, size_t limit) const {
299 for (size_t i = offset; i < limit - 2; i++) {
300 //TODO: speed
301 if (data[i] == 0x00 && data[i + 1] == 0x00 && data[i + 2] == 0x03) {
302 return i;
303 }
304 }
305 return limit;
306 }
307
decryptBlock(uint8_t * buffer,size_t size,uint8_t AESInitVec[AES_BLOCK_SIZE])308 status_t HlsSampleDecryptor::decryptBlock(uint8_t *buffer, size_t size,
309 uint8_t AESInitVec[AES_BLOCK_SIZE]) {
310 if (size == 0) {
311 return OK;
312 }
313
314 if ((size % AES_BLOCK_SIZE) != 0) {
315 ALOGE("decryptBlock: size (%zu) not a multiple of block size", size);
316 return ERROR_MALFORMED;
317 }
318
319 ALOGV("decryptBlock: %p (%zu)", buffer, size);
320
321 AES_cbc_encrypt(buffer, buffer, size, &mAesKey, AESInitVec, AES_DECRYPT);
322
323 return OK;
324 }
325
aesBlockToStr(uint8_t block[AES_BLOCK_SIZE])326 AString HlsSampleDecryptor::aesBlockToStr(uint8_t block[AES_BLOCK_SIZE]) {
327 AString result;
328
329 if (block == NULL) {
330 result = AString("null");
331 } else {
332 result = AStringPrintf("0x%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
333 block[0], block[1], block[2], block[3], block[4], block[5], block[6], block[7],
334 block[8], block[9], block[10], block[11], block[12], block[13], block[14], block[15]);
335 }
336
337 return result;
338 }
339
340
341 } // namespace android
342