blob: b89313062b670bd9f3daba73a0ed5c4f5058f31f [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1521 base64 encoding/decoding
3 *
Bence Szépkútia2947ac2020-08-19 16:37:36 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkútif744bd72020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000024 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
Paul Bakker5121ce52009-01-03 21:22:43 +000045 */
46
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000048#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020049#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020051#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000052
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if defined(MBEDTLS_BASE64_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000054
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000055#include "mbedtls/base64.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000056
Manuel Pégourié-Gonnard93866642015-06-22 19:21:23 +020057#include <stdint.h>
Paul Bakker5c2364c2012-10-01 14:41:15 +000058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059#if defined(MBEDTLS_SELF_TEST)
Rich Evans00ab4702015-02-06 13:43:58 +000060#include <string.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020061#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000062#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010063#else
Rich Evans00ab4702015-02-06 13:43:58 +000064#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#define mbedtls_printf printf
66#endif /* MBEDTLS_PLATFORM_C */
67#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010068
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +010069#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
70
Gilles Peskinef4a0a272021-07-28 13:54:02 +020071/* Return 0xff if low <= c <= high, 0 otherwise.
72 *
73 * Constant flow with respect to c.
74 */
75static unsigned char mask_of_range( unsigned char low, unsigned char high,
76 unsigned char c )
77{
Gilles Peskinebbf97cd2021-07-30 12:57:22 +020078 /* low_mask is: 0 if low <= c, 0x...ff if low > c */
79 unsigned low_mask = ( (unsigned) c - low ) >> 8;
80 /* high_mask is: 0 if c <= high, 0x...ff if high > c */
81 unsigned high_mask = ( (unsigned) high - c ) >> 8;
82 return( ~( low_mask | high_mask ) & 0xff );
Gilles Peskinef4a0a272021-07-28 13:54:02 +020083}
84
Gilles Peskineb44517e2021-07-28 14:31:39 +020085/* Given a value in the range 0..63, return the corresponding Base64 digit.
86 * The implementation assumes that letters are consecutive (e.g. ASCII
87 * but not EBCDIC).
88 */
89static unsigned char enc_char( unsigned char val )
90{
91 unsigned char digit = 0;
92 /* For each range of values, if val is in that range, mask digit with
93 * the corresponding value. Since val can only be in a single range,
94 * only at most one masking will change digit. */
95 digit |= mask_of_range( 0, 25, val ) & ( 'A' + val );
96 digit |= mask_of_range( 26, 51, val ) & ( 'a' + val - 26 );
97 digit |= mask_of_range( 52, 61, val ) & ( '0' + val - 52 );
98 digit |= mask_of_range( 62, 62, val ) & '+';
99 digit |= mask_of_range( 63, 63, val ) & '/';
100 return( digit );
101}
102
Paul Bakker5121ce52009-01-03 21:22:43 +0000103/*
104 * Encode a buffer into base64 format
105 */
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100106int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
Paul Bakker23986e52011-04-24 08:57:21 +0000107 const unsigned char *src, size_t slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000108{
Paul Bakker23986e52011-04-24 08:57:21 +0000109 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000110 int C1, C2, C3;
111 unsigned char *p;
112
113 if( slen == 0 )
Manuel Pégourié-Gonnard65fc6a82015-01-28 16:49:26 +0000114 {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100115 *olen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000116 return( 0 );
Manuel Pégourié-Gonnard65fc6a82015-01-28 16:49:26 +0000117 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000118
Manuel Pégourié-Gonnard0aa45c22015-09-30 16:30:28 +0200119 n = slen / 3 + ( slen % 3 != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000120
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +0100121 if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000122 {
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +0100123 *olen = BASE64_SIZE_T_MAX;
Manuel Pégourié-Gonnard0aa45c22015-09-30 16:30:28 +0200124 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000125 }
126
Manuel Pégourié-Gonnard0aa45c22015-09-30 16:30:28 +0200127 n *= 4;
128
Janos Follath98e28a72016-05-31 14:03:54 +0100129 if( ( dlen < n + 1 ) || ( NULL == dst ) )
Paul Bakker5121ce52009-01-03 21:22:43 +0000130 {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100131 *olen = n + 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000133 }
134
Paul Bakker66d5d072014-06-17 16:39:18 +0200135 n = ( slen / 3 ) * 3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000136
137 for( i = 0, p = dst; i < n; i += 3 )
138 {
139 C1 = *src++;
140 C2 = *src++;
141 C3 = *src++;
142
Gilles Peskineb44517e2021-07-28 14:31:39 +0200143 *p++ = enc_char( ( C1 >> 2 ) & 0x3F );
144 *p++ = enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F );
145 *p++ = enc_char( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F );
146 *p++ = enc_char( C3 & 0x3F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000147 }
148
149 if( i < slen )
150 {
151 C1 = *src++;
Paul Bakker66d5d072014-06-17 16:39:18 +0200152 C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000153
Gilles Peskineb44517e2021-07-28 14:31:39 +0200154 *p++ = enc_char( ( C1 >> 2 ) & 0x3F );
155 *p++ = enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000156
Paul Bakker66d5d072014-06-17 16:39:18 +0200157 if( ( i + 1 ) < slen )
Gilles Peskineb44517e2021-07-28 14:31:39 +0200158 *p++ = enc_char( ( ( C2 & 15 ) << 2 ) & 0x3F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000159 else *p++ = '=';
160
161 *p++ = '=';
162 }
163
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100164 *olen = p - dst;
Paul Bakker5121ce52009-01-03 21:22:43 +0000165 *p = 0;
166
167 return( 0 );
168}
169
Gilles Peskinef4a0a272021-07-28 13:54:02 +0200170/* Given a Base64 digit, return its value.
171 * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'),
172 * return -1.
173 *
174 * The implementation assumes that letters are consecutive (e.g. ASCII
175 * but not EBCDIC).
176 *
177 * The implementation is constant-flow (no branch or memory access depending
178 * on the value of c) unless the compiler inlines and optimizes a specific
179 * access.
180 */
181static signed char dec_value( unsigned char c )
182{
183 unsigned char val = 0;
184 /* For each range of digits, if c is in that range, mask val with
185 * the corresponding value. Since c can only be in a single range,
186 * only at most one masking will change val. Set val to one plus
187 * the desired value so that it stays 0 if c is in none of the ranges. */
188 val |= mask_of_range( 'A', 'Z', c ) & ( c - 'A' + 0 + 1 );
189 val |= mask_of_range( 'a', 'z', c ) & ( c - 'a' + 26 + 1 );
190 val |= mask_of_range( '0', '9', c ) & ( c - '0' + 52 + 1 );
191 val |= mask_of_range( '+', '+', c ) & ( c - '+' + 62 + 1 );
192 val |= mask_of_range( '/', '/', c ) & ( c - '/' + 63 + 1 );
193 /* At this point, val is 0 if c is an invalid digit and v+1 if c is
194 * a digit with the value v. */
195 return( val - 1 );
196}
197
Paul Bakker5121ce52009-01-03 21:22:43 +0000198/*
199 * Decode a base64-formatted buffer
200 */
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100201int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
Paul Bakker23986e52011-04-24 08:57:21 +0000202 const unsigned char *src, size_t slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000203{
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200204 size_t i; /* index in source */
205 size_t n; /* number of digits or trailing = in source */
206 uint32_t x; /* value accumulator */
Gilles Peskine231b67a2021-07-30 12:56:21 +0200207 unsigned accumulated_digits = 0;
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200208 unsigned equals = 0;
209 int spaces_present = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000210 unsigned char *p;
211
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200212 /* First pass: check for validity and get output length */
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200213 for( i = n = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000214 {
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200215 /* Skip spaces before checking for EOL */
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200216 spaces_present = 0;
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200217 while( i < slen && src[i] == ' ' )
218 {
219 ++i;
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200220 spaces_present = 1;
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200221 }
222
223 /* Spaces at end of buffer are OK */
224 if( i == slen )
225 break;
226
Paul Bakker5121ce52009-01-03 21:22:43 +0000227 if( ( slen - i ) >= 2 &&
228 src[i] == '\r' && src[i + 1] == '\n' )
229 continue;
230
231 if( src[i] == '\n' )
232 continue;
233
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200234 /* Space inside a line is an error */
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200235 if( spaces_present )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200236 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200237
Gilles Peskinea47fdcf2021-07-28 11:33:04 +0200238 if( src[i] > 127 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200239 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000240
Gilles Peskinea47fdcf2021-07-28 11:33:04 +0200241 if( src[i] == '=' )
242 {
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200243 if( ++equals > 2 )
Gilles Peskinea47fdcf2021-07-28 11:33:04 +0200244 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
245 }
246 else
247 {
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200248 if( equals != 0 )
Gilles Peskinea47fdcf2021-07-28 11:33:04 +0200249 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Gilles Peskinef4a0a272021-07-28 13:54:02 +0200250 if( dec_value( src[i] ) < 0 )
Gilles Peskinea47fdcf2021-07-28 11:33:04 +0200251 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
252 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000253 n++;
254 }
255
256 if( n == 0 )
Simon Butchera45aa132015-10-05 00:26:36 +0100257 {
258 *olen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000259 return( 0 );
Simon Butchera45aa132015-10-05 00:26:36 +0100260 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000261
Simon Butchera29c5e9e2017-02-02 08:46:53 +0000262 /* The following expression is to calculate the following formula without
263 * risk of integer overflow in n:
264 * n = ( ( n * 6 ) + 7 ) >> 3;
265 */
Andres AG4623d832017-01-18 17:21:03 +0000266 n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 );
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200267 n -= equals;
Paul Bakker5121ce52009-01-03 21:22:43 +0000268
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100269 if( dst == NULL || dlen < n )
Paul Bakker5121ce52009-01-03 21:22:43 +0000270 {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100271 *olen = n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200272 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000273 }
274
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200275 equals = 0;
Gilles Peskine231b67a2021-07-30 12:56:21 +0200276 for( x = 0, p = dst; i > 0; i--, src++ )
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200277 {
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200278 if( *src == '\r' || *src == '\n' || *src == ' ' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000279 continue;
280
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200281 x = x << 6;
Gilles Peskinea47fdcf2021-07-28 11:33:04 +0200282 if( *src == '=' )
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200283 ++equals;
Gilles Peskinea47fdcf2021-07-28 11:33:04 +0200284 else
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200285 x |= dec_value( *src );
Paul Bakker5121ce52009-01-03 21:22:43 +0000286
Gilles Peskine231b67a2021-07-30 12:56:21 +0200287 if( ++accumulated_digits == 4 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000288 {
Gilles Peskine231b67a2021-07-30 12:56:21 +0200289 accumulated_digits = 0;
Gilles Peskineea96b3a2021-07-28 14:20:06 +0200290 *p++ = (unsigned char)( x >> 16 );
291 if( equals <= 1 ) *p++ = (unsigned char)( x >> 8 );
292 if( equals <= 0 ) *p++ = (unsigned char)( x );
Paul Bakker5121ce52009-01-03 21:22:43 +0000293 }
294 }
295
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100296 *olen = p - dst;
Paul Bakker5121ce52009-01-03 21:22:43 +0000297
298 return( 0 );
299}
300
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000302
Paul Bakker5121ce52009-01-03 21:22:43 +0000303static const unsigned char base64_test_dec[64] =
304{
305 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
306 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
307 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
308 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
309 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
310 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
311 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
312 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
313};
314
315static const unsigned char base64_test_enc[] =
316 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
317 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
318
319/*
320 * Checkup routine
321 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200322int mbedtls_base64_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000323{
Paul Bakker23986e52011-04-24 08:57:21 +0000324 size_t len;
Paul Bakker3c2122f2013-06-24 19:03:14 +0200325 const unsigned char *src;
326 unsigned char buffer[128];
Paul Bakker5121ce52009-01-03 21:22:43 +0000327
328 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329 mbedtls_printf( " Base64 encoding test: " );
Paul Bakker5121ce52009-01-03 21:22:43 +0000330
Paul Bakker3c2122f2013-06-24 19:03:14 +0200331 src = base64_test_dec;
Paul Bakker5121ce52009-01-03 21:22:43 +0000332
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100333 if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 ||
Paul Bakker3c2122f2013-06-24 19:03:14 +0200334 memcmp( base64_test_enc, buffer, 88 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000335 {
336 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200337 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000338
339 return( 1 );
340 }
341
342 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343 mbedtls_printf( "passed\n Base64 decoding test: " );
Paul Bakker5121ce52009-01-03 21:22:43 +0000344
Paul Bakker3c2122f2013-06-24 19:03:14 +0200345 src = base64_test_enc;
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100347 if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 ||
Paul Bakker5121ce52009-01-03 21:22:43 +0000348 memcmp( base64_test_dec, buffer, 64 ) != 0 )
349 {
350 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000352
353 return( 1 );
354 }
355
356 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200357 mbedtls_printf( "passed\n\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000358
359 return( 0 );
360}
361
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000363
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364#endif /* MBEDTLS_BASE64_C */