29 #define BASE64_TABLE_MAX 122
33 static const int b64table[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
34 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
35 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
36 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
37 -1, -1, -1, 62, -1, -1, -1, 63, 52, 53,
38 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
39 -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
40 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
41 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
42 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
43 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
44 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
54 static inline int GetBase64Value(uint8_t c)
60 val = b64table[(int) c];
75 if (GetBase64Value(encoded_byte) < 0 && encoded_byte !=
'=') {
91 ascii[0] = (uint8_t) (b64[0] << 2) | (b64[1] >> 4);
92 ascii[1] = (uint8_t) (b64[1] << 4) | (b64[2] >> 2);
93 ascii[2] = (uint8_t) (b64[2] << 6) | (b64[3]);
110 uint32_t *consumed_bytes, uint32_t *decoded_bytes,
Base64Mode mode)
113 uint32_t
padding = 0, bbidx = 0, sp = 0, leading_sp = 0;
114 uint8_t *dptr = dest;
121 for (uint32_t i = 0; i <
len; i++) {
123 val = GetBase64Value(
src[i]);
147 b64[bbidx++] = (val > 0 ? (uint8_t)val : 0);
154 if (dest_size < *decoded_bytes + numDecoded_blk) {
161 DecodeBase64Block(dptr, b64);
162 dptr += numDecoded_blk;
163 *decoded_bytes += numDecoded_blk;
170 memset(&b64, 0,
sizeof(b64));
178 if (dest_size < *decoded_bytes + numDecoded_blk) {
186 if (dest_size - *decoded_bytes < 3)
188 *decoded_bytes += numDecoded_blk;
189 DecodeBase64Block(dptr, b64);
190 *consumed_bytes += bbidx;
197 DecodeBase64Block(dptr, b64);
200 if (*decoded_bytes == 0) {
204 *consumed_bytes += leading_sp;
210 #define TEST_RFC2045(src, fin_str, dest_size, exp_decoded, exp_consumed, ecode) \
212 uint32_t consumed_bytes = 0, num_decoded = 0; \
213 uint8_t dst[dest_size]; \
214 Base64Ecode code = DecodeBase64(dst, dest_size, (const uint8_t *)src, strlen(src), \
215 &consumed_bytes, &num_decoded, BASE64_MODE_RFC2045); \
216 FAIL_IF(code != ecode); \
217 FAIL_IF(memcmp(dst, fin_str, strlen(fin_str)) != 0); \
218 FAIL_IF(num_decoded != exp_decoded); \
219 FAIL_IF(consumed_bytes != exp_consumed); \
222 #define TEST_RFC4648(src, fin_str, dest_size, exp_decoded, exp_consumed, ecode) \
224 uint32_t consumed_bytes = 0, num_decoded = 0; \
225 uint8_t dst[dest_size]; \
226 Base64Ecode code = DecodeBase64(dst, dest_size, (const uint8_t *)src, strlen(src), \
227 &consumed_bytes, &num_decoded, BASE64_MODE_RFC4648); \
228 FAIL_IF(code != ecode); \
229 FAIL_IF(memcmp(dst, fin_str, strlen(fin_str)) != 0); \
230 FAIL_IF(num_decoded != exp_decoded); \
231 FAIL_IF(consumed_bytes != exp_consumed); \
234 static int B64DecodeCompleteString(
void)
239 const char *
src =
"SGVsbG8gV29ybGR6";
240 const char *fin_str =
"Hello Worldz";
245 static int B64DecodeInCompleteString(
void)
250 const char *
src =
"SGVsbG8gV29ybGR";
251 const char *fin_str =
"Hello Wor";
256 static int B64DecodeCompleteStringWSp(
void)
262 const char *
src =
"SGVs bG8 gV29y bGQ=";
263 const char *fin_str =
"Hello World";
268 static int B64DecodeInCompleteStringWSp(
void)
275 const char *
src =
"SGVs bG8 gV29y bGQ";
276 const char *fin_str =
"Hello Wor";
282 static int B64DecodeStringBiggerThanBuffer(
void)
288 const char *
src =
"SGVs bG8 gV29y bGQ=";
289 const char *fin_str =
"Hello Wor";
295 static int B64DecodeStringEndingSpaces(
void)
297 const char *
src =
"0YPhA d H";
298 uint32_t consumed_bytes = 0, num_decoded = 0;
308 static int B64TestVectorsRFC2045(
void)
310 const char *src1 =
"";
311 const char *fin_str1 =
"";
313 const char *src2 =
"Zg==";
314 const char *fin_str2 =
"f";
316 const char *src3 =
"Zm8=";
317 const char *fin_str3 =
"fo";
319 const char *src4 =
"Zm9v";
320 const char *fin_str4 =
"foo";
322 const char *src5 =
"Zm9vYg==";
323 const char *fin_str5 =
"foob";
325 const char *src6 =
"Zm9vYmE=";
326 const char *fin_str6 =
"fooba";
328 const char *src7 =
"Zm9vYmFy";
329 const char *fin_str7 =
"foobar";
331 const char *src8 =
"Zm 9v Ym Fy";
332 const char *fin_str8 =
"foobar";
334 const char *src9 =
"Zm$9vYm.Fy";
335 const char *fin_str9 =
"foobar";
337 const char *src10 =
"Y21Wd2IzSjBaVzFoYVd4bWNtRjFaRUJoZEc4dVoyOTJMbUYxOmpqcHh4b3Rhb2w%5";
338 const char *fin_str10 =
"cmVwb3J0ZW1haWxmcmF1ZEBhdG8uZ292LmF1:jjpxxotaol9";
349 TEST_RFC2045(src10, fin_str10, strlen(fin_str10) + 2, strlen(fin_str10), strlen(src10),
354 static int B64TestVectorsRFC4648(
void)
356 const char *src1 =
"";
357 const char *fin_str1 =
"";
359 const char *src2 =
"Zg==";
360 const char *fin_str2 =
"f";
362 const char *src3 =
"Zm8=";
363 const char *fin_str3 =
"fo";
365 const char *src4 =
"Zm9v";
366 const char *fin_str4 =
"foo";
368 const char *src5 =
"Zm9vYg==";
369 const char *fin_str5 =
"foob";
371 const char *src6 =
"Zm9vYmE=";
372 const char *fin_str6 =
"fooba";
374 const char *src7 =
"Zm9vYmFy";
375 const char *fin_str7 =
"foobar";
377 const char *src8 =
"Zm 9v Ym Fy";
378 const char *fin_str8 =
"f";
380 const char *src9 =
"Zm$9vYm.Fy";
381 const char *fin_str9 =
"f";
383 const char *src10 =
"Y21Wd2IzSjBaVzFoYVd4bWNtRjFaRUJoZEc4dVoyOTJMbUYxOmpqcHh4b3Rhb2w%3D";
384 const char *fin_str10 =
"cmVwb3J0ZW1haWxmcmF1ZEBhdG8uZ292LmF1:jjpxxotaol";
395 TEST_RFC4648(src10, fin_str10, strlen(fin_str10) + 1, strlen(fin_str10), strlen(src10) - 3,
402 UtRegisterTest(
"B64DecodeCompleteStringWSp", B64DecodeCompleteStringWSp);
403 UtRegisterTest(
"B64DecodeInCompleteStringWSp", B64DecodeInCompleteStringWSp);
404 UtRegisterTest(
"B64DecodeCompleteString", B64DecodeCompleteString);
405 UtRegisterTest(
"B64DecodeInCompleteString", B64DecodeInCompleteString);
406 UtRegisterTest(
"B64DecodeStringBiggerThanBuffer", B64DecodeStringBiggerThanBuffer);
407 UtRegisterTest(
"B64DecodeStringEndingSpaces", B64DecodeStringEndingSpaces);