Home | History | Annotate | Download | only in objmng
      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 
     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 
     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 
     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 */
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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