1 /**
2 * Copyright (C) 2022 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 #include <string.h>
17 #include <ImsMediaBinaryFormat.h>
18 #include <ImsMediaTrace.h>
19
20 // Default value for non-printable characters
21 #define NP 0xFF
22 // Carriage-Return (\r)
23 #define CR 0x0D
24 // Line-Feed (\n)
25 #define LF 0x0A
26 // Padding character for Base64
27 #define BASE64_PAD '='
28
29 // Constant table for Base64 value encoding / decoding
30 static const char BASE64_ENCODING_TABLE[] =
31 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
32 static const uint8_t BASE64_DECODING_TABLE[] = {
33 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 0 ~ 9
34 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 10 ~ 19
35 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 20 ~ 29
36 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 30 ~ 39
37 NP, NP, NP, 62, NP, NP, NP, 63, 52, 53, // 40 ~ 49
38 54, 55, 56, 57, 58, 59, 60, 61, NP, NP, // 50 ~ 59
39 NP, NP, NP, NP, NP, 0, 1, 2, 3, 4, // 60 ~ 69
40 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 70 ~ 79
41 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 80 ~ 89
42 25, NP, NP, NP, NP, NP, NP, 26, 27, 28, // 90 ~ 99
43 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // 100 ~ 109
44 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // 110 ~ 119
45 49, 50, 51, NP, NP, NP, NP, NP, NP, NP, // 120 ~ 129
46 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 130 ~ 139
47 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 140 ~ 149
48 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 150 ~ 159
49 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 160 ~ 169
50 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 170 ~ 179
51 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 180 ~ 189
52 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 190 ~ 199
53 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 200 ~ 209
54 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 210 ~ 219
55 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 220 ~ 229
56 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 230 ~ 239
57 NP, NP, NP, NP, NP, NP, NP, NP, NP, NP, // 240 ~ 249
58 NP, NP, NP, NP, NP, NP // 250 ~ 256
59 };
60
BinaryToBase16(char * pszDst,uint32_t nDstBuffSize,uint8_t * pbSrc,uint32_t nSrcSize)61 static bool BinaryToBase16(char* pszDst, uint32_t nDstBuffSize, uint8_t* pbSrc, uint32_t nSrcSize)
62 {
63 if (((nDstBuffSize - 1) >> 1) < nSrcSize)
64 return false;
65
66 if (nSrcSize > 0)
67 {
68 uint32_t m, n;
69
70 for (m = 0, n = 0; m < nSrcSize; m++)
71 {
72 int8_t c, h, l;
73
74 c = (int8_t)pbSrc[m];
75
76 h = (c >> 4) & 0x0F;
77 l = c & 0x0F;
78
79 if (h < 10)
80 h += '0';
81 else
82 h += 'A' - 10;
83 if (l < 10)
84 l += '0';
85 else
86 l += 'A' - 10;
87
88 pszDst[n++] = h;
89 pszDst[n++] = l;
90 }
91 pszDst[n] = 0;
92 }
93
94 return true;
95 }
96
Base16ToBinary(uint8_t * pbDst,uint32_t * pnDstSize,uint32_t nDstBuffSize,char * pszSrc)97 static bool Base16ToBinary(uint8_t* pbDst, uint32_t* pnDstSize, uint32_t nDstBuffSize, char* pszSrc)
98 {
99 uint32_t nSrcLen;
100 uint32_t src_pos, dst_pos;
101
102 nSrcLen = strlen(pszSrc);
103 if (nSrcLen & 0x1)
104 nSrcLen++;
105 if (nDstBuffSize < (nSrcLen >> 1))
106 return false;
107 for (src_pos = 0, dst_pos = 0; src_pos < nSrcLen; src_pos += 2, dst_pos++)
108 {
109 char h, l;
110
111 h = pszSrc[src_pos];
112 l = pszSrc[src_pos + 1];
113
114 if (h >= '0' && h <= '9')
115 h = h - '0';
116 else if (h >= 'a' && h <= 'f')
117 h = h - 'a' + 10;
118 else if (h >= 'A' && h <= 'F')
119 h = h - 'A' + 10;
120
121 if (l >= '0' && l <= '9')
122 l = l - '0';
123 else if (l >= 'a' && l <= 'f')
124 l = l - 'a' + 10;
125 else if (l >= 'A' && l <= 'F')
126 l = l - 'A' + 10;
127
128 pbDst[dst_pos] = (h << 4) | l;
129 }
130
131 *pnDstSize = dst_pos;
132
133 return true;
134 }
135
BinaryToBase64(char * pszDst,uint32_t nDstBuffSize,const uint8_t * pbSrc,uint32_t nSrcSize)136 static bool BinaryToBase64(
137 char* pszDst, uint32_t nDstBuffSize, const uint8_t* pbSrc, uint32_t nSrcSize)
138 {
139 char* pEncBuffer = pszDst;
140
141 if ((nDstBuffSize - 1) < ((nSrcSize + 2) / 3 * 4))
142 return false;
143
144 for (int32_t nPos = 0; nPos < nSrcSize; ++nPos)
145 {
146 uint8_t c6bit = (pbSrc[nPos] >> 2) & 0x3F;
147 (*pEncBuffer) = BASE64_ENCODING_TABLE[(uint8_t)c6bit];
148 pEncBuffer++;
149
150 c6bit = (pbSrc[nPos] << 4) & 0x3F;
151
152 if (++nPos < nSrcSize)
153 c6bit |= (pbSrc[nPos] >> 4) & 0x0F;
154
155 (*pEncBuffer) = BASE64_ENCODING_TABLE[(uint8_t)c6bit];
156 pEncBuffer++;
157
158 if (nPos < nSrcSize)
159 {
160 c6bit = (pbSrc[nPos] << 2) & 0x3F;
161
162 if (++nPos < nSrcSize)
163 c6bit |= (pbSrc[nPos] >> 6) & 0x03;
164
165 (*pEncBuffer) = BASE64_ENCODING_TABLE[(uint8_t)c6bit];
166 pEncBuffer++;
167 }
168 else
169 {
170 ++nPos;
171 (*pEncBuffer) = BASE64_PAD;
172 pEncBuffer++;
173 }
174
175 if (nPos < nSrcSize)
176 {
177 c6bit = pbSrc[nPos] & 0x3F;
178 (*pEncBuffer) = BASE64_ENCODING_TABLE[(uint8_t)c6bit];
179 pEncBuffer++;
180 }
181 else
182 {
183 (*pEncBuffer) = BASE64_PAD;
184 pEncBuffer++;
185 }
186 }
187
188 (*pEncBuffer) = 0x00;
189
190 return true;
191 }
192
Base64ToBinary(uint8_t * pbDst,uint32_t * pnDstSize,uint32_t nDstBuffSize,char * pszSrc)193 static bool Base64ToBinary(uint8_t* pbDst, uint32_t* pnDstSize, uint32_t nDstBuffSize, char* pszSrc)
194 {
195 uint8_t* pDecBuffer = pbDst;
196 uint32_t nSrcLen;
197
198 nSrcLen = strlen(pszSrc);
199
200 if (nDstBuffSize < ((nSrcLen >> 2) * 3 + (nSrcLen & 0x3)))
201 return false;
202
203 for (int32_t nPos = 0; nPos < nSrcLen; ++nPos)
204 {
205 if (pszSrc[nPos] == LF)
206 nPos += 1;
207 if (pszSrc[nPos] == CR)
208 nPos += 2;
209
210 uint8_t c8bit = BASE64_DECODING_TABLE[(uint8_t)pszSrc[nPos]];
211 ++nPos;
212
213 if (pszSrc[nPos] == LF)
214 nPos += 1;
215 if (pszSrc[nPos] == CR)
216 nPos += 2;
217
218 uint8_t c8bit1 = BASE64_DECODING_TABLE[(uint8_t)pszSrc[nPos]];
219 c8bit = (c8bit << 2) | ((c8bit1 >> 4) & 0x03);
220 (*pDecBuffer) = c8bit;
221 pDecBuffer++;
222
223 if (++nPos < nSrcLen)
224 {
225 if (pszSrc[nPos] == LF)
226 nPos += 1;
227 if (pszSrc[nPos] == CR)
228 nPos += 2;
229
230 c8bit = pszSrc[nPos];
231
232 if (c8bit == BASE64_PAD)
233 break;
234
235 c8bit = BASE64_DECODING_TABLE[(uint8_t)pszSrc[nPos]];
236 c8bit1 = ((c8bit1 << 4) & 0xF0) | ((c8bit >> 2) & 0x0F);
237 (*pDecBuffer) = c8bit1;
238 pDecBuffer++;
239 }
240
241 if (++nPos < nSrcLen)
242 {
243 if (pszSrc[nPos] == LF)
244 nPos += 1;
245 if (pszSrc[nPos] == CR)
246 nPos += 2;
247
248 c8bit1 = pszSrc[nPos];
249
250 if (c8bit1 == BASE64_PAD)
251 break;
252
253 c8bit1 = BASE64_DECODING_TABLE[(uint8_t)pszSrc[nPos]];
254 c8bit = ((c8bit << 6) & 0xC0) | c8bit1;
255 (*pDecBuffer) = c8bit;
256 pDecBuffer++;
257 }
258 }
259
260 *pnDstSize = (uint32_t)(pDecBuffer - pbDst);
261
262 return true;
263 }
264
BinaryToBase00(char * pszDst,uint32_t nDstBuffSize,uint8_t * pbSrc,uint32_t nSrcSize,uint32_t eFormat)265 bool ImsMediaBinaryFormat::BinaryToBase00(
266 char* pszDst, uint32_t nDstBuffSize, uint8_t* pbSrc, uint32_t nSrcSize, uint32_t eFormat)
267 {
268 switch (eFormat)
269 {
270 case BINARY_FORMAT_BASE16:
271 return BinaryToBase16(pszDst, nDstBuffSize, pbSrc, nSrcSize);
272 case BINARY_FORMAT_BASE64:
273 return BinaryToBase64(pszDst, nDstBuffSize, pbSrc, nSrcSize);
274 case BINARY_FORMAT_BASE32:
275 default:
276 IMLOGE1("[BinaryToBase00] not supported binary format %d", eFormat);
277 return false;
278 }
279 }
280
Base00ToBinary(uint8_t * pbDst,uint32_t * pnDstSize,uint32_t nDstBuffSize,char * pszSrc,uint32_t eFormat)281 bool ImsMediaBinaryFormat::Base00ToBinary(
282 uint8_t* pbDst, uint32_t* pnDstSize, uint32_t nDstBuffSize, char* pszSrc, uint32_t eFormat)
283 {
284 switch (eFormat)
285 {
286 case BINARY_FORMAT_BASE16:
287 return Base16ToBinary(pbDst, pnDstSize, nDstBuffSize, pszSrc);
288 case BINARY_FORMAT_BASE64:
289 return Base64ToBinary(pbDst, pnDstSize, nDstBuffSize, pszSrc);
290 case BINARY_FORMAT_BASE32:
291 default:
292 IMLOGE1("[Base00ToBinary] not supported binary format %d", eFormat);
293 return false;
294 }
295 }
296