base64.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*
  2. * Copyright (C) 2015-2018 Alibaba Group Holding Limited
  3. */
  4. #if !defined(MBEDTLS_CONFIG_FILE)
  5. #include "mbedtls/config.h"
  6. #else
  7. #include MBEDTLS_CONFIG_FILE
  8. #endif
  9. #if defined(MBEDTLS_BASE64_C)
  10. #include "mbedtls/base64.h"
  11. #include <stdint.h>
  12. #if defined(MBEDTLS_SELF_TEST)
  13. #include <string.h>
  14. #if defined(MBEDTLS_PLATFORM_C)
  15. #include "mbedtls/platform.h"
  16. #else
  17. #include <stdio.h>
  18. #include "mbedtls/debug.h"
  19. #define mbedtls_printf tls_info
  20. #endif /* MBEDTLS_PLATFORM_C */
  21. #endif /* MBEDTLS_SELF_TEST */
  22. static const unsigned char base64_enc_map[64] =
  23. {
  24. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
  25. 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
  26. 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
  27. 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
  28. 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
  29. 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
  30. '8', '9', '+', '/'
  31. };
  32. static const unsigned char base64_dec_map[128] =
  33. {
  34. 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
  35. 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
  36. 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
  37. 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
  38. 127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
  39. 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
  40. 127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
  41. 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  42. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  43. 25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
  44. 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
  45. 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
  46. 49, 50, 51, 127, 127, 127, 127, 127
  47. };
  48. #define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
  49. /*
  50. * Encode a buffer into base64 format
  51. */
  52. int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
  53. const unsigned char *src, size_t slen )
  54. {
  55. size_t i, n;
  56. int C1, C2, C3;
  57. unsigned char *p;
  58. if( slen == 0 )
  59. {
  60. *olen = 0;
  61. return( 0 );
  62. }
  63. n = slen / 3 + ( slen % 3 != 0 );
  64. if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 )
  65. {
  66. *olen = BASE64_SIZE_T_MAX;
  67. return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
  68. }
  69. n *= 4;
  70. if( ( dlen < n + 1 ) || ( NULL == dst ) )
  71. {
  72. *olen = n + 1;
  73. return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
  74. }
  75. n = ( slen / 3 ) * 3;
  76. for( i = 0, p = dst; i < n; i += 3 )
  77. {
  78. C1 = *src++;
  79. C2 = *src++;
  80. C3 = *src++;
  81. *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
  82. *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
  83. *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
  84. *p++ = base64_enc_map[C3 & 0x3F];
  85. }
  86. if( i < slen )
  87. {
  88. C1 = *src++;
  89. C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
  90. *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
  91. *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
  92. if( ( i + 1 ) < slen )
  93. *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
  94. else *p++ = '=';
  95. *p++ = '=';
  96. }
  97. *olen = p - dst;
  98. *p = 0;
  99. return( 0 );
  100. }
  101. /*
  102. * Decode a base64-formatted buffer
  103. */
  104. int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
  105. const unsigned char *src, size_t slen )
  106. {
  107. size_t i, n;
  108. uint32_t j, x;
  109. unsigned char *p;
  110. /* First pass: check for validity and get output length */
  111. for( i = n = j = 0; i < slen; i++ )
  112. {
  113. /* Skip spaces before checking for EOL */
  114. x = 0;
  115. while( i < slen && src[i] == ' ' )
  116. {
  117. ++i;
  118. ++x;
  119. }
  120. /* Spaces at end of buffer are OK */
  121. if( i == slen )
  122. break;
  123. if( ( slen - i ) >= 2 &&
  124. src[i] == '\r' && src[i + 1] == '\n' )
  125. continue;
  126. if( src[i] == '\n' )
  127. continue;
  128. /* Space inside a line is an error */
  129. if( x != 0 )
  130. return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
  131. if( src[i] == '=' && ++j > 2 )
  132. return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
  133. if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
  134. return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
  135. if( base64_dec_map[src[i]] < 64 && j != 0 )
  136. return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
  137. n++;
  138. }
  139. if( n == 0 )
  140. {
  141. *olen = 0;
  142. return( 0 );
  143. }
  144. /* The following expression is to calculate the following formula without
  145. * risk of integer overflow in n:
  146. * n = ( ( n * 6 ) + 7 ) >> 3;
  147. */
  148. n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 );
  149. n -= j;
  150. if( dst == NULL || dlen < n )
  151. {
  152. *olen = n;
  153. return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
  154. }
  155. for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
  156. {
  157. if( *src == '\r' || *src == '\n' || *src == ' ' )
  158. continue;
  159. j -= ( base64_dec_map[*src] == 64 );
  160. x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
  161. if( ++n == 4 )
  162. {
  163. n = 0;
  164. if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
  165. if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
  166. if( j > 2 ) *p++ = (unsigned char)( x );
  167. }
  168. }
  169. *olen = p - dst;
  170. return( 0 );
  171. }
  172. #if defined(MBEDTLS_SELF_TEST)
  173. static const unsigned char base64_test_dec[64] =
  174. {
  175. 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
  176. 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
  177. 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
  178. 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
  179. 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
  180. 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
  181. 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
  182. 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
  183. };
  184. static const unsigned char base64_test_enc[] =
  185. "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
  186. "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
  187. /*
  188. * Checkup routine
  189. */
  190. int mbedtls_base64_self_test( int verbose )
  191. {
  192. size_t len;
  193. const unsigned char *src;
  194. unsigned char buffer[128];
  195. if( verbose != 0 )
  196. mbedtls_printf( " Base64 encoding test: " );
  197. src = base64_test_dec;
  198. if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 ||
  199. memcmp( base64_test_enc, buffer, 88 ) != 0 )
  200. {
  201. if( verbose != 0 )
  202. mbedtls_printf( "failed\n" );
  203. return( 1 );
  204. }
  205. if( verbose != 0 )
  206. mbedtls_printf( "passed\n Base64 decoding test: " );
  207. src = base64_test_enc;
  208. if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 ||
  209. memcmp( base64_test_dec, buffer, 64 ) != 0 )
  210. {
  211. if( verbose != 0 )
  212. mbedtls_printf( "failed\n" );
  213. return( 1 );
  214. }
  215. if( verbose != 0 )
  216. mbedtls_printf( "passed\n\n" );
  217. return( 0 );
  218. }
  219. #endif /* MBEDTLS_SELF_TEST */
  220. #endif /* MBEDTLS_BASE64_C */