blob: 8b818c86a845209ff4e92044abc5e57a102d4b1b [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,
Gilles Peskineb553eaa2021-07-28 11:33:04 +020057 127, 127, 127, 127, 127, 0, 1, 2, 3, 4,
Paul Bakker5121ce52009-01-03 21:22:43 +000058 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 Elliottbe165bd2021-03-04 14:34:50 +000070 */
71static void mbedtls_base64_cond_assign_uchar( unsigned char * dest, const unsigned char * const src,
72 unsigned char condition )
Paul Elliottdadd10d2021-02-05 17:49:23 +000073{
Paul Elliott88f2eb62021-03-03 15:31:17 +000074 /* MSVC has a warning about unary minus on unsigned integer types,
75 * but this is well-defined and precisely what we want to do here. */
76#if defined(_MSC_VER)
77#pragma warning( push )
78#pragma warning( disable : 4146 )
79#endif
Paul Elliottdadd10d2021-02-05 17:49:23 +000080
Paul Elliott07fa1f12021-03-03 17:21:17 +000081 /* Generate bitmask from condition, mask will either be 0xFF or 0 */
Paul Elliott3ffd1342021-03-03 17:11:32 +000082 unsigned char mask = ( condition | -condition );
83 mask >>= 7;
84 mask = -mask;
Paul Elliott88f2eb62021-03-03 15:31:17 +000085
86#if defined(_MSC_VER)
87#pragma warning( pop )
88#endif
89
90 *dest = ( ( *src ) & mask ) | ( ( *dest ) & ~mask );
Paul Elliottdadd10d2021-02-05 17:49:23 +000091}
92
93/*
Paul Elliott3e790812021-02-25 12:28:49 +000094 * Constant flow check for equality
Paul Elliottbe165bd2021-03-04 14:34:50 +000095 */
96static 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 Elliottbe165bd2021-03-04 14:34:50 +0000121 */
122static unsigned char mbedtls_base64_table_lookup( const unsigned char * const table,
123 const size_t table_size, const size_t table_index )
Paul Elliottdadd10d2021-02-05 17:49:23 +0000124{
125 size_t i;
126 unsigned char result = 0;
127
128 for( i = 0; i < table_size; ++i )
129 {
Paul Elliottbe165bd2021-03-04 14:34:50 +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
Gilles Peskineb553eaa2021-07-28 11:33:04 +0200251 if( src[i] > 127 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200252 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000253
Gilles Peskineb553eaa2021-07-28 11:33:04 +0200254 if( src[i] == '=' )
255 {
256 if( ++j > 2 )
257 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
258 }
259 else
260 {
261 if( j != 0 )
262 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
263 dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), src[i] );
264 if( dec_map_lookup == 127 )
265 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
266 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000267 n++;
268 }
269
270 if( n == 0 )
Simon Butchera45aa132015-10-05 00:26:36 +0100271 {
272 *olen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000273 return( 0 );
Simon Butchera45aa132015-10-05 00:26:36 +0100274 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000275
Simon Butchera29c5e9e2017-02-02 08:46:53 +0000276 /* The following expression is to calculate the following formula without
277 * risk of integer overflow in n:
278 * n = ( ( n * 6 ) + 7 ) >> 3;
279 */
Andres AG4623d832017-01-18 17:21:03 +0000280 n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 );
Paul Bakkerd5983182014-07-04 13:50:31 +0200281 n -= j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000282
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100283 if( dst == NULL || dlen < n )
Paul Bakker5121ce52009-01-03 21:22:43 +0000284 {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100285 *olen = n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200286 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000287 }
288
289 for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
290 {
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200291 if( *src == '\r' || *src == '\n' || *src == ' ' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000292 continue;
293
Gilles Peskineb553eaa2021-07-28 11:33:04 +0200294 if( *src == '=' )
295 {
296 --j;
297 x = x << 6;
298 }
299 else
300 {
301 dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), *src );
302 x = ( x << 6 ) | ( dec_map_lookup & 0x3F );
303 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
305 if( ++n == 4 )
306 {
307 n = 0;
Joe Subbianifbeb6922021-07-16 14:27:50 +0100308 if( j > 0 ) *p++ = MBEDTLS_BYTE_2( x );
309 if( j > 1 ) *p++ = MBEDTLS_BYTE_1( x );
310 if( j > 2 ) *p++ = MBEDTLS_BYTE_0( x );
Paul Bakker5121ce52009-01-03 21:22:43 +0000311 }
312 }
313
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100314 *olen = p - dst;
Paul Bakker5121ce52009-01-03 21:22:43 +0000315
316 return( 0 );
317}
318
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000320
Paul Bakker5121ce52009-01-03 21:22:43 +0000321static const unsigned char base64_test_dec[64] =
322{
323 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
324 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
325 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
326 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
327 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
328 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
329 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
330 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
331};
332
333static const unsigned char base64_test_enc[] =
334 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
335 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
336
337/*
338 * Checkup routine
339 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200340int mbedtls_base64_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000341{
Paul Bakker23986e52011-04-24 08:57:21 +0000342 size_t len;
Paul Bakker3c2122f2013-06-24 19:03:14 +0200343 const unsigned char *src;
344 unsigned char buffer[128];
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
346 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347 mbedtls_printf( " Base64 encoding test: " );
Paul Bakker5121ce52009-01-03 21:22:43 +0000348
Paul Bakker3c2122f2013-06-24 19:03:14 +0200349 src = base64_test_dec;
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100351 if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 ||
Paul Bakker3c2122f2013-06-24 19:03:14 +0200352 memcmp( base64_test_enc, buffer, 88 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000353 {
354 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000356
357 return( 1 );
358 }
359
360 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200361 mbedtls_printf( "passed\n Base64 decoding test: " );
Paul Bakker5121ce52009-01-03 21:22:43 +0000362
Paul Bakker3c2122f2013-06-24 19:03:14 +0200363 src = base64_test_enc;
Paul Bakker5121ce52009-01-03 21:22:43 +0000364
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100365 if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 ||
Paul Bakker5121ce52009-01-03 21:22:43 +0000366 memcmp( base64_test_dec, buffer, 64 ) != 0 )
367 {
368 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000370
371 return( 1 );
372 }
373
374 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 mbedtls_printf( "passed\n\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000376
377 return( 0 );
378}
379
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200380#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200382#endif /* MBEDTLS_BASE64_C */