• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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