ReactOS 0.4.15-dev-7842-g558ab78
base64.c
Go to the documentation of this file.
1/*
2 * RFC 1521 base64 encoding/decoding
3 *
4 * Copyright The Mbed TLS Contributors
5 * 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:
12 *
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.
24 *
25 * **********
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 * **********
45 */
46
47#if !defined(MBEDTLS_CONFIG_FILE)
48#include "mbedtls/config.h"
49#else
50#include MBEDTLS_CONFIG_FILE
51#endif
52
53#if defined(MBEDTLS_BASE64_C)
54
55#include "mbedtls/base64.h"
56
57#include <stdint.h>
58
59#if defined(MBEDTLS_SELF_TEST)
60#include <string.h>
61#if defined(MBEDTLS_PLATFORM_C)
62#include "mbedtls/platform.h"
63#else
64#include <stdio.h>
65#define mbedtls_printf printf
66#endif /* MBEDTLS_PLATFORM_C */
67#endif /* MBEDTLS_SELF_TEST */
68
69static 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
97#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
98
99/*
100 * Constant flow conditional assignment to unsigned char
101 */
102static void mbedtls_base64_cond_assign_uchar( unsigned char * dest, const unsigned char * const src,
103 unsigned char condition )
104{
105 /* 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
111
112 /* Generate bitmask from condition, mask will either be 0xFF or 0 */
113 unsigned char mask = ( condition | -condition );
114 mask >>= 7;
115 mask = -mask;
116
117#if defined(_MSC_VER)
118#pragma warning( pop )
119#endif
120
121 *dest = ( ( *src ) & mask ) | ( ( *dest ) & ~mask );
122}
123
124/*
125 * Constant flow conditional assignment to uint_32
126 */
127static void mbedtls_base64_cond_assign_uint32( uint32_t * dest, const uint32_t src,
129{
130 /* 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
136
137 /* Generate bitmask from condition, mask will either be 0xFFFFFFFF or 0 */
139 mask >>= 31;
140 mask = -mask;
141
142#if defined(_MSC_VER)
143#pragma warning( pop )
144#endif
145
146 *dest = ( src & mask ) | ( ( *dest ) & ~mask );
147}
148
149/*
150 * Constant flow check for equality
151 */
152static unsigned char mbedtls_base64_eq( size_t in_a, size_t in_b )
153{
154 size_t difference = in_a ^ in_b;
155
156 /* 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
163 difference |= -difference;
164
165#if defined(_MSC_VER)
166#pragma warning( pop )
167#endif
168
169 /* cope with the varying size of size_t per platform */
170 difference >>= ( sizeof( difference ) * 8 - 1 );
171
172 return (unsigned char) ( 1 ^ difference );
173}
174
175/*
176 * Constant flow lookup into table.
177 */
178static unsigned char mbedtls_base64_table_lookup( const unsigned char * const table,
179 const size_t table_size, const size_t table_index )
180{
181 size_t i;
182 unsigned char result = 0;
183
184 for( i = 0; i < table_size; ++i )
185 {
186 mbedtls_base64_cond_assign_uchar( &result, &table[i], mbedtls_base64_eq( i, table_index ) );
187 }
188
189 return result;
190}
191
192/*
193 * Encode a buffer into base64 format
194 */
195int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
196 const unsigned char *src, size_t slen )
197{
198 size_t i, n;
199 int C1, C2, C3;
200 unsigned char *p;
201
202 if( slen == 0 )
203 {
204 *olen = 0;
205 return( 0 );
206 }
207
208 n = slen / 3 + ( slen % 3 != 0 );
209
210 if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 )
211 {
212 *olen = BASE64_SIZE_T_MAX;
214 }
215
216 n *= 4;
217
218 if( ( dlen < n + 1 ) || ( NULL == dst ) )
219 {
220 *olen = n + 1;
222 }
223
224 n = ( slen / 3 ) * 3;
225
226 for( i = 0, p = dst; i < n; i += 3 )
227 {
228 C1 = *src++;
229 C2 = *src++;
230 C3 = *src++;
231
232 *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 ) );
243 }
244
245 if( i < slen )
246 {
247 C1 = *src++;
248 C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
249
250 *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 ) );
255
256 if( ( i + 1 ) < slen )
257 *p++ = mbedtls_base64_table_lookup( base64_enc_map, sizeof( base64_enc_map ),
258 ( ( ( C2 & 15 ) << 2 ) & 0x3F ) );
259 else *p++ = '=';
260
261 *p++ = '=';
262 }
263
264 *olen = p - dst;
265 *p = 0;
266
267 return( 0 );
268}
269
270/*
271 * Decode a base64-formatted buffer
272 */
273int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
274 const unsigned char *src, size_t slen )
275{
276 size_t i, n;
277 uint32_t j, x;
278 unsigned char *p;
279 unsigned char dec_map_lookup;
280
281 /* First pass: check for validity and get output length */
282 for( i = n = j = 0; i < slen; i++ )
283 {
284 /* 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
296 if( ( slen - i ) >= 2 &&
297 src[i] == '\r' && src[i + 1] == '\n' )
298 continue;
299
300 if( src[i] == '\n' )
301 continue;
302
303 /* Space inside a line is an error */
304 if( x != 0 )
306
307 if( src[i] == '=' && ++j > 2 )
309
310 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 )
314
315 if( dec_map_lookup < 64 && j != 0 )
317
318 n++;
319 }
320
321 if( n == 0 )
322 {
323 *olen = 0;
324 return( 0 );
325 }
326
327 /* The following expression is to calculate the following formula without
328 * risk of integer overflow in n:
329 * n = ( ( n * 6 ) + 7 ) >> 3;
330 */
331 n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 );
332 n -= j;
333
334 if( dst == NULL || dlen < n )
335 {
336 *olen = n;
338 }
339
340 for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
341 {
342 if( *src == '\r' || *src == '\n' || *src == ' ' )
343 continue;
344
345 dec_map_lookup = mbedtls_base64_table_lookup( base64_dec_map, sizeof( base64_dec_map ), *src );
346
347 mbedtls_base64_cond_assign_uint32( &j, j - 1, mbedtls_base64_eq( dec_map_lookup, 64 ) );
348 x = ( x << 6 ) | ( dec_map_lookup & 0x3F );
349
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
359 *olen = p - dst;
360
361 return( 0 );
362}
363
364#if defined(MBEDTLS_SELF_TEST)
365
366static 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 */
385int mbedtls_base64_self_test( int verbose )
386{
387 size_t len;
388 const unsigned char *src;
389 unsigned char buffer[128];
390
391 if( verbose != 0 )
392 mbedtls_printf( " Base64 encoding test: " );
393
394 src = base64_test_dec;
395
396 if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 ||
397 memcmp( base64_test_enc, buffer, 88 ) != 0 )
398 {
399 if( verbose != 0 )
400 mbedtls_printf( "failed\n" );
401
402 return( 1 );
403 }
404
405 if( verbose != 0 )
406 mbedtls_printf( "passed\n Base64 decoding test: " );
407
408 src = base64_test_enc;
409
410 if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 ||
411 memcmp( base64_test_dec, buffer, 64 ) != 0 )
412 {
413 if( verbose != 0 )
414 mbedtls_printf( "failed\n" );
415
416 return( 1 );
417 }
418
419 if( verbose != 0 )
420 mbedtls_printf( "passed\n\n" );
421
422 return( 0 );
423}
424
425#endif /* MBEDTLS_SELF_TEST */
426
427#endif /* MBEDTLS_BASE64_C */
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
RFC 1521 base64 encoding/decoding.
int mbedtls_base64_decode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen)
Decode a base64-formatted buffer.
int mbedtls_base64_encode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen)
Encode a buffer into base64 format.
#define MBEDTLS_ERR_BASE64_INVALID_CHARACTER
Definition: base64.h:61
#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
Definition: base64.h:60
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
unsigned char
Definition: typeof.h:29
#define C2
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLdouble n
Definition: glext.h:7729
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLenum condition
Definition: glext.h:9255
GLenum GLint GLuint mask
Definition: glext.h:6028
GLenum GLenum dst
Definition: glext.h:6340
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static char * dest
Definition: rtl.c:135
#define verbose
Definition: rosglue.h:36
Configuration options (set of defines)
This file contains the definitions and functions of the Mbed TLS platform abstraction layer.
LOCAL int table_size
Definition: write.c:65
#define mbedtls_printf
Definition: timing.c:57