2 * RFC 1521 base64 encoding/decoding
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * This file is part of mbed TLS (https://tls.mbed.org)
22 #if !defined(MBEDTLS_CONFIG_FILE)
23 #include "mbedtls/config.h"
25 #include MBEDTLS_CONFIG_FILE
28 #if defined(MBEDTLS_BASE64_C)
30 #include "mbedtls/base64.h"
34 #if defined(MBEDTLS_SELF_TEST)
36 #if defined(MBEDTLS_PLATFORM_C)
37 #include "mbedtls/platform.h"
40 #define mbedtls_printf printf
41 #endif /* MBEDTLS_PLATFORM_C */
42 #endif /* MBEDTLS_SELF_TEST */
44 static const unsigned char base64_enc_map
[64] =
46 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
47 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
48 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
49 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
50 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
51 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
55 static const unsigned char base64_dec_map
[128] =
57 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
58 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
59 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
60 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
61 127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
62 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
63 127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
64 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
65 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
66 25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
67 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
68 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
69 49, 50, 51, 127, 127, 127, 127, 127
72 #define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
75 * Encode a buffer into base64 format
77 int mbedtls_base64_encode( unsigned char *dst
, size_t dlen
, size_t *olen
,
78 const unsigned char *src
, size_t slen
)
90 n
= slen
/ 3 + ( slen
% 3 != 0 );
92 if( n
> ( BASE64_SIZE_T_MAX
- 1 ) / 4 )
94 *olen
= BASE64_SIZE_T_MAX
;
95 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
);
103 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
);
106 n
= ( slen
/ 3 ) * 3;
108 for( i
= 0, p
= dst
; i
< n
; i
+= 3 )
114 *p
++ = base64_enc_map
[(C1
>> 2) & 0x3F];
115 *p
++ = base64_enc_map
[(((C1
& 3) << 4) + (C2
>> 4)) & 0x3F];
116 *p
++ = base64_enc_map
[(((C2
& 15) << 2) + (C3
>> 6)) & 0x3F];
117 *p
++ = base64_enc_map
[C3
& 0x3F];
123 C2
= ( ( i
+ 1 ) < slen
) ? *src
++ : 0;
125 *p
++ = base64_enc_map
[(C1
>> 2) & 0x3F];
126 *p
++ = base64_enc_map
[(((C1
& 3) << 4) + (C2
>> 4)) & 0x3F];
128 if( ( i
+ 1 ) < slen
)
129 *p
++ = base64_enc_map
[((C2
& 15) << 2) & 0x3F];
142 * Decode a base64-formatted buffer
144 int mbedtls_base64_decode( unsigned char *dst
, size_t dlen
, size_t *olen
,
145 const unsigned char *src
, size_t slen
)
151 /* First pass: check for validity and get output length */
152 for( i
= n
= j
= 0; i
< slen
; i
++ )
154 /* Skip spaces before checking for EOL */
156 while( i
< slen
&& src
[i
] == ' ' )
162 /* Spaces at end of buffer are OK */
166 if( ( slen
- i
) >= 2 &&
167 src
[i
] == '\r' && src
[i
+ 1] == '\n' )
173 /* Space inside a line is an error */
175 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER
);
177 if( src
[i
] == '=' && ++j
> 2 )
178 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER
);
180 if( src
[i
] > 127 || base64_dec_map
[src
[i
]] == 127 )
181 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER
);
183 if( base64_dec_map
[src
[i
]] < 64 && j
!= 0 )
184 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER
);
195 n
= ( ( n
* 6 ) + 7 ) >> 3;
198 if( dst
== NULL
|| dlen
< n
)
201 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
);
204 for( j
= 3, n
= x
= 0, p
= dst
; i
> 0; i
--, src
++ )
206 if( *src
== '\r' || *src
== '\n' || *src
== ' ' )
209 j
-= ( base64_dec_map
[*src
] == 64 );
210 x
= ( x
<< 6 ) | ( base64_dec_map
[*src
] & 0x3F );
215 if( j
> 0 ) *p
++ = (unsigned char)( x
>> 16 );
216 if( j
> 1 ) *p
++ = (unsigned char)( x
>> 8 );
217 if( j
> 2 ) *p
++ = (unsigned char)( x
);
226 #if defined(MBEDTLS_SELF_TEST)
228 static const unsigned char base64_test_dec
[64] =
230 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
231 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
232 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
233 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
234 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
235 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
236 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
237 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
240 static const unsigned char base64_test_enc
[] =
241 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
242 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
247 int mbedtls_base64_self_test( int verbose
)
250 const unsigned char *src
;
251 unsigned char buffer
[128];
254 mbedtls_printf( " Base64 encoding test: " );
256 src
= base64_test_dec
;
258 if( mbedtls_base64_encode( buffer
, sizeof( buffer
), &len
, src
, 64 ) != 0 ||
259 memcmp( base64_test_enc
, buffer
, 88 ) != 0 )
262 mbedtls_printf( "failed\n" );
268 mbedtls_printf( "passed\n Base64 decoding test: " );
270 src
= base64_test_enc
;
272 if( mbedtls_base64_decode( buffer
, sizeof( buffer
), &len
, src
, 88 ) != 0 ||
273 memcmp( base64_test_dec
, buffer
, 64 ) != 0 )
276 mbedtls_printf( "failed\n" );
282 mbedtls_printf( "passed\n\n" );
287 #endif /* MBEDTLS_SELF_TEST */
289 #endif /* MBEDTLS_BASE64_C */