blob: ce95918934f116280a8aebd840f1eecc7e3f6aa7 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1521 base64 encoding/decoding
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
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
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
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.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19
Gilles Peskinedb09ef62020-06-03 01:43:33 +020020#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000021
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022#if defined(MBEDTLS_BASE64_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000023
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000024#include "mbedtls/base64.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000025
Manuel Pégourié-Gonnard93866642015-06-22 19:21:23 +020026#include <stdint.h>
Paul Bakker5c2364c2012-10-01 14:41:15 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_SELF_TEST)
Rich Evans00ab4702015-02-06 13:43:58 +000029#include <string.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000031#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010032#else
Rich Evans00ab4702015-02-06 13:43:58 +000033#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#define mbedtls_printf printf
35#endif /* MBEDTLS_PLATFORM_C */
36#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010037
Paul Bakker5121ce52009-01-03 21:22:43 +000038static const unsigned char base64_enc_map[64] =
39{
40 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
41 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
42 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
43 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
44 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
45 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
46 '8', '9', '+', '/'
47};
48
49static const unsigned char base64_dec_map[128] =
50{
51 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
52 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
53 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
54 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
55 127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
56 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
57 127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
58 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
59 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
60 25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
61 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
62 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
63 49, 50, 51, 127, 127, 127, 127, 127
64};
65
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +010066#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
67
Paul Elliott3e790812021-02-25 12:28:49 +000068/*
Paul Elliott0544d492021-03-01 19:15:43 +000069 * Constant flow conditional assignment to unsigned char
Paul Elliott3e790812021-02-25 12:28:49 +000070*/
Paul Elliott0544d492021-03-01 19:15:43 +000071static void mbedtls_base64_cond_assign_uchar(unsigned char * dest, const unsigned char * const src,
Paul Elliottdadd10d2021-02-05 17:49:23 +000072 unsigned char condition)
73{
74 /* make sure assign is 0 or 1 in a time-constant manner */
75 condition = (condition | (unsigned char)-condition) >> 7;
76
77 *dest = ( *dest ) * ( 1 - condition ) + ( *src ) * condition;
78}
79
80/*
Paul Elliott0544d492021-03-01 19:15:43 +000081 * Constant flow conditional assignment to uint_32
82*/
83static void mbedtls_base64_cond_assign_uint32(uint32_t * dest, const uint32_t src,
84 unsigned char condition)
85{
86 /* make sure assign is 0 or 1 in a time-constant manner */
87 condition = (condition | (unsigned char)-condition) >> 7;
88
89 *dest = ( *dest ) * ( 1 - condition ) + ( src ) * condition;
90}
91
92
93/*
Paul Elliott3e790812021-02-25 12:28:49 +000094 * Constant flow check for equality
Paul Elliottdadd10d2021-02-05 17:49:23 +000095*/
Paul Elliott3e790812021-02-25 12:28:49 +000096static unsigned char mbedtls_base64_eq(size_t in_a, size_t in_b)
Paul Elliottdadd10d2021-02-05 17:49:23 +000097{
Paul Elliott717ba772021-03-01 17:49:42 +000098 size_t difference = in_a ^ in_b;
Paul Elliottdadd10d2021-02-05 17:49:23 +000099
Paul Elliott3e790812021-02-25 12:28:49 +0000100 /* MSVC has a warning about unary minus on unsigned integer types,
101 * but this is well-defined and precisely what we want to do here. */
102#if defined(_MSC_VER)
103#pragma warning( push )
104#pragma warning( disable : 4146 )
105#endif
106
Paul Elliottdadd10d2021-02-05 17:49:23 +0000107 difference |= -difference;
Paul Elliott3e790812021-02-25 12:28:49 +0000108
109#if defined(_MSC_VER)
110#pragma warning( pop )
111#endif
112
Paul Elliott717ba772021-03-01 17:49:42 +0000113 /* cope with the varying size of size_t per platform */
114 difference >>= ( sizeof( difference ) * 8 - 1 );
115
Paul Elliottdadd10d2021-02-05 17:49:23 +0000116 return (unsigned char) ( 1 ^ difference );
117}
118
119/*
Paul Elliott3e790812021-02-25 12:28:49 +0000120 * Constant flow lookup into table.
Paul Elliottdadd10d2021-02-05 17:49:23 +0000121*/
122static unsigned char mbedtls_base64_table_lookup(const unsigned char * const table,
123 const size_t table_size, const size_t table_index)
124{
125 size_t i;
126 unsigned char result = 0;
127
128 for( i = 0; i < table_size; ++i )
129 {
Paul Elliott0544d492021-03-01 19:15:43 +0000130 mbedtls_base64_cond_assign_uchar(&result, &table[i], mbedtls_base64_eq(i, table_index));
Paul Elliottdadd10d2021-02-05 17:49:23 +0000131 }
132
133 return result;
134}
135
Paul Bakker5121ce52009-01-03 21:22:43 +0000136/*
137 * Encode a buffer into base64 format
138 */
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100139int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
Paul Bakker23986e52011-04-24 08:57:21 +0000140 const unsigned char *src, size_t slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000141{
Paul Bakker23986e52011-04-24 08:57:21 +0000142 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000143 int C1, C2, C3;
144 unsigned char *p;
145
146 if( slen == 0 )
Manuel Pégourié-Gonnard65fc6a82015-01-28 16:49:26 +0000147 {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100148 *olen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000149 return( 0 );
Manuel Pégourié-Gonnard65fc6a82015-01-28 16:49:26 +0000150 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000151
Manuel Pégourié-Gonnard0aa45c22015-09-30 16:30:28 +0200152 n = slen / 3 + ( slen % 3 != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000153
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +0100154 if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000155 {
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +0100156 *olen = BASE64_SIZE_T_MAX;
Manuel Pégourié-Gonnard0aa45c22015-09-30 16:30:28 +0200157 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000158 }
159
Manuel Pégourié-Gonnard0aa45c22015-09-30 16:30:28 +0200160 n *= 4;
161
Janos Follath98e28a72016-05-31 14:03:54 +0100162 if( ( dlen < n + 1 ) || ( NULL == dst ) )
Paul Bakker5121ce52009-01-03 21:22:43 +0000163 {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100164 *olen = n + 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200165 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000166 }
167
Paul Bakker66d5d072014-06-17 16:39:18 +0200168 n = ( slen / 3 ) * 3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000169
170 for( i = 0, p = dst; i < n; i += 3 )
171 {
172 C1 = *src++;
173 C2 = *src++;
174 C3 = *src++;
175
Paul Elliottdadd10d2021-02-05 17:49:23 +0000176 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
177 ( ( C1 >> 2 ) & 0x3F ) );
178
179 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
180 ( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
181
182 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
183 ( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F ) );
184
185 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
186 ( C3 & 0x3F ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000187 }
188
189 if( i < slen )
190 {
191 C1 = *src++;
Paul Bakker66d5d072014-06-17 16:39:18 +0200192 C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000193
Paul Elliottdadd10d2021-02-05 17:49:23 +0000194 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
195 ( ( C1 >> 2 ) & 0x3F ) );
196
197 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
198 ( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000199
Paul Bakker66d5d072014-06-17 16:39:18 +0200200 if( ( i + 1 ) < slen )
Paul Elliottdadd10d2021-02-05 17:49:23 +0000201 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
202 ( ( ( C2 & 15 ) << 2 ) & 0x3F ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000203 else *p++ = '=';
204
205 *p++ = '=';
206 }
207
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100208 *olen = p - dst;
Paul Bakker5121ce52009-01-03 21:22:43 +0000209 *p = 0;
210
211 return( 0 );
212}
213
214/*
215 * Decode a base64-formatted buffer
216 */
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100217int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
Paul Bakker23986e52011-04-24 08:57:21 +0000218 const unsigned char *src, size_t slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000219{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000220 size_t i, n;
221 uint32_t j, x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000222 unsigned char *p;
Paul Elliott6e152fa2021-03-01 18:33:09 +0000223 unsigned char dec_map_lookup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000224
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200225 /* First pass: check for validity and get output length */
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200226 for( i = n = j = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000227 {
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200228 /* Skip spaces before checking for EOL */
229 x = 0;
230 while( i < slen && src[i] == ' ' )
231 {
232 ++i;
233 ++x;
234 }
235
236 /* Spaces at end of buffer are OK */
237 if( i == slen )
238 break;
239
Paul Bakker5121ce52009-01-03 21:22:43 +0000240 if( ( slen - i ) >= 2 &&
241 src[i] == '\r' && src[i + 1] == '\n' )
242 continue;
243
244 if( src[i] == '\n' )
245 continue;
246
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200247 /* Space inside a line is an error */
248 if( x != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200249 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200250
Paul Bakker5121ce52009-01-03 21:22:43 +0000251 if( src[i] == '=' && ++j > 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200252 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000253
Paul Elliott6e152fa2021-03-01 18:33:09 +0000254 dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), src[i] );
255
256 if( src[i] > 127 || dec_map_lookup == 127 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200257 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000258
Paul Elliott6e152fa2021-03-01 18:33:09 +0000259 if( dec_map_lookup < 64 && j != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200260 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000261
262 n++;
263 }
264
265 if( n == 0 )
Simon Butchera45aa132015-10-05 00:26:36 +0100266 {
267 *olen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000268 return( 0 );
Simon Butchera45aa132015-10-05 00:26:36 +0100269 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000270
Simon Butchera29c5e9e2017-02-02 08:46:53 +0000271 /* The following expression is to calculate the following formula without
272 * risk of integer overflow in n:
273 * n = ( ( n * 6 ) + 7 ) >> 3;
274 */
Andres AG4623d832017-01-18 17:21:03 +0000275 n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 );
Paul Bakkerd5983182014-07-04 13:50:31 +0200276 n -= j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000277
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100278 if( dst == NULL || dlen < n )
Paul Bakker5121ce52009-01-03 21:22:43 +0000279 {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100280 *olen = n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200281 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000282 }
283
284 for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
285 {
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200286 if( *src == '\r' || *src == '\n' || *src == ' ' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000287 continue;
288
Paul Elliott6e152fa2021-03-01 18:33:09 +0000289 dec_map_lookup = mbedtls_base64_table_lookup(base64_dec_map, sizeof( base64_dec_map ), *src );
290
Paul Elliott0544d492021-03-01 19:15:43 +0000291 mbedtls_base64_cond_assign_uint32( &j, j - 1, mbedtls_base64_eq( dec_map_lookup, 64 ) );
Paul Elliott6e152fa2021-03-01 18:33:09 +0000292 x = ( x << 6 ) | ( dec_map_lookup & 0x3F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000293
294 if( ++n == 4 )
295 {
296 n = 0;
297 if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
298 if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
299 if( j > 2 ) *p++ = (unsigned char)( x );
300 }
301 }
302
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100303 *olen = p - dst;
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
305 return( 0 );
306}
307
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200308#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000309
Paul Bakker5121ce52009-01-03 21:22:43 +0000310static const unsigned char base64_test_dec[64] =
311{
312 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
313 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
314 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
315 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
316 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
317 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
318 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
319 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
320};
321
322static const unsigned char base64_test_enc[] =
323 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
324 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
325
326/*
327 * Checkup routine
328 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329int mbedtls_base64_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000330{
Paul Bakker23986e52011-04-24 08:57:21 +0000331 size_t len;
Paul Bakker3c2122f2013-06-24 19:03:14 +0200332 const unsigned char *src;
333 unsigned char buffer[128];
Paul Bakker5121ce52009-01-03 21:22:43 +0000334
335 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336 mbedtls_printf( " Base64 encoding test: " );
Paul Bakker5121ce52009-01-03 21:22:43 +0000337
Paul Bakker3c2122f2013-06-24 19:03:14 +0200338 src = base64_test_dec;
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100340 if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 ||
Paul Bakker3c2122f2013-06-24 19:03:14 +0200341 memcmp( base64_test_enc, buffer, 88 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000342 {
343 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200344 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
346 return( 1 );
347 }
348
349 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350 mbedtls_printf( "passed\n Base64 decoding test: " );
Paul Bakker5121ce52009-01-03 21:22:43 +0000351
Paul Bakker3c2122f2013-06-24 19:03:14 +0200352 src = base64_test_enc;
Paul Bakker5121ce52009-01-03 21:22:43 +0000353
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100354 if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 ||
Paul Bakker5121ce52009-01-03 21:22:43 +0000355 memcmp( base64_test_dec, buffer, 64 ) != 0 )
356 {
357 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200358 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000359
360 return( 1 );
361 }
362
363 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364 mbedtls_printf( "passed\n\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000365
366 return( 0 );
367}
368
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000370
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200371#endif /* MBEDTLS_BASE64_C */