blob: df22327b1d24231205b060868f464f33db2ec745 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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#include <drm_rights_manager.h>
18#include <drm_inner.h>
19#include <drm_file.h>
20#include <drm_i18n.h>
21
22static int32_t drm_getString(uint8_t* string, int32_t len, int32_t handle)
23{
24 int32_t i;
25
26 for (i = 0; i < len; i++) {
27 if (DRM_FILE_FAILURE == DRM_file_read(handle, &string[i], 1))
28 return FALSE;
29 if (string[i] == '\n') {
30 string[i + 1] = '\0';
31 break;
32 }
33 }
34 return TRUE;
35}
36
37static int32_t drm_putString(uint8_t* string, int32_t handle)
38{
39 int32_t i = 0;
40
41 for (i = 0;; i++) {
42 if (string[i] == '\0')
43 break;
44 if (DRM_FILE_FAILURE == DRM_file_write(handle, &string[i], 1))
45 return FALSE;
46 }
47 return TRUE;
48}
49
50static int32_t drm_writeToUidTxt(uint8_t* Uid, int32_t* id)
51{
52 int32_t length;
53 int32_t i;
54 uint8_t idStr[8];
55 int32_t idMax;
56 uint8_t(*uidStr)[256];
57 uint16_t nameUcs2[MAX_FILENAME_LEN];
58 int32_t nameLen;
59 int32_t bytesConsumed;
60 int32_t handle;
61 int32_t fileRes;
62
63 if (*id < 1)
64 return FALSE;
65
66 /* convert in ucs2 */
67 nameLen = strlen(DRM_UID_FILE_PATH);
68 nameLen = DRM_i18n_mbsToWcs(DRM_CHARSET_UTF8,
69 (uint8_t *)DRM_UID_FILE_PATH,
70 nameLen,
71 nameUcs2,
72 MAX_FILENAME_LEN,
73 &bytesConsumed);
74 fileRes = DRM_file_open(nameUcs2,
75 nameLen,
76 DRM_FILE_MODE_READ,
77 &handle);
78 if (DRM_FILE_SUCCESS != fileRes) {
79 DRM_file_open(nameUcs2,
80 nameLen,
81 DRM_FILE_MODE_WRITE,
82 &handle);
83 DRM_file_write(handle, (uint8_t *)"0\n", 2);
84 DRM_file_close(handle);
85 DRM_file_open(nameUcs2,
86 nameLen,
87 DRM_FILE_MODE_READ,
88 &handle);
89 }
90
91 if (!drm_getString(idStr, 8, handle)) {
92 DRM_file_close(handle);
93 return FALSE;
94 }
95 idMax = atoi((char *)idStr);
96
97 if (idMax < *id)
98 uidStr = malloc((idMax + 1) * 256);
99 else
100 uidStr = malloc(idMax * 256);
101
102 for (i = 0; i < idMax; i++) {
103 if (!drm_getString(uidStr[i], 256, handle)) {
104 DRM_file_close(handle);
105 free(uidStr);
106 return FALSE;
107 }
108 }
109 length = strlen((char *)Uid);
110 strcpy((char *)uidStr[*id - 1], (char *)Uid);
111 uidStr[*id - 1][length] = '\n';
112 uidStr[*id - 1][length + 1] = '\0';
113 if (idMax < (*id))
114 idMax++;
115 DRM_file_close(handle);
116
117 DRM_file_open(nameUcs2,
118 nameLen,
119 DRM_FILE_MODE_WRITE,
120 &handle);
121 sprintf((char *)idStr, "%d", idMax);
122
123 if (!drm_putString(idStr, handle)) {
124 DRM_file_close(handle);
125 free(uidStr);
126 return FALSE;
127 }
128 if (DRM_FILE_FAILURE == DRM_file_write(handle, (uint8_t *)"\n", 1)) {
129 DRM_file_close(handle);
130 free(uidStr);
131 return FALSE;
132 }
133 for (i = 0; i < idMax; i++) {
134 if (!drm_putString(uidStr[i], handle)) {
135 DRM_file_close(handle);
136 free(uidStr);
137 return FALSE;
138 }
139 }
140 if (DRM_FILE_FAILURE == DRM_file_write(handle, (uint8_t *)"\n", 1)) {
141 DRM_file_close(handle);
142 free(uidStr);
143 return FALSE;
144 }
145 DRM_file_close(handle);
146 free(uidStr);
147 return TRUE;
148}
149
150/* See objmng_files.h */
151int32_t drm_readFromUidTxt(uint8_t* Uid, int32_t* id, int32_t option)
152{
153 int32_t i;
154 uint8_t p[256] = { 0 };
155 uint8_t idStr[8];
156 int32_t idMax = 0;
157 uint16_t nameUcs2[MAX_FILENAME_LEN];
158 int32_t nameLen = 0;
159 int32_t bytesConsumed;
160 int32_t handle;
161 int32_t fileRes;
162
163 if (NULL == id || NULL == Uid)
164 return FALSE;
165
166 DRM_file_startup();
167
168 /* convert in ucs2 */
169 nameLen = strlen(DRM_UID_FILE_PATH);
170 nameLen = DRM_i18n_mbsToWcs(DRM_CHARSET_UTF8,
171 (uint8_t *)DRM_UID_FILE_PATH,
172 nameLen,
173 nameUcs2,
174 MAX_FILENAME_LEN,
175 &bytesConsumed);
176 fileRes = DRM_file_open(nameUcs2,
177 nameLen,
178 DRM_FILE_MODE_READ,
179 &handle);
180 if (DRM_FILE_SUCCESS != fileRes) {
181 DRM_file_open(nameUcs2,
182 nameLen,
183 DRM_FILE_MODE_WRITE,
184 &handle);
185 DRM_file_write(handle, (uint8_t *)"0\n", 2);
186 DRM_file_close(handle);
187 DRM_file_open(nameUcs2,
188 nameLen,
189 DRM_FILE_MODE_READ,
190 &handle);
191 }
192
193 if (!drm_getString(idStr, 8, handle)) {
194 DRM_file_close(handle);
195 return FALSE;
196 }
197 idMax = atoi((char *)idStr);
198
199 if (option == GET_UID) {
200 if (*id < 1 || *id > idMax) {
201 DRM_file_close(handle);
202 return FALSE;
203 }
204 for (i = 1; i <= *id; i++) {
205 if (!drm_getString(Uid, 256, handle)) {
206 DRM_file_close(handle);
207 return FALSE;
208 }
209 }
210 DRM_file_close(handle);
211 return TRUE;
212 }
213 if (option == GET_ID) {
214 *id = -1;
215 for (i = 1; i <= idMax; i++) {
216 if (!drm_getString(p, 256, handle)) {
217 DRM_file_close(handle);
218 return FALSE;
219 }
220 if (strstr((char *)p, (char *)Uid) != NULL
221 && strlen((char *)p) == strlen((char *)Uid) + 1) {
222 *id = i;
223 DRM_file_close(handle);
224 return TRUE;
225 }
226 if ((*id == -1) && (strlen((char *)p) < 3))
227 *id = i;
228 }
229 if (*id != -1) {
230 DRM_file_close(handle);
231 return FALSE;
232 }
233 *id = idMax + 1;
234 DRM_file_close(handle);
235 return FALSE;
236 }
237 DRM_file_close(handle);
238 return FALSE;
239}
240
241static int32_t drm_acquireId(uint8_t* uid, int32_t* id)
242{
243 if (TRUE == drm_readFromUidTxt(uid, id, GET_ID))
244 return TRUE;
245
246 drm_writeToUidTxt(uid, id);
247
248 return FALSE; /* The Uid is not exit, then return FALSE indicate it */
249}
250
251int32_t drm_writeOrReadInfo(int32_t id, T_DRM_Rights* Ro, int32_t* RoAmount, int32_t option)
252{
253 uint8_t fullname[MAX_FILENAME_LEN] = {0};
254 int32_t tmpRoAmount;
255 uint16_t nameUcs2[MAX_FILENAME_LEN];
256 int32_t nameLen = 0;
257 int32_t bytesConsumed;
258 int32_t handle;
259 int32_t fileRes;
260
261 sprintf((char *)fullname, ANDROID_DRM_CORE_PATH"%d"EXTENSION_NAME_INFO, id);
262
263 /* convert in ucs2 */
264 nameLen = strlen((char *)fullname);
265 nameLen = DRM_i18n_mbsToWcs(DRM_CHARSET_UTF8,
266 fullname,
267 nameLen,
268 nameUcs2,
269 MAX_FILENAME_LEN,
270 &bytesConsumed);
271 fileRes = DRM_file_open(nameUcs2,
272 nameLen,
273 DRM_FILE_MODE_READ,
274 &handle);
275 if (DRM_FILE_SUCCESS != fileRes) {
276 if (GET_ALL_RO == option || GET_A_RO == option)
277 return FALSE;
278
279 if (GET_ROAMOUNT == option) {
280 *RoAmount = -1;
281 return TRUE;
282 }
283 }
284
285 DRM_file_close(handle);
286 DRM_file_open(nameUcs2,
287 nameLen,
288 DRM_FILE_MODE_READ | DRM_FILE_MODE_WRITE,
289 &handle);
290
291 switch(option) {
292 case GET_ROAMOUNT:
293 if (DRM_FILE_FAILURE == DRM_file_read(handle, (uint8_t*)RoAmount, sizeof(int32_t))) {
294 DRM_file_close(handle);
295 return FALSE;
296 }
297 break;
298 case GET_ALL_RO:
299 DRM_file_setPosition(handle, sizeof(int32_t));
300
301 if (DRM_FILE_FAILURE == DRM_file_read(handle, (uint8_t*)Ro, (*RoAmount) * sizeof(T_DRM_Rights))) {
302 DRM_file_close(handle);
303 return FALSE;
304 }
305 break;
306 case SAVE_ALL_RO:
307 if (DRM_FILE_FAILURE == DRM_file_write(handle, (uint8_t*)RoAmount, sizeof(int32_t))) {
308 DRM_file_close(handle);
309 return FALSE;
310 }
311
312 if (NULL != Ro && *RoAmount >= 1) {
313 if (DRM_FILE_FAILURE == DRM_file_write(handle, (uint8_t*) Ro, (*RoAmount) * sizeof(T_DRM_Rights))) {
314 DRM_file_close(handle);
315 return FALSE;
316 }
317 }
318 break;
319 case GET_A_RO:
320 DRM_file_setPosition(handle, sizeof(int32_t) + (*RoAmount - 1) * sizeof(T_DRM_Rights));
321
322 if (DRM_FILE_FAILURE == DRM_file_read(handle, (uint8_t*)Ro, sizeof(T_DRM_Rights))) {
323 DRM_file_close(handle);
324 return FALSE;
325 }
326 break;
327 case SAVE_A_RO:
328 DRM_file_setPosition(handle, sizeof(int32_t) + (*RoAmount - 1) * sizeof(T_DRM_Rights));
329
330 if (DRM_FILE_FAILURE == DRM_file_write(handle, (uint8_t*)Ro, sizeof(T_DRM_Rights))) {
331 DRM_file_close(handle);
332 return FALSE;
333 }
334
335 DRM_file_setPosition(handle, 0);
336 if (DRM_FILE_FAILURE == DRM_file_read(handle, (uint8_t*)&tmpRoAmount, sizeof(int32_t))) {
337 DRM_file_close(handle);
338 return FALSE;
339 }
340 if (tmpRoAmount < *RoAmount) {
341 DRM_file_setPosition(handle, 0);
342 DRM_file_write(handle, (uint8_t*)RoAmount, sizeof(int32_t));
343 }
344 break;
345 default:
346 DRM_file_close(handle);
347 return FALSE;
348 }
349
350 DRM_file_close(handle);
351 return TRUE;
352}
353
354int32_t drm_appendRightsInfo(T_DRM_Rights* rights)
355{
356 int32_t id;
357 int32_t roAmount;
358
359 if (NULL == rights)
360 return FALSE;
361
362 drm_acquireId(rights->uid, &id);
363
364 if (FALSE == drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT))
365 return FALSE;
366
367 if (-1 == roAmount)
368 roAmount = 0;
369
370 /* The RO amount increase */
371 roAmount++;
372
373 /* Save the rights information */
374 if (FALSE == drm_writeOrReadInfo(id, rights, &roAmount, SAVE_A_RO))
375 return FALSE;
376
377 return TRUE;
378}
379
380int32_t drm_getMaxIdFromUidTxt()
381{
382 uint8_t idStr[8];
383 int32_t idMax = 0;
384 uint16_t nameUcs2[MAX_FILENAME_LEN] = {0};
385 int32_t nameLen = 0;
386 int32_t bytesConsumed;
387 int32_t handle;
388 int32_t fileRes;
389
390 /* convert in ucs2 */
391 nameLen = strlen(DRM_UID_FILE_PATH);
392 nameLen = DRM_i18n_mbsToWcs(DRM_CHARSET_UTF8,
393 (uint8_t *)DRM_UID_FILE_PATH,
394 nameLen,
395 nameUcs2,
396 MAX_FILENAME_LEN,
397 &bytesConsumed);
398 fileRes = DRM_file_open(nameUcs2,
399 nameLen,
400 DRM_FILE_MODE_READ,
401 &handle);
402
403 /* this means the uid.txt file is not exist, so there is not any DRM object */
404 if (DRM_FILE_SUCCESS != fileRes)
405 return 0;
406
407 if (!drm_getString(idStr, 8, handle)) {
408 DRM_file_close(handle);
409 return -1;
410 }
411 DRM_file_close(handle);
412
413 idMax = atoi((char *)idStr);
414 return idMax;
415}
416
417int32_t drm_removeIdInfoFile(int32_t id)
418{
419 uint8_t filename[MAX_FILENAME_LEN] = {0};
420 uint16_t nameUcs2[MAX_FILENAME_LEN];
421 int32_t nameLen = 0;
422 int32_t bytesConsumed;
423
424 if (id <= 0)
425 return FALSE;
426
427 sprintf((char *)filename, ANDROID_DRM_CORE_PATH"%d"EXTENSION_NAME_INFO, id);
428
429 /* convert in ucs2 */
430 nameLen = strlen((char *)filename);
431 nameLen = DRM_i18n_mbsToWcs(DRM_CHARSET_UTF8,
432 filename,
433 nameLen,
434 nameUcs2,
435 MAX_FILENAME_LEN,
436 &bytesConsumed);
437 if (DRM_FILE_SUCCESS != DRM_file_delete(nameUcs2, nameLen))
438 return FALSE;
439
440 return TRUE;
441}
442
443int32_t drm_updateUidTxtWhenDelete(int32_t id)
444{
445 uint16_t nameUcs2[MAX_FILENAME_LEN];
446 int32_t nameLen = 0;
447 int32_t bytesConsumed;
448 int32_t handle;
449 int32_t fileRes;
450 int32_t bufferLen;
451 uint8_t *buffer;
452 uint8_t idStr[8];
453 int32_t idMax;
454
455 if (id <= 0)
456 return FALSE;
457
458 nameLen = strlen(DRM_UID_FILE_PATH);
459 nameLen = DRM_i18n_mbsToWcs(DRM_CHARSET_UTF8,
460 (uint8_t *)DRM_UID_FILE_PATH,
461 nameLen,
462 nameUcs2,
463 MAX_FILENAME_LEN,
464 &bytesConsumed);
465 bufferLen = DRM_file_getFileLength(nameUcs2, nameLen);
466 if (bufferLen <= 0)
467 return FALSE;
468
469 buffer = (uint8_t *)malloc(bufferLen);
470 if (NULL == buffer)
471 return FALSE;
472
473 fileRes = DRM_file_open(nameUcs2,
474 nameLen,
475 DRM_FILE_MODE_READ,
476 &handle);
477 if (DRM_FILE_SUCCESS != fileRes) {
478 free(buffer);
479 return FALSE;
480 }
481
482 drm_getString(idStr, 8, handle);
483 idMax = atoi((char *)idStr);
484
485 bufferLen -= strlen((char *)idStr);
486 fileRes = DRM_file_read(handle, buffer, bufferLen);
487 buffer[bufferLen] = '\0';
488 DRM_file_close(handle);
489
490 /* handle this buffer */
491 {
492 uint8_t *pStart, *pEnd;
493 int32_t i, movLen;
494
495 pStart = buffer;
496 pEnd = pStart;
497 for (i = 0; i < id; i++) {
498 if (pEnd != pStart)
499 pStart = ++pEnd;
500 while ('\n' != *pEnd)
501 pEnd++;
502 if (pStart == pEnd)
503 pStart--;
504 }
505 movLen = bufferLen - (pEnd - buffer);
506 memmove(pStart, pEnd, movLen);
507 bufferLen -= (pEnd - pStart);
508 }
509
510 if (DRM_FILE_SUCCESS != DRM_file_delete(nameUcs2, nameLen)) {
511 free(buffer);
512 return FALSE;
513 }
514
515 fileRes = DRM_file_open(nameUcs2,
516 nameLen,
517 DRM_FILE_MODE_WRITE,
518 &handle);
519 if (DRM_FILE_SUCCESS != fileRes) {
520 free(buffer);
521 return FALSE;
522 }
523 sprintf((char *)idStr, "%d", idMax);
524 drm_putString(idStr, handle);
525 DRM_file_write(handle, (uint8_t*)"\n", 1);
526 DRM_file_write(handle, buffer, bufferLen);
527 free(buffer);
528 DRM_file_close(handle);
529 return TRUE;
530}
531
532int32_t drm_getKey(uint8_t* uid, uint8_t* KeyValue)
533{
534 T_DRM_Rights ro;
535 int32_t id, roAmount;
536
537 if (NULL == uid || NULL == KeyValue)
538 return FALSE;
539
540 if (FALSE == drm_readFromUidTxt(uid, &id, GET_ID))
541 return FALSE;
542
543 if (FALSE == drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT))
544 return FALSE;
545
546 if (roAmount <= 0)
547 return FALSE;
548
549 memset(&ro, 0, sizeof(T_DRM_Rights));
550 roAmount = 1;
551 if (FALSE == drm_writeOrReadInfo(id, &ro, &roAmount, GET_A_RO))
552 return FALSE;
553
554 memcpy(KeyValue, ro.KeyValue, DRM_KEY_LEN);
555 return TRUE;
556}
557
558void drm_discardPaddingByte(uint8_t *decryptedBuf, int32_t *decryptedBufLen)
559{
560 int32_t tmpLen = *decryptedBufLen;
561 int32_t i;
562
563 if (NULL == decryptedBuf || *decryptedBufLen < 0)
564 return;
565
566 /* Check whether the last several bytes are padding or not */
567 for (i = 1; i < decryptedBuf[tmpLen - 1]; i++) {
568 if (decryptedBuf[tmpLen - 1 - i] != decryptedBuf[tmpLen - 1])
569 break; /* Not the padding bytes */
570 }
571 if (i == decryptedBuf[tmpLen - 1]) /* They are padding bytes */
572 *decryptedBufLen = tmpLen - i;
573 return;
574}
575
Chia-chi Yeh64e69e82009-08-06 02:28:24 +0800576int32_t drm_aesDecBuffer(uint8_t * Buffer, int32_t * BufferLen, AES_KEY *key)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577{
578 uint8_t dbuf[3 * DRM_ONE_AES_BLOCK_LEN], buf[DRM_ONE_AES_BLOCK_LEN];
579 uint64_t i, len, wlen = DRM_ONE_AES_BLOCK_LEN, curLen, restLen;
580 uint8_t *pTarget, *pTargetHead;
581
582 pTargetHead = Buffer;
583 pTarget = Buffer;
584 curLen = 0;
585 restLen = *BufferLen;
586
587 if (restLen > 2 * DRM_ONE_AES_BLOCK_LEN) {
588 len = 2 * DRM_ONE_AES_BLOCK_LEN;
589 } else {
590 len = restLen;
591 }
592 memcpy(dbuf, Buffer, (size_t)len);
593 restLen -= len;
594 Buffer += len;
595
596 if (len < 2 * DRM_ONE_AES_BLOCK_LEN) { /* The original file is less than one block in length */
597 len -= DRM_ONE_AES_BLOCK_LEN;
598 /* Decrypt from position len to position len + DRM_ONE_AES_BLOCK_LEN */
Chia-chi Yeh64e69e82009-08-06 02:28:24 +0800599 AES_decrypt((dbuf + len), (dbuf + len), key);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600
601 /* Undo the CBC chaining */
602 for (i = 0; i < len; ++i)
603 dbuf[i] ^= dbuf[i + DRM_ONE_AES_BLOCK_LEN];
604
605 /* Output the decrypted bytes */
606 memcpy(pTarget, dbuf, (size_t)len);
607 pTarget += len;
608 } else {
609 uint8_t *b1 = dbuf, *b2 = b1 + DRM_ONE_AES_BLOCK_LEN, *b3 = b2 + DRM_ONE_AES_BLOCK_LEN, *bt;
610
611 for (;;) { /* While some ciphertext remains, prepare to decrypt block b2 */
612 /* Read in the next block to see if ciphertext stealing is needed */
613 b3 = Buffer;
614 if (restLen > DRM_ONE_AES_BLOCK_LEN) {
615 len = DRM_ONE_AES_BLOCK_LEN;
616 } else {
617 len = restLen;
618 }
619 restLen -= len;
620 Buffer += len;
621
622 /* Decrypt the b2 block */
Chia-chi Yeh64e69e82009-08-06 02:28:24 +0800623 AES_decrypt((uint8_t *)b2, buf, key);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624
625 if (len == 0 || len == DRM_ONE_AES_BLOCK_LEN) { /* No ciphertext stealing */
626 /* Unchain CBC using the previous ciphertext block in b1 */
627 for (i = 0; i < DRM_ONE_AES_BLOCK_LEN; ++i)
628 buf[i] ^= b1[i];
629 } else { /* Partial last block - use ciphertext stealing */
630 wlen = len;
631 /* Produce last 'len' bytes of plaintext by xoring with */
632 /* The lowest 'len' bytes of next block b3 - C[N-1] */
633 for (i = 0; i < len; ++i)
634 buf[i] ^= b3[i];
635
636 /* Reconstruct the C[N-1] block in b3 by adding in the */
637 /* Last (DRM_ONE_AES_BLOCK_LEN - len) bytes of C[N-2] in b2 */
638 for (i = len; i < DRM_ONE_AES_BLOCK_LEN; ++i)
639 b3[i] = buf[i];
640
641 /* Decrypt the C[N-1] block in b3 */
Chia-chi Yeh64e69e82009-08-06 02:28:24 +0800642 AES_decrypt((uint8_t *)b3, (uint8_t *)b3, key);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800643
644 /* Produce the last but one plaintext block by xoring with */
645 /* The last but two ciphertext block */
646 for (i = 0; i < DRM_ONE_AES_BLOCK_LEN; ++i)
647 b3[i] ^= b1[i];
648
649 /* Write decrypted plaintext blocks */
650 memcpy(pTarget, b3, DRM_ONE_AES_BLOCK_LEN);
651 pTarget += DRM_ONE_AES_BLOCK_LEN;
652 }
653
654 /* Write the decrypted plaintext block */
655 memcpy(pTarget, buf, (size_t)wlen);
656 pTarget += wlen;
657
658 if (len != DRM_ONE_AES_BLOCK_LEN) {
659 *BufferLen = pTarget - pTargetHead;
660 return 0;
661 }
662
663 /* Advance the buffer pointers */
664 bt = b1, b1 = b2, b2 = b3, b3 = bt;
665 }
666 }
667 return 0;
668}
669
670int32_t drm_updateDcfDataLen(uint8_t* pDcfLastData, uint8_t* keyValue, int32_t* moreBytes)
671{
Chia-chi Yeh64e69e82009-08-06 02:28:24 +0800672 AES_KEY key;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800673 int32_t len = DRM_TWO_AES_BLOCK_LEN;
674
675 if (NULL == pDcfLastData || NULL == keyValue)
676 return FALSE;
677
Chia-chi Yeh64e69e82009-08-06 02:28:24 +0800678 AES_set_decrypt_key(keyValue, DRM_KEY_LEN * 8, &key);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800679
Chia-chi Yeh64e69e82009-08-06 02:28:24 +0800680 if (drm_aesDecBuffer(pDcfLastData, &len, &key) < 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681 return FALSE;
682
683 drm_discardPaddingByte(pDcfLastData, &len);
684
685 *moreBytes = DRM_TWO_AES_BLOCK_LEN - len;
686
687 return TRUE;
688}