blob: 6b0cb7169fb081ef27494323a190fd2afde55649 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1521 base64 encoding/decoding
3 *
Bence Szépkúti44bfbe32020-08-19 16:54:51 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkúti4e9f7122020-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úti4e9f7122020-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 Elliottaae04ef2021-02-25 12:28:49 +000099/*
Paul Elliottbd559622021-03-01 19:15:43 +0000100 * Constant flow conditional assignment to unsigned char
Paul Elliottaae04ef2021-02-25 12:28:49 +0000101*/
Paul Elliottbd559622021-03-01 19:15:43 +0000102static void mbedtls_base64_cond_assign_uchar(unsigned char * dest, const unsigned char * const src,
Paul Elliottaa502792021-02-05 17:49:23 +0000103 unsigned char condition)
104{
Paul Elliott2f2ec572021-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 Elliottaa502792021-02-05 17:49:23 +0000111
Paul Elliott2f2ec572021-03-03 15:31:17 +0000112 /* Generate bitmask from condition, mask will either be 0xFFFFFFFF or 0 */
113 unsigned char mask = -( unsigned char )( ( condition | -condition ) >> 7 );
114
115#if defined(_MSC_VER)
116#pragma warning( pop )
117#endif
118
119 *dest = ( ( *src ) & mask ) | ( ( *dest ) & ~mask );
Paul Elliottaa502792021-02-05 17:49:23 +0000120}
121
122/*
Paul Elliottbd559622021-03-01 19:15:43 +0000123 * Constant flow conditional assignment to uint_32
124*/
125static void mbedtls_base64_cond_assign_uint32(uint32_t * dest, const uint32_t src,
Paul Elliott2f2ec572021-03-03 15:31:17 +0000126 uint32_t condition)
Paul Elliottbd559622021-03-01 19:15:43 +0000127{
Paul Elliott2f2ec572021-03-03 15:31:17 +0000128 /* MSVC has a warning about unary minus on unsigned integer types,
129 * but this is well-defined and precisely what we want to do here. */
130#if defined(_MSC_VER)
131#pragma warning( push )
132#pragma warning( disable : 4146 )
133#endif
Paul Elliottbd559622021-03-01 19:15:43 +0000134
Paul Elliott2f2ec572021-03-03 15:31:17 +0000135 /* Generate bitmask from condition, mask will either be 0xFFFFFFFF or 0 */
136 uint32_t mask = -( uint32_t )( ( condition | -condition ) >> 31 );
137
138#if defined(_MSC_VER)
139#pragma warning( pop )
140#endif
141
142 *dest = ( src & mask ) | ( ( *dest ) & ~mask );
Paul Elliottbd559622021-03-01 19:15:43 +0000143}
144
145
146/*
Paul Elliottaae04ef2021-02-25 12:28:49 +0000147 * Constant flow check for equality
Paul Elliottaa502792021-02-05 17:49:23 +0000148*/
Paul Elliottaae04ef2021-02-25 12:28:49 +0000149static unsigned char mbedtls_base64_eq(size_t in_a, size_t in_b)
Paul Elliottaa502792021-02-05 17:49:23 +0000150{
Paul Elliotteb3916d2021-03-01 17:49:42 +0000151 size_t difference = in_a ^ in_b;
Paul Elliottaa502792021-02-05 17:49:23 +0000152
Paul Elliottaae04ef2021-02-25 12:28:49 +0000153 /* MSVC has a warning about unary minus on unsigned integer types,
154 * but this is well-defined and precisely what we want to do here. */
155#if defined(_MSC_VER)
156#pragma warning( push )
157#pragma warning( disable : 4146 )
158#endif
159
Paul Elliottaa502792021-02-05 17:49:23 +0000160 difference |= -difference;
Paul Elliottaae04ef2021-02-25 12:28:49 +0000161
162#if defined(_MSC_VER)
163#pragma warning( pop )
164#endif
165
Paul Elliotteb3916d2021-03-01 17:49:42 +0000166 /* cope with the varying size of size_t per platform */
167 difference >>= ( sizeof( difference ) * 8 - 1 );
168
Paul Elliottaa502792021-02-05 17:49:23 +0000169 return (unsigned char) ( 1 ^ difference );
170}
171
172/*
Paul Elliottaae04ef2021-02-25 12:28:49 +0000173 * Constant flow lookup into table.
Paul Elliottaa502792021-02-05 17:49:23 +0000174*/
175static unsigned char mbedtls_base64_table_lookup(const unsigned char * const table,
176 const size_t table_size, const size_t table_index)
177{
178 size_t i;
179 unsigned char result = 0;
180
181 for( i = 0; i < table_size; ++i )
182 {
Paul Elliottbd559622021-03-01 19:15:43 +0000183 mbedtls_base64_cond_assign_uchar(&result, &table[i], mbedtls_base64_eq(i, table_index));
Paul Elliottaa502792021-02-05 17:49:23 +0000184 }
185
186 return result;
187}
188
Paul Bakker5121ce52009-01-03 21:22:43 +0000189/*
190 * Encode a buffer into base64 format
191 */
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100192int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
Paul Bakker23986e52011-04-24 08:57:21 +0000193 const unsigned char *src, size_t slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000194{
Paul Bakker23986e52011-04-24 08:57:21 +0000195 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000196 int C1, C2, C3;
197 unsigned char *p;
198
199 if( slen == 0 )
Manuel Pégourié-Gonnard65fc6a82015-01-28 16:49:26 +0000200 {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100201 *olen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000202 return( 0 );
Manuel Pégourié-Gonnard65fc6a82015-01-28 16:49:26 +0000203 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000204
Manuel Pégourié-Gonnard0aa45c22015-09-30 16:30:28 +0200205 n = slen / 3 + ( slen % 3 != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000206
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +0100207 if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000208 {
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +0100209 *olen = BASE64_SIZE_T_MAX;
Manuel Pégourié-Gonnard0aa45c22015-09-30 16:30:28 +0200210 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000211 }
212
Manuel Pégourié-Gonnard0aa45c22015-09-30 16:30:28 +0200213 n *= 4;
214
Janos Follath98e28a72016-05-31 14:03:54 +0100215 if( ( dlen < n + 1 ) || ( NULL == dst ) )
Paul Bakker5121ce52009-01-03 21:22:43 +0000216 {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100217 *olen = n + 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200218 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000219 }
220
Paul Bakker66d5d072014-06-17 16:39:18 +0200221 n = ( slen / 3 ) * 3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000222
223 for( i = 0, p = dst; i < n; i += 3 )
224 {
225 C1 = *src++;
226 C2 = *src++;
227 C3 = *src++;
228
Paul Elliottaa502792021-02-05 17:49:23 +0000229 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
230 ( ( C1 >> 2 ) & 0x3F ) );
231
232 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
233 ( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
234
235 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
236 ( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F ) );
237
238 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
239 ( C3 & 0x3F ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000240 }
241
242 if( i < slen )
243 {
244 C1 = *src++;
Paul Bakker66d5d072014-06-17 16:39:18 +0200245 C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000246
Paul Elliottaa502792021-02-05 17:49:23 +0000247 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
248 ( ( C1 >> 2 ) & 0x3F ) );
249
250 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
251 ( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000252
Paul Bakker66d5d072014-06-17 16:39:18 +0200253 if( ( i + 1 ) < slen )
Paul Elliottaa502792021-02-05 17:49:23 +0000254 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
255 ( ( ( C2 & 15 ) << 2 ) & 0x3F ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000256 else *p++ = '=';
257
258 *p++ = '=';
259 }
260
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100261 *olen = p - dst;
Paul Bakker5121ce52009-01-03 21:22:43 +0000262 *p = 0;
263
264 return( 0 );
265}
266
267/*
268 * Decode a base64-formatted buffer
269 */
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100270int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
Paul Bakker23986e52011-04-24 08:57:21 +0000271 const unsigned char *src, size_t slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000272{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000273 size_t i, n;
274 uint32_t j, x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000275 unsigned char *p;
Paul Elliott419983d2021-03-01 18:33:09 +0000276 unsigned char dec_map_lookup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000277
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200278 /* First pass: check for validity and get output length */
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200279 for( i = n = j = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000280 {
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200281 /* Skip spaces before checking for EOL */
282 x = 0;
283 while( i < slen && src[i] == ' ' )
284 {
285 ++i;
286 ++x;
287 }
288
289 /* Spaces at end of buffer are OK */
290 if( i == slen )
291 break;
292
Paul Bakker5121ce52009-01-03 21:22:43 +0000293 if( ( slen - i ) >= 2 &&
294 src[i] == '\r' && src[i + 1] == '\n' )
295 continue;
296
297 if( src[i] == '\n' )
298 continue;
299
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200300 /* Space inside a line is an error */
301 if( x != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200303
Paul Bakker5121ce52009-01-03 21:22:43 +0000304 if( src[i] == '=' && ++j > 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000306
Paul Elliott419983d2021-03-01 18:33:09 +0000307 dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), src[i] );
308
309 if( src[i] > 127 || dec_map_lookup == 127 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200310 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000311
Paul Elliott419983d2021-03-01 18:33:09 +0000312 if( dec_map_lookup < 64 && j != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200313 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000314
315 n++;
316 }
317
318 if( n == 0 )
Simon Butchera45aa132015-10-05 00:26:36 +0100319 {
320 *olen = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000321 return( 0 );
Simon Butchera45aa132015-10-05 00:26:36 +0100322 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000323
Simon Butchera29c5e9e2017-02-02 08:46:53 +0000324 /* The following expression is to calculate the following formula without
325 * risk of integer overflow in n:
326 * n = ( ( n * 6 ) + 7 ) >> 3;
327 */
Andres AG4623d832017-01-18 17:21:03 +0000328 n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 );
Paul Bakkerd5983182014-07-04 13:50:31 +0200329 n -= j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000330
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100331 if( dst == NULL || dlen < n )
Paul Bakker5121ce52009-01-03 21:22:43 +0000332 {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100333 *olen = n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200334 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000335 }
336
337 for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
338 {
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200339 if( *src == '\r' || *src == '\n' || *src == ' ' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000340 continue;
341
Paul Elliott419983d2021-03-01 18:33:09 +0000342 dec_map_lookup = mbedtls_base64_table_lookup(base64_dec_map, sizeof( base64_dec_map ), *src );
343
Paul Elliottbd559622021-03-01 19:15:43 +0000344 mbedtls_base64_cond_assign_uint32( &j, j - 1, mbedtls_base64_eq( dec_map_lookup, 64 ) );
Paul Elliott419983d2021-03-01 18:33:09 +0000345 x = ( x << 6 ) | ( dec_map_lookup & 0x3F );
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
347 if( ++n == 4 )
348 {
349 n = 0;
350 if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
351 if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
352 if( j > 2 ) *p++ = (unsigned char)( x );
353 }
354 }
355
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100356 *olen = p - dst;
Paul Bakker5121ce52009-01-03 21:22:43 +0000357
358 return( 0 );
359}
360
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200361#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000362
Paul Bakker5121ce52009-01-03 21:22:43 +0000363static const unsigned char base64_test_dec[64] =
364{
365 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
366 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
367 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
368 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
369 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
370 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
371 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
372 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
373};
374
375static const unsigned char base64_test_enc[] =
376 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
377 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
378
379/*
380 * Checkup routine
381 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200382int mbedtls_base64_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000383{
Paul Bakker23986e52011-04-24 08:57:21 +0000384 size_t len;
Paul Bakker3c2122f2013-06-24 19:03:14 +0200385 const unsigned char *src;
386 unsigned char buffer[128];
Paul Bakker5121ce52009-01-03 21:22:43 +0000387
388 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 mbedtls_printf( " Base64 encoding test: " );
Paul Bakker5121ce52009-01-03 21:22:43 +0000390
Paul Bakker3c2122f2013-06-24 19:03:14 +0200391 src = base64_test_dec;
Paul Bakker5121ce52009-01-03 21:22:43 +0000392
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100393 if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 ||
Paul Bakker3c2122f2013-06-24 19:03:14 +0200394 memcmp( base64_test_enc, buffer, 88 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000395 {
396 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000398
399 return( 1 );
400 }
401
402 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403 mbedtls_printf( "passed\n Base64 decoding test: " );
Paul Bakker5121ce52009-01-03 21:22:43 +0000404
Paul Bakker3c2122f2013-06-24 19:03:14 +0200405 src = base64_test_enc;
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100407 if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 ||
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 memcmp( base64_test_dec, buffer, 64 ) != 0 )
409 {
410 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000412
413 return( 1 );
414 }
415
416 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417 mbedtls_printf( "passed\n\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000418
419 return( 0 );
420}
421
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000423
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424#endif /* MBEDTLS_BASE64_C */