• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
drm_getString(uint8_t * string,int32_t len,int32_t handle)22 static 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 
drm_putString(uint8_t * string,int32_t handle)37 static 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 
drm_writeToUidTxt(uint8_t * Uid,int32_t * id)50 static 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 */
drm_readFromUidTxt(uint8_t * Uid,int32_t * id,int32_t option)151 int32_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 
drm_acquireId(uint8_t * uid,int32_t * id)241 static 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 
drm_writeOrReadInfo(int32_t id,T_DRM_Rights * Ro,int32_t * RoAmount,int32_t option)251 int32_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 
drm_appendRightsInfo(T_DRM_Rights * rights)354 int32_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 
drm_getMaxIdFromUidTxt()380 int32_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 
drm_removeIdInfoFile(int32_t id)417 int32_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 
drm_updateUidTxtWhenDelete(int32_t id)443 int32_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 
drm_getKey(uint8_t * uid,uint8_t * KeyValue)532 int32_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 
drm_discardPaddingByte(uint8_t * decryptedBuf,int32_t * decryptedBufLen)558 void 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 
drm_aesDecBuffer(uint8_t * Buffer,int32_t * BufferLen,AES_KEY * key)576 int32_t drm_aesDecBuffer(uint8_t * Buffer, int32_t * BufferLen, AES_KEY *key)
577 {
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 */
599         AES_decrypt((dbuf + len), (dbuf + len), key);
600 
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 */
623             AES_decrypt((uint8_t *)b2, buf, key);
624 
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 */
642                 AES_decrypt((uint8_t *)b3, (uint8_t *)b3, key);
643 
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 
drm_updateDcfDataLen(uint8_t * pDcfLastData,uint8_t * keyValue,int32_t * moreBytes)670 int32_t drm_updateDcfDataLen(uint8_t* pDcfLastData, uint8_t* keyValue, int32_t* moreBytes)
671 {
672     AES_KEY key;
673     int32_t len = DRM_TWO_AES_BLOCK_LEN;
674 
675     if (NULL == pDcfLastData || NULL == keyValue)
676         return FALSE;
677 
678     AES_set_decrypt_key(keyValue, DRM_KEY_LEN * 8, &key);
679 
680     if (drm_aesDecBuffer(pDcfLastData, &len, &key) < 0)
681         return FALSE;
682 
683     drm_discardPaddingByte(pDcfLastData, &len);
684 
685     *moreBytes = DRM_TWO_AES_BLOCK_LEN - len;
686 
687     return TRUE;
688 }
689