blob: 692e11e3fae70f3f58027cff4f5f3d51ef0ae890 [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
Paul Bakker5121ce52009-01-03 21:22:43 +000069static const unsigned char base64_enc_map[64] =
70{
71 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
72 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
73 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
74 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
75 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
76 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
77 '8', '9', '+', '/'
78};
79
80static const unsigned char base64_dec_map[128] =
81{
82 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
83 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
84 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
85 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
86 127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
87 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
88 127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
89 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
90 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
91 25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
92 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
93 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
94 49, 50, 51, 127, 127, 127, 127, 127
95};
96
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +010097#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
98
Paul Elliottf13a47b2021-02-25 12:28:49 +000099/*
Paul Elliotte8ee0f12021-03-01 19:15:43 +0000100 * Constant flow conditional assignment to unsigned char
Paul Elliottcd65b622021-03-04 14:34:50 +0000101 */
102static void mbedtls_base64_cond_assign_uchar( unsigned char * dest, const unsigned char * const src,
103 unsigned char condition )
Paul Elliott738d2312021-02-05 17:49:23 +0000104{
Paul Elliott6f69d4c2021-03-03 15:31:17 +0000105 /* MSVC has a warning about unary minus on unsigned integer types,
106 * but this is well-defined and precisely what we want to do here. */
107#if defined(_MSC_VER)
108#pragma warning( push )
109#pragma warning( disable : 4146 )
110#endif
Paul Elliott738d2312021-02-05 17:49:23 +0000111
Paul Elliott48236242021-03-03 17:21:17 +0000112 /* Generate bitmask from condition, mask will either be 0xFF or 0 */
Paul Elliott490c5d42021-03-03 17:11:32 +0000113 unsigned char mask = ( condition | -condition );
114 mask >>= 7;
115 mask = -mask;
Paul Elliott6f69d4c2021-03-03 15:31:17 +0000116
117#if defined(_MSC_VER)
118#pragma warning( pop )
119#endif
120
121 *dest = ( ( *src ) & mask ) | ( ( *dest ) & ~mask );
Paul Elliott738d2312021-02-05 17:49:23 +0000122}
123
124/*
Paul Elliotte8ee0f12021-03-01 19:15:43 +0000125 * Constant flow conditional assignment to uint_32
Paul Elliottcd65b622021-03-04 14:34:50 +0000126 */
127static void mbedtls_base64_cond_assign_uint32( uint32_t * dest, const uint32_t src,
128 uint32_t condition )
Paul Elliotte8ee0f12021-03-01 19:15:43 +0000129{
Paul Elliott6f69d4c2021-03-03 15:31:17 +0000130 /* MSVC has a warning about unary minus on unsigned integer types,
131 * but this is well-defined and precisely what we want to do here. */
132#if defined(_MSC_VER)
133#pragma warning( push )
134#pragma warning( disable : 4146 )
135#endif
Paul Elliotte8ee0f12021-03-01 19:15:43 +0000136
Paul Elliott6f69d4c2021-03-03 15:31:17 +0000137 /* Generate bitmask from condition, mask will either be 0xFFFFFFFF or 0 */
Paul Elliott490c5d42021-03-03 17:11:32 +0000138 uint32_t mask = ( condition | -condition );
139 mask >>= 31;
140 mask = -mask;
Paul Elliott6f69d4c2021-03-03 15:31:17 +0000141
142#if defined(_MSC_VER)
143#pragma warning( pop )
144#endif
145
146 *dest = ( src & mask ) | ( ( *dest ) & ~mask );
Paul Elliotte8ee0f12021-03-01 19:15:43 +0000147}
148
Paul Elliotte8ee0f12021-03-01 19:15:43 +0000149/*
Paul Elliottf13a47b2021-02-25 12:28:49 +0000150 * Constant flow check for equality
Paul Elliottcd65b622021-03-04 14:34:50 +0000151 */
152static unsigned char mbedtls_base64_eq( size_t in_a, size_t in_b )
Paul Elliott738d2312021-02-05 17:49:23 +0000153{
Paul Elliott86cb9282021-03-01 17:49:42 +0000154 size_t difference = in_a ^ in_b;
Paul Elliott738d2312021-02-05 17:49:23 +0000155
Paul Elliottf13a47b2021-02-25 12:28:49 +0000156 /* MSVC has a warning about unary minus on unsigned integer types,
157 * but this is well-defined and precisely what we want to do here. */
158#if defined(_MSC_VER)
159#pragma warning( push )
160#pragma warning( disable : 4146 )
161#endif
162
Paul Elliott738d2312021-02-05 17:49:23 +0000163 difference |= -difference;
Paul Elliottf13a47b2021-02-25 12:28:49 +0000164
165#if defined(_MSC_VER)
166#pragma warning( pop )
167#endif
168
Paul Elliott86cb9282021-03-01 17:49:42 +0000169 /* cope with the varying size of size_t per platform */
170 difference >>= ( sizeof( difference ) * 8 - 1 );
171
Paul Elliott738d2312021-02-05 17:49:23 +0000172 return (unsigned char) ( 1 ^ difference );
173}
174
175/*
Paul Elliottf13a47b2021-02-25 12:28:49 +0000176 * Constant flow lookup into table.
Paul Elliottcd65b622021-03-04 14:34:50 +0000177 */
178static unsigned char mbedtls_base64_table_lookup( const unsigned char * const table,
179 const size_t table_size, const size_t table_index )
Paul Elliott738d2312021-02-05 17:49:23 +0000180{
181 size_t i;
182 unsigned char result = 0;
183
184 for( i = 0; i < table_size; ++i )
185 {
Paul Elliottcd65b622021-03-04 14:34:50 +0000186 mbedtls_base64_cond_assign_uchar( &result, &table[i], mbedtls_base64_eq( i, table_index ) );
Paul Elliott738d2312021-02-05 17:49:23 +0000187 }
188
189 return result;
190}
191
Paul Bakker5121ce52009-01-03 21:22:43 +0000192/*
193 * Encode a buffer into base64 format
194 */
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100195int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
Paul Bakker23986e52011-04-24 08:57:21 +0000196 const unsigned char *src, size_t slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000197{
Paul Bakker23986e52011-04-24 08:57:21 +0000198 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000199 int C1, C2, C3;
200 unsigned char *p;
201
202 if( slen == 0 )
Manuel Pégourié-Gonnard65fc6a82015-01-28 16:49:26 +0000203 {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100204 *olen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000205 return( 0 );
Manuel Pégourié-Gonnard65fc6a82015-01-28 16:49:26 +0000206 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000207
Manuel Pégourié-Gonnard0aa45c22015-09-30 16:30:28 +0200208 n = slen / 3 + ( slen % 3 != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000209
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +0100210 if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000211 {
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +0100212 *olen = BASE64_SIZE_T_MAX;
Manuel Pégourié-Gonnard0aa45c22015-09-30 16:30:28 +0200213 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000214 }
215
Manuel Pégourié-Gonnard0aa45c22015-09-30 16:30:28 +0200216 n *= 4;
217
Janos Follath98e28a72016-05-31 14:03:54 +0100218 if( ( dlen < n + 1 ) || ( NULL == dst ) )
Paul Bakker5121ce52009-01-03 21:22:43 +0000219 {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100220 *olen = n + 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200221 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000222 }
223
Paul Bakker66d5d072014-06-17 16:39:18 +0200224 n = ( slen / 3 ) * 3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000225
226 for( i = 0, p = dst; i < n; i += 3 )
227 {
228 C1 = *src++;
229 C2 = *src++;
230 C3 = *src++;
231
Paul Elliott738d2312021-02-05 17:49:23 +0000232 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
233 ( ( C1 >> 2 ) & 0x3F ) );
234
235 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
236 ( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
237
238 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
239 ( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F ) );
240
241 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
242 ( C3 & 0x3F ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000243 }
244
245 if( i < slen )
246 {
247 C1 = *src++;
Paul Bakker66d5d072014-06-17 16:39:18 +0200248 C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000249
Paul Elliott738d2312021-02-05 17:49:23 +0000250 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
251 ( ( C1 >> 2 ) & 0x3F ) );
252
253 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
254 ( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000255
Paul Bakker66d5d072014-06-17 16:39:18 +0200256 if( ( i + 1 ) < slen )
Paul Elliott738d2312021-02-05 17:49:23 +0000257 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
258 ( ( ( C2 & 15 ) << 2 ) & 0x3F ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000259 else *p++ = '=';
260
261 *p++ = '=';
262 }
263
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100264 *olen = p - dst;
Paul Bakker5121ce52009-01-03 21:22:43 +0000265 *p = 0;
266
267 return( 0 );
268}
269
270/*
271 * Decode a base64-formatted buffer
272 */
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100273int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
Paul Bakker23986e52011-04-24 08:57:21 +0000274 const unsigned char *src, size_t slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000275{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000276 size_t i, n;
277 uint32_t j, x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000278 unsigned char *p;
Paul Elliott6a667372021-03-01 18:33:09 +0000279 unsigned char dec_map_lookup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000280
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200281 /* First pass: check for validity and get output length */
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200282 for( i = n = j = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 {
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200284 /* Skip spaces before checking for EOL */
285 x = 0;
286 while( i < slen && src[i] == ' ' )
287 {
288 ++i;
289 ++x;
290 }
291
292 /* Spaces at end of buffer are OK */
293 if( i == slen )
294 break;
295
Paul Bakker5121ce52009-01-03 21:22:43 +0000296 if( ( slen - i ) >= 2 &&
297 src[i] == '\r' && src[i + 1] == '\n' )
298 continue;
299
300 if( src[i] == '\n' )
301 continue;
302
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200303 /* Space inside a line is an error */
304 if( x != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200306
Paul Bakker5121ce52009-01-03 21:22:43 +0000307 if( src[i] == '=' && ++j > 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200308 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000309
Paul Elliott6a667372021-03-01 18:33:09 +0000310 dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), src[i] );
311
312 if( src[i] > 127 || dec_map_lookup == 127 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200313 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000314
Paul Elliott6a667372021-03-01 18:33:09 +0000315 if( dec_map_lookup < 64 && j != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200316 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000317
318 n++;
319 }
320
321 if( n == 0 )
Simon Butchera45aa132015-10-05 00:26:36 +0100322 {
323 *olen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000324 return( 0 );
Simon Butchera45aa132015-10-05 00:26:36 +0100325 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
Simon Butchera29c5e9e2017-02-02 08:46:53 +0000327 /* The following expression is to calculate the following formula without
328 * risk of integer overflow in n:
329 * n = ( ( n * 6 ) + 7 ) >> 3;
330 */
Andres AG4623d832017-01-18 17:21:03 +0000331 n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 );
Paul Bakkerd5983182014-07-04 13:50:31 +0200332 n -= j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000333
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100334 if( dst == NULL || dlen < n )
Paul Bakker5121ce52009-01-03 21:22:43 +0000335 {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100336 *olen = n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200337 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000338 }
339
340 for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
341 {
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200342 if( *src == '\r' || *src == '\n' || *src == ' ' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000343 continue;
344
Paul Elliottcd65b622021-03-04 14:34:50 +0000345 dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), *src );
Paul Elliott6a667372021-03-01 18:33:09 +0000346
Paul Elliotte8ee0f12021-03-01 19:15:43 +0000347 mbedtls_base64_cond_assign_uint32( &j, j - 1, mbedtls_base64_eq( dec_map_lookup, 64 ) );
Paul Elliott6a667372021-03-01 18:33:09 +0000348 x = ( x << 6 ) | ( dec_map_lookup & 0x3F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000349
350 if( ++n == 4 )
351 {
352 n = 0;
353 if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
354 if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
355 if( j > 2 ) *p++ = (unsigned char)( x );
356 }
357 }
358
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100359 *olen = p - dst;
Paul Bakker5121ce52009-01-03 21:22:43 +0000360
361 return( 0 );
362}
363
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000365
Paul Bakker5121ce52009-01-03 21:22:43 +0000366static const unsigned char base64_test_dec[64] =
367{
368 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
369 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
370 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
371 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
372 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
373 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
374 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
375 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
376};
377
378static const unsigned char base64_test_enc[] =
379 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
380 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
381
382/*
383 * Checkup routine
384 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385int mbedtls_base64_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000386{
Paul Bakker23986e52011-04-24 08:57:21 +0000387 size_t len;
Paul Bakker3c2122f2013-06-24 19:03:14 +0200388 const unsigned char *src;
389 unsigned char buffer[128];
Paul Bakker5121ce52009-01-03 21:22:43 +0000390
391 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392 mbedtls_printf( " Base64 encoding test: " );
Paul Bakker5121ce52009-01-03 21:22:43 +0000393
Paul Bakker3c2122f2013-06-24 19:03:14 +0200394 src = base64_test_dec;
Paul Bakker5121ce52009-01-03 21:22:43 +0000395
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100396 if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 ||
Paul Bakker3c2122f2013-06-24 19:03:14 +0200397 memcmp( base64_test_enc, buffer, 88 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000398 {
399 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200400 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000401
402 return( 1 );
403 }
404
405 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406 mbedtls_printf( "passed\n Base64 decoding test: " );
Paul Bakker5121ce52009-01-03 21:22:43 +0000407
Paul Bakker3c2122f2013-06-24 19:03:14 +0200408 src = base64_test_enc;
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100410 if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 ||
Paul Bakker5121ce52009-01-03 21:22:43 +0000411 memcmp( base64_test_dec, buffer, 64 ) != 0 )
412 {
413 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200414 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
416 return( 1 );
417 }
418
419 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420 mbedtls_printf( "passed\n\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000421
422 return( 0 );
423}
424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000426
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427#endif /* MBEDTLS_BASE64_C */