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
73 * Encode a buffer into base64 format
75 int mbedtls_base64_encode( unsigned char *dst
, size_t dlen
, size_t *olen
,
76 const unsigned char *src
, size_t slen
)
88 n
= ( slen
<< 3 ) / 6;
90 switch( ( slen
<< 3 ) - ( n
* 6 ) )
92 case 2: n
+= 3; break;
93 case 4: n
+= 2; break;
100 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
);
103 n
= ( slen
/ 3 ) * 3;
105 for( i
= 0, p
= dst
; i
< n
; i
+= 3 )
111 *p
++ = base64_enc_map
[(C1
>> 2) & 0x3F];
112 *p
++ = base64_enc_map
[(((C1
& 3) << 4) + (C2
>> 4)) & 0x3F];
113 *p
++ = base64_enc_map
[(((C2
& 15) << 2) + (C3
>> 6)) & 0x3F];
114 *p
++ = base64_enc_map
[C3
& 0x3F];
120 C2
= ( ( i
+ 1 ) < slen
) ? *src
++ : 0;
122 *p
++ = base64_enc_map
[(C1
>> 2) & 0x3F];
123 *p
++ = base64_enc_map
[(((C1
& 3) << 4) + (C2
>> 4)) & 0x3F];
125 if( ( i
+ 1 ) < slen
)
126 *p
++ = base64_enc_map
[((C2
& 15) << 2) & 0x3F];
139 * Decode a base64-formatted buffer
141 int mbedtls_base64_decode( unsigned char *dst
, size_t dlen
, size_t *olen
,
142 const unsigned char *src
, size_t slen
)
148 /* First pass: check for validity and get output length */
149 for( i
= n
= j
= 0; i
< slen
; i
++ )
151 /* Skip spaces before checking for EOL */
153 while( i
< slen
&& src
[i
] == ' ' )
159 /* Spaces at end of buffer are OK */
163 if( ( slen
- i
) >= 2 &&
164 src
[i
] == '\r' && src
[i
+ 1] == '\n' )
170 /* Space inside a line is an error */
172 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER
);
174 if( src
[i
] == '=' && ++j
> 2 )
175 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER
);
177 if( src
[i
] > 127 || base64_dec_map
[src
[i
]] == 127 )
178 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER
);
180 if( base64_dec_map
[src
[i
]] < 64 && j
!= 0 )
181 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER
);
189 n
= ( ( n
* 6 ) + 7 ) >> 3;
192 if( dst
== NULL
|| dlen
< n
)
195 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
);
198 for( j
= 3, n
= x
= 0, p
= dst
; i
> 0; i
--, src
++ )
200 if( *src
== '\r' || *src
== '\n' || *src
== ' ' )
203 j
-= ( base64_dec_map
[*src
] == 64 );
204 x
= ( x
<< 6 ) | ( base64_dec_map
[*src
] & 0x3F );
209 if( j
> 0 ) *p
++ = (unsigned char)( x
>> 16 );
210 if( j
> 1 ) *p
++ = (unsigned char)( x
>> 8 );
211 if( j
> 2 ) *p
++ = (unsigned char)( x
);
220 #if defined(MBEDTLS_SELF_TEST)
222 static const unsigned char base64_test_dec
[64] =
224 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
225 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
226 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
227 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
228 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
229 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
230 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
231 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
234 static const unsigned char base64_test_enc
[] =
235 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
236 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
241 int mbedtls_base64_self_test( int verbose
)
244 const unsigned char *src
;
245 unsigned char buffer
[128];
248 mbedtls_printf( " Base64 encoding test: " );
250 src
= base64_test_dec
;
252 if( mbedtls_base64_encode( buffer
, sizeof( buffer
), &len
, src
, 64 ) != 0 ||
253 memcmp( base64_test_enc
, buffer
, 88 ) != 0 )
256 mbedtls_printf( "failed\n" );
262 mbedtls_printf( "passed\n Base64 decoding test: " );
264 src
= base64_test_enc
;
266 if( mbedtls_base64_decode( buffer
, sizeof( buffer
), &len
, src
, 88 ) != 0 ||
267 memcmp( base64_test_dec
, buffer
, 64 ) != 0 )
270 mbedtls_printf( "failed\n" );
276 mbedtls_printf( "passed\n\n" );
281 #endif /* MBEDTLS_SELF_TEST */
283 #endif /* MBEDTLS_BASE64_C */