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 <objmng/drm_decoder.h> 18 19/* global variables */ 20static const uint8_t * base64_alphabet = (const uint8_t *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 21 22#define SKIP_CRLF(p) while('\r' == *(p) || '\n' == *(p)) \ 23 p++ 24 25static int8_t get_alphabet_index(int8_t ch) 26{ 27 uint8_t * tmp; 28 29 if ('=' == ch) 30 return 64; 31 32 tmp = (uint8_t *)strchr((const char *)base64_alphabet, ch); 33 if (NULL == tmp) 34 return -1; 35 36 return (int8_t)(tmp - base64_alphabet); 37} 38 39/* See drm_decoder.h */ 40int32_t drm_decodeBase64(uint8_t * dest, int32_t destLen, uint8_t * src, int32_t * srcLen) 41{ 42 int32_t maxDestSize, i, maxGroup; 43 uint8_t *pDest, *pSrc; 44 int8_t tpChar; 45 46 if (NULL == src || NULL == srcLen || *srcLen <= 0 || destLen < 0) 47 return -1; 48 49 maxDestSize = (*srcLen) * 3/4; 50 if (NULL == dest || 0 == destLen) 51 return maxDestSize; 52 53 if (destLen < maxDestSize) 54 maxDestSize = destLen; 55 maxGroup = maxDestSize/3; 56 57 pDest = dest; /* start to decode src to dest */ 58 pSrc = src; 59 for (i = 0; i < maxGroup && *srcLen - (pSrc - src) >= 4; i++) { 60 SKIP_CRLF(pSrc); 61 if (pSrc - src >= *srcLen) 62 break; 63 tpChar = get_alphabet_index(*pSrc); /* to first byte */ 64 if (-1 == tpChar || 64 == tpChar) 65 return -1; 66 pDest[0] = tpChar << 2; 67 pSrc++; 68 SKIP_CRLF(pSrc); 69 tpChar = get_alphabet_index(*pSrc); 70 if (-1 == tpChar || 64 == tpChar) 71 return -1; 72 pDest[0] |= (tpChar >> 4); 73 pDest[1] = tpChar << 4; /* to second byte */ 74 pSrc++; 75 SKIP_CRLF(pSrc); 76 tpChar = get_alphabet_index(*pSrc); 77 if (-1 == tpChar) 78 return -1; 79 if (64 == tpChar) /* end */ 80 return pDest - dest + 1; 81 pDest[1] |= (tpChar >> 2); 82 pDest[2] = tpChar << 6; /* to third byte */ 83 pSrc++; 84 SKIP_CRLF(pSrc); 85 tpChar = get_alphabet_index(*pSrc); 86 if (-1 == tpChar) 87 return -1; 88 if (64 == tpChar) /* end */ 89 return pDest - dest + 2; 90 pDest[2] |= tpChar; 91 pDest += 3; 92 pSrc++; 93 } 94 *srcLen = pSrc - src; 95 return pDest - dest; 96} 97