xref: /optee_os/lib/libmbedtls/mbedtls/library/base64.c (revision 7901324d9530594155991c8b283023d567741cc7)
1817466cbSJens Wiklander /*
2817466cbSJens Wiklander  *  RFC 1521 base64 encoding/decoding
3817466cbSJens Wiklander  *
4*7901324dSJerome Forissier  *  Copyright The Mbed TLS Contributors
5*7901324dSJerome Forissier  *  SPDX-License-Identifier: Apache-2.0
6817466cbSJens Wiklander  *
7817466cbSJens Wiklander  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
8817466cbSJens Wiklander  *  not use this file except in compliance with the License.
9817466cbSJens Wiklander  *  You may obtain a copy of the License at
10817466cbSJens Wiklander  *
11817466cbSJens Wiklander  *  http://www.apache.org/licenses/LICENSE-2.0
12817466cbSJens Wiklander  *
13817466cbSJens Wiklander  *  Unless required by applicable law or agreed to in writing, software
14817466cbSJens Wiklander  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15817466cbSJens Wiklander  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16817466cbSJens Wiklander  *  See the License for the specific language governing permissions and
17817466cbSJens Wiklander  *  limitations under the License.
18817466cbSJens Wiklander  */
19817466cbSJens Wiklander 
20*7901324dSJerome Forissier #include "common.h"
21817466cbSJens Wiklander 
22817466cbSJens Wiklander #if defined(MBEDTLS_BASE64_C)
23817466cbSJens Wiklander 
24817466cbSJens Wiklander #include "mbedtls/base64.h"
25817466cbSJens Wiklander 
26817466cbSJens Wiklander #include <stdint.h>
27817466cbSJens Wiklander 
28817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST)
29817466cbSJens Wiklander #include <string.h>
30817466cbSJens Wiklander #if defined(MBEDTLS_PLATFORM_C)
31817466cbSJens Wiklander #include "mbedtls/platform.h"
32817466cbSJens Wiklander #else
33817466cbSJens Wiklander #include <stdio.h>
34817466cbSJens Wiklander #define mbedtls_printf printf
35817466cbSJens Wiklander #endif /* MBEDTLS_PLATFORM_C */
36817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */
37817466cbSJens Wiklander 
38817466cbSJens Wiklander static const unsigned char base64_enc_map[64] =
39817466cbSJens Wiklander {
40817466cbSJens Wiklander     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
41817466cbSJens Wiklander     'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
42817466cbSJens Wiklander     'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
43817466cbSJens Wiklander     'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
44817466cbSJens Wiklander     'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
45817466cbSJens Wiklander     'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
46817466cbSJens Wiklander     '8', '9', '+', '/'
47817466cbSJens Wiklander };
48817466cbSJens Wiklander 
49817466cbSJens Wiklander static const unsigned char base64_dec_map[128] =
50817466cbSJens Wiklander {
51817466cbSJens Wiklander     127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
52817466cbSJens Wiklander     127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
53817466cbSJens Wiklander     127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
54817466cbSJens Wiklander     127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
55817466cbSJens Wiklander     127, 127, 127,  62, 127, 127, 127,  63,  52,  53,
56817466cbSJens Wiklander      54,  55,  56,  57,  58,  59,  60,  61, 127, 127,
57817466cbSJens Wiklander     127,  64, 127, 127, 127,   0,   1,   2,   3,   4,
58817466cbSJens Wiklander       5,   6,   7,   8,   9,  10,  11,  12,  13,  14,
59817466cbSJens Wiklander      15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
60817466cbSJens Wiklander      25, 127, 127, 127, 127, 127, 127,  26,  27,  28,
61817466cbSJens Wiklander      29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
62817466cbSJens Wiklander      39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
63817466cbSJens Wiklander      49,  50,  51, 127, 127, 127, 127, 127
64817466cbSJens Wiklander };
65817466cbSJens Wiklander 
66817466cbSJens Wiklander #define BASE64_SIZE_T_MAX   ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
67817466cbSJens Wiklander 
68817466cbSJens Wiklander /*
69*7901324dSJerome Forissier  * Constant flow conditional assignment to unsigned char
70*7901324dSJerome Forissier  */
71*7901324dSJerome Forissier static void mbedtls_base64_cond_assign_uchar( unsigned char * dest, const unsigned char * const src,
72*7901324dSJerome Forissier                                        unsigned char condition )
73*7901324dSJerome Forissier {
74*7901324dSJerome Forissier     /* MSVC has a warning about unary minus on unsigned integer types,
75*7901324dSJerome Forissier      * but this is well-defined and precisely what we want to do here. */
76*7901324dSJerome Forissier #if defined(_MSC_VER)
77*7901324dSJerome Forissier #pragma warning( push )
78*7901324dSJerome Forissier #pragma warning( disable : 4146 )
79*7901324dSJerome Forissier #endif
80*7901324dSJerome Forissier 
81*7901324dSJerome Forissier     /* Generate bitmask from condition, mask will either be 0xFF or 0 */
82*7901324dSJerome Forissier     unsigned char mask = ( condition | -condition );
83*7901324dSJerome Forissier     mask >>= 7;
84*7901324dSJerome Forissier     mask = -mask;
85*7901324dSJerome Forissier 
86*7901324dSJerome Forissier #if defined(_MSC_VER)
87*7901324dSJerome Forissier #pragma warning( pop )
88*7901324dSJerome Forissier #endif
89*7901324dSJerome Forissier 
90*7901324dSJerome Forissier     *dest = ( ( *src ) & mask ) | ( ( *dest ) & ~mask );
91*7901324dSJerome Forissier }
92*7901324dSJerome Forissier 
93*7901324dSJerome Forissier /*
94*7901324dSJerome Forissier  * Constant flow conditional assignment to uint_32
95*7901324dSJerome Forissier  */
96*7901324dSJerome Forissier static void mbedtls_base64_cond_assign_uint32( uint32_t * dest, const uint32_t src,
97*7901324dSJerome Forissier                                        uint32_t condition )
98*7901324dSJerome Forissier {
99*7901324dSJerome Forissier     /* MSVC has a warning about unary minus on unsigned integer types,
100*7901324dSJerome Forissier      * but this is well-defined and precisely what we want to do here. */
101*7901324dSJerome Forissier #if defined(_MSC_VER)
102*7901324dSJerome Forissier #pragma warning( push )
103*7901324dSJerome Forissier #pragma warning( disable : 4146 )
104*7901324dSJerome Forissier #endif
105*7901324dSJerome Forissier 
106*7901324dSJerome Forissier     /* Generate bitmask from condition, mask will either be 0xFFFFFFFF or 0 */
107*7901324dSJerome Forissier     uint32_t mask = ( condition | -condition );
108*7901324dSJerome Forissier     mask >>= 31;
109*7901324dSJerome Forissier     mask = -mask;
110*7901324dSJerome Forissier 
111*7901324dSJerome Forissier #if defined(_MSC_VER)
112*7901324dSJerome Forissier #pragma warning( pop )
113*7901324dSJerome Forissier #endif
114*7901324dSJerome Forissier 
115*7901324dSJerome Forissier     *dest = ( src & mask ) | ( ( *dest ) & ~mask );
116*7901324dSJerome Forissier }
117*7901324dSJerome Forissier 
118*7901324dSJerome Forissier /*
119*7901324dSJerome Forissier  * Constant flow check for equality
120*7901324dSJerome Forissier  */
121*7901324dSJerome Forissier static unsigned char mbedtls_base64_eq( size_t in_a, size_t in_b )
122*7901324dSJerome Forissier {
123*7901324dSJerome Forissier     size_t difference = in_a ^ in_b;
124*7901324dSJerome Forissier 
125*7901324dSJerome Forissier     /* MSVC has a warning about unary minus on unsigned integer types,
126*7901324dSJerome Forissier      * but this is well-defined and precisely what we want to do here. */
127*7901324dSJerome Forissier #if defined(_MSC_VER)
128*7901324dSJerome Forissier #pragma warning( push )
129*7901324dSJerome Forissier #pragma warning( disable : 4146 )
130*7901324dSJerome Forissier #endif
131*7901324dSJerome Forissier 
132*7901324dSJerome Forissier     difference |= -difference;
133*7901324dSJerome Forissier 
134*7901324dSJerome Forissier #if defined(_MSC_VER)
135*7901324dSJerome Forissier #pragma warning( pop )
136*7901324dSJerome Forissier #endif
137*7901324dSJerome Forissier 
138*7901324dSJerome Forissier     /* cope with the varying size of size_t per platform */
139*7901324dSJerome Forissier     difference >>= ( sizeof( difference ) * 8 - 1 );
140*7901324dSJerome Forissier 
141*7901324dSJerome Forissier     return (unsigned char) ( 1 ^ difference );
142*7901324dSJerome Forissier }
143*7901324dSJerome Forissier 
144*7901324dSJerome Forissier /*
145*7901324dSJerome Forissier  * Constant flow lookup into table.
146*7901324dSJerome Forissier  */
147*7901324dSJerome Forissier static unsigned char mbedtls_base64_table_lookup( const unsigned char * const table,
148*7901324dSJerome Forissier                                                  const size_t table_size, const size_t table_index )
149*7901324dSJerome Forissier {
150*7901324dSJerome Forissier     size_t i;
151*7901324dSJerome Forissier     unsigned char result = 0;
152*7901324dSJerome Forissier 
153*7901324dSJerome Forissier     for( i = 0; i < table_size; ++i )
154*7901324dSJerome Forissier     {
155*7901324dSJerome Forissier         mbedtls_base64_cond_assign_uchar( &result, &table[i], mbedtls_base64_eq( i, table_index ) );
156*7901324dSJerome Forissier     }
157*7901324dSJerome Forissier 
158*7901324dSJerome Forissier     return result;
159*7901324dSJerome Forissier }
160*7901324dSJerome Forissier 
161*7901324dSJerome Forissier /*
162817466cbSJens Wiklander  * Encode a buffer into base64 format
163817466cbSJens Wiklander  */
164817466cbSJens Wiklander int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
165817466cbSJens Wiklander                    const unsigned char *src, size_t slen )
166817466cbSJens Wiklander {
167817466cbSJens Wiklander     size_t i, n;
168817466cbSJens Wiklander     int C1, C2, C3;
169817466cbSJens Wiklander     unsigned char *p;
170817466cbSJens Wiklander 
171817466cbSJens Wiklander     if( slen == 0 )
172817466cbSJens Wiklander     {
173817466cbSJens Wiklander         *olen = 0;
174817466cbSJens Wiklander         return( 0 );
175817466cbSJens Wiklander     }
176817466cbSJens Wiklander 
177817466cbSJens Wiklander     n = slen / 3 + ( slen % 3 != 0 );
178817466cbSJens Wiklander 
179817466cbSJens Wiklander     if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 )
180817466cbSJens Wiklander     {
181817466cbSJens Wiklander         *olen = BASE64_SIZE_T_MAX;
182817466cbSJens Wiklander         return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
183817466cbSJens Wiklander     }
184817466cbSJens Wiklander 
185817466cbSJens Wiklander     n *= 4;
186817466cbSJens Wiklander 
187817466cbSJens Wiklander     if( ( dlen < n + 1 ) || ( NULL == dst ) )
188817466cbSJens Wiklander     {
189817466cbSJens Wiklander         *olen = n + 1;
190817466cbSJens Wiklander         return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
191817466cbSJens Wiklander     }
192817466cbSJens Wiklander 
193817466cbSJens Wiklander     n = ( slen / 3 ) * 3;
194817466cbSJens Wiklander 
195817466cbSJens Wiklander     for( i = 0, p = dst; i < n; i += 3 )
196817466cbSJens Wiklander     {
197817466cbSJens Wiklander         C1 = *src++;
198817466cbSJens Wiklander         C2 = *src++;
199817466cbSJens Wiklander         C3 = *src++;
200817466cbSJens Wiklander 
201*7901324dSJerome Forissier         *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
202*7901324dSJerome Forissier                                             ( ( C1 >> 2 ) & 0x3F ) );
203*7901324dSJerome Forissier 
204*7901324dSJerome Forissier         *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
205*7901324dSJerome Forissier                                             ( ( ( ( C1 &  3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
206*7901324dSJerome Forissier 
207*7901324dSJerome Forissier         *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
208*7901324dSJerome Forissier                                             ( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F ) );
209*7901324dSJerome Forissier 
210*7901324dSJerome Forissier         *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
211*7901324dSJerome Forissier                                             ( C3 & 0x3F ) );
212817466cbSJens Wiklander     }
213817466cbSJens Wiklander 
214817466cbSJens Wiklander     if( i < slen )
215817466cbSJens Wiklander     {
216817466cbSJens Wiklander         C1 = *src++;
217817466cbSJens Wiklander         C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
218817466cbSJens Wiklander 
219*7901324dSJerome Forissier         *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
220*7901324dSJerome Forissier                                             ( ( C1 >> 2 ) & 0x3F ) );
221*7901324dSJerome Forissier 
222*7901324dSJerome Forissier         *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
223*7901324dSJerome Forissier                                             ( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F ) );
224817466cbSJens Wiklander 
225817466cbSJens Wiklander         if( ( i + 1 ) < slen )
226*7901324dSJerome Forissier              *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
227*7901324dSJerome Forissier                                                  ( ( ( C2 & 15 ) << 2 ) & 0x3F ) );
228817466cbSJens Wiklander         else *p++ = '=';
229817466cbSJens Wiklander 
230817466cbSJens Wiklander         *p++ = '=';
231817466cbSJens Wiklander     }
232817466cbSJens Wiklander 
233817466cbSJens Wiklander     *olen = p - dst;
234817466cbSJens Wiklander     *p = 0;
235817466cbSJens Wiklander 
236817466cbSJens Wiklander     return( 0 );
237817466cbSJens Wiklander }
238817466cbSJens Wiklander 
239817466cbSJens Wiklander /*
240817466cbSJens Wiklander  * Decode a base64-formatted buffer
241817466cbSJens Wiklander  */
242817466cbSJens Wiklander int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
243817466cbSJens Wiklander                    const unsigned char *src, size_t slen )
244817466cbSJens Wiklander {
245817466cbSJens Wiklander     size_t i, n;
246817466cbSJens Wiklander     uint32_t j, x;
247817466cbSJens Wiklander     unsigned char *p;
248*7901324dSJerome Forissier     unsigned char dec_map_lookup;
249817466cbSJens Wiklander 
250817466cbSJens Wiklander     /* First pass: check for validity and get output length */
251817466cbSJens Wiklander     for( i = n = j = 0; i < slen; i++ )
252817466cbSJens Wiklander     {
253817466cbSJens Wiklander         /* Skip spaces before checking for EOL */
254817466cbSJens Wiklander         x = 0;
255817466cbSJens Wiklander         while( i < slen && src[i] == ' ' )
256817466cbSJens Wiklander         {
257817466cbSJens Wiklander             ++i;
258817466cbSJens Wiklander             ++x;
259817466cbSJens Wiklander         }
260817466cbSJens Wiklander 
261817466cbSJens Wiklander         /* Spaces at end of buffer are OK */
262817466cbSJens Wiklander         if( i == slen )
263817466cbSJens Wiklander             break;
264817466cbSJens Wiklander 
265817466cbSJens Wiklander         if( ( slen - i ) >= 2 &&
266817466cbSJens Wiklander             src[i] == '\r' && src[i + 1] == '\n' )
267817466cbSJens Wiklander             continue;
268817466cbSJens Wiklander 
269817466cbSJens Wiklander         if( src[i] == '\n' )
270817466cbSJens Wiklander             continue;
271817466cbSJens Wiklander 
272817466cbSJens Wiklander         /* Space inside a line is an error */
273817466cbSJens Wiklander         if( x != 0 )
274817466cbSJens Wiklander             return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
275817466cbSJens Wiklander 
276817466cbSJens Wiklander         if( src[i] == '=' && ++j > 2 )
277817466cbSJens Wiklander             return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
278817466cbSJens Wiklander 
279*7901324dSJerome Forissier         dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), src[i] );
280*7901324dSJerome Forissier 
281*7901324dSJerome Forissier         if( src[i] > 127 || dec_map_lookup == 127 )
282817466cbSJens Wiklander             return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
283817466cbSJens Wiklander 
284*7901324dSJerome Forissier         if( dec_map_lookup < 64 && j != 0 )
285817466cbSJens Wiklander             return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
286817466cbSJens Wiklander 
287817466cbSJens Wiklander         n++;
288817466cbSJens Wiklander     }
289817466cbSJens Wiklander 
290817466cbSJens Wiklander     if( n == 0 )
291817466cbSJens Wiklander     {
292817466cbSJens Wiklander         *olen = 0;
293817466cbSJens Wiklander         return( 0 );
294817466cbSJens Wiklander     }
295817466cbSJens Wiklander 
296817466cbSJens Wiklander     /* The following expression is to calculate the following formula without
297817466cbSJens Wiklander      * risk of integer overflow in n:
298817466cbSJens Wiklander      *     n = ( ( n * 6 ) + 7 ) >> 3;
299817466cbSJens Wiklander      */
300817466cbSJens Wiklander     n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 );
301817466cbSJens Wiklander     n -= j;
302817466cbSJens Wiklander 
303817466cbSJens Wiklander     if( dst == NULL || dlen < n )
304817466cbSJens Wiklander     {
305817466cbSJens Wiklander         *olen = n;
306817466cbSJens Wiklander         return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
307817466cbSJens Wiklander     }
308817466cbSJens Wiklander 
309817466cbSJens Wiklander    for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
310817466cbSJens Wiklander    {
311817466cbSJens Wiklander         if( *src == '\r' || *src == '\n' || *src == ' ' )
312817466cbSJens Wiklander             continue;
313817466cbSJens Wiklander 
314*7901324dSJerome Forissier         dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), *src );
315*7901324dSJerome Forissier 
316*7901324dSJerome Forissier         mbedtls_base64_cond_assign_uint32( &j, j - 1, mbedtls_base64_eq( dec_map_lookup, 64 ) );
317*7901324dSJerome Forissier         x  = ( x << 6 ) | ( dec_map_lookup & 0x3F );
318817466cbSJens Wiklander 
319817466cbSJens Wiklander         if( ++n == 4 )
320817466cbSJens Wiklander         {
321817466cbSJens Wiklander             n = 0;
322817466cbSJens Wiklander             if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
323817466cbSJens Wiklander             if( j > 1 ) *p++ = (unsigned char)( x >>  8 );
324817466cbSJens Wiklander             if( j > 2 ) *p++ = (unsigned char)( x       );
325817466cbSJens Wiklander         }
326817466cbSJens Wiklander     }
327817466cbSJens Wiklander 
328817466cbSJens Wiklander     *olen = p - dst;
329817466cbSJens Wiklander 
330817466cbSJens Wiklander     return( 0 );
331817466cbSJens Wiklander }
332817466cbSJens Wiklander 
333817466cbSJens Wiklander #if defined(MBEDTLS_SELF_TEST)
334817466cbSJens Wiklander 
335817466cbSJens Wiklander static const unsigned char base64_test_dec[64] =
336817466cbSJens Wiklander {
337817466cbSJens Wiklander     0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
338817466cbSJens Wiklander     0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
339817466cbSJens Wiklander     0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
340817466cbSJens Wiklander     0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
341817466cbSJens Wiklander     0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
342817466cbSJens Wiklander     0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
343817466cbSJens Wiklander     0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
344817466cbSJens Wiklander     0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
345817466cbSJens Wiklander };
346817466cbSJens Wiklander 
347817466cbSJens Wiklander static const unsigned char base64_test_enc[] =
348817466cbSJens Wiklander     "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
349817466cbSJens Wiklander     "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
350817466cbSJens Wiklander 
351817466cbSJens Wiklander /*
352817466cbSJens Wiklander  * Checkup routine
353817466cbSJens Wiklander  */
354817466cbSJens Wiklander int mbedtls_base64_self_test( int verbose )
355817466cbSJens Wiklander {
356817466cbSJens Wiklander     size_t len;
357817466cbSJens Wiklander     const unsigned char *src;
358817466cbSJens Wiklander     unsigned char buffer[128];
359817466cbSJens Wiklander 
360817466cbSJens Wiklander     if( verbose != 0 )
361817466cbSJens Wiklander         mbedtls_printf( "  Base64 encoding test: " );
362817466cbSJens Wiklander 
363817466cbSJens Wiklander     src = base64_test_dec;
364817466cbSJens Wiklander 
365817466cbSJens Wiklander     if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 ||
366817466cbSJens Wiklander          memcmp( base64_test_enc, buffer, 88 ) != 0 )
367817466cbSJens Wiklander     {
368817466cbSJens Wiklander         if( verbose != 0 )
369817466cbSJens Wiklander             mbedtls_printf( "failed\n" );
370817466cbSJens Wiklander 
371817466cbSJens Wiklander         return( 1 );
372817466cbSJens Wiklander     }
373817466cbSJens Wiklander 
374817466cbSJens Wiklander     if( verbose != 0 )
375817466cbSJens Wiklander         mbedtls_printf( "passed\n  Base64 decoding test: " );
376817466cbSJens Wiklander 
377817466cbSJens Wiklander     src = base64_test_enc;
378817466cbSJens Wiklander 
379817466cbSJens Wiklander     if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 ||
380817466cbSJens Wiklander          memcmp( base64_test_dec, buffer, 64 ) != 0 )
381817466cbSJens Wiklander     {
382817466cbSJens Wiklander         if( verbose != 0 )
383817466cbSJens Wiklander             mbedtls_printf( "failed\n" );
384817466cbSJens Wiklander 
385817466cbSJens Wiklander         return( 1 );
386817466cbSJens Wiklander     }
387817466cbSJens Wiklander 
388817466cbSJens Wiklander     if( verbose != 0 )
389817466cbSJens Wiklander         mbedtls_printf( "passed\n\n" );
390817466cbSJens Wiklander 
391817466cbSJens Wiklander     return( 0 );
392817466cbSJens Wiklander }
393817466cbSJens Wiklander 
394817466cbSJens Wiklander #endif /* MBEDTLS_SELF_TEST */
395817466cbSJens Wiklander 
396817466cbSJens Wiklander #endif /* MBEDTLS_BASE64_C */
397