Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
base64.c
00001 /* 00002 * RFC 1521 base64 encoding/decoding 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 00022 #if !defined(MBEDTLS_CONFIG_FILE) 00023 #include "mbedtls/config.h" 00024 #else 00025 #include MBEDTLS_CONFIG_FILE 00026 #endif 00027 00028 #if defined(MBEDTLS_BASE64_C) 00029 00030 #include "mbedtls/base64.h" 00031 00032 #include <stdint.h> 00033 00034 #if defined(MBEDTLS_SELF_TEST) 00035 #include <string.h> 00036 #if defined(MBEDTLS_PLATFORM_C) 00037 #include "mbedtls/platform.h" 00038 #else 00039 #include <stdio.h> 00040 #define mbedtls_printf printf 00041 #endif /* MBEDTLS_PLATFORM_C */ 00042 #endif /* MBEDTLS_SELF_TEST */ 00043 00044 static const unsigned char base64_enc_map[64] = 00045 { 00046 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 00047 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 00048 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 00049 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 00050 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 00051 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', 00052 '8', '9', '+', '/' 00053 }; 00054 00055 static const unsigned char base64_dec_map[128] = 00056 { 00057 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 00058 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 00059 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 00060 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 00061 127, 127, 127, 62, 127, 127, 127, 63, 52, 53, 00062 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, 00063 127, 64, 127, 127, 127, 0, 1, 2, 3, 4, 00064 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 00065 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 00066 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, 00067 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 00068 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 00069 49, 50, 51, 127, 127, 127, 127, 127 00070 }; 00071 00072 #define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ 00073 00074 /* 00075 * Encode a buffer into base64 format 00076 */ 00077 int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, 00078 const unsigned char *src, size_t slen ) 00079 { 00080 size_t i, n; 00081 int C1, C2, C3; 00082 unsigned char *p; 00083 00084 if( slen == 0 ) 00085 { 00086 *olen = 0; 00087 return( 0 ); 00088 } 00089 00090 n = slen / 3 + ( slen % 3 != 0 ); 00091 00092 if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 ) 00093 { 00094 *olen = BASE64_SIZE_T_MAX; 00095 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); 00096 } 00097 00098 n *= 4; 00099 00100 if( ( dlen < n + 1 ) || ( NULL == dst ) ) 00101 { 00102 *olen = n + 1; 00103 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); 00104 } 00105 00106 n = ( slen / 3 ) * 3; 00107 00108 for( i = 0, p = dst; i < n; i += 3 ) 00109 { 00110 C1 = *src++; 00111 C2 = *src++; 00112 C3 = *src++; 00113 00114 *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; 00115 *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; 00116 *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; 00117 *p++ = base64_enc_map[C3 & 0x3F]; 00118 } 00119 00120 if( i < slen ) 00121 { 00122 C1 = *src++; 00123 C2 = ( ( i + 1 ) < slen ) ? *src++ : 0; 00124 00125 *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; 00126 *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; 00127 00128 if( ( i + 1 ) < slen ) 00129 *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; 00130 else *p++ = '='; 00131 00132 *p++ = '='; 00133 } 00134 00135 *olen = p - dst; 00136 *p = 0; 00137 00138 return( 0 ); 00139 } 00140 00141 /* 00142 * Decode a base64-formatted buffer 00143 */ 00144 int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, 00145 const unsigned char *src, size_t slen ) 00146 { 00147 size_t i, n; 00148 uint32_t j, x; 00149 unsigned char *p; 00150 00151 /* First pass: check for validity and get output length */ 00152 for( i = n = j = 0; i < slen; i++ ) 00153 { 00154 /* Skip spaces before checking for EOL */ 00155 x = 0; 00156 while( i < slen && src[i] == ' ' ) 00157 { 00158 ++i; 00159 ++x; 00160 } 00161 00162 /* Spaces at end of buffer are OK */ 00163 if( i == slen ) 00164 break; 00165 00166 if( ( slen - i ) >= 2 && 00167 src[i] == '\r' && src[i + 1] == '\n' ) 00168 continue; 00169 00170 if( src[i] == '\n' ) 00171 continue; 00172 00173 /* Space inside a line is an error */ 00174 if( x != 0 ) 00175 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); 00176 00177 if( src[i] == '=' && ++j > 2 ) 00178 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); 00179 00180 if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) 00181 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); 00182 00183 if( base64_dec_map[src[i]] < 64 && j != 0 ) 00184 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); 00185 00186 n++; 00187 } 00188 00189 if( n == 0 ) 00190 { 00191 *olen = 0; 00192 return( 0 ); 00193 } 00194 00195 /* The following expression is to calculate the following formula without 00196 * risk of integer overflow in n: 00197 * n = ( ( n * 6 ) + 7 ) >> 3; 00198 */ 00199 n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 ); 00200 n -= j; 00201 00202 if( dst == NULL || dlen < n ) 00203 { 00204 *olen = n; 00205 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); 00206 } 00207 00208 for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) 00209 { 00210 if( *src == '\r' || *src == '\n' || *src == ' ' ) 00211 continue; 00212 00213 j -= ( base64_dec_map[*src] == 64 ); 00214 x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F ); 00215 00216 if( ++n == 4 ) 00217 { 00218 n = 0; 00219 if( j > 0 ) *p++ = (unsigned char)( x >> 16 ); 00220 if( j > 1 ) *p++ = (unsigned char)( x >> 8 ); 00221 if( j > 2 ) *p++ = (unsigned char)( x ); 00222 } 00223 } 00224 00225 *olen = p - dst; 00226 00227 return( 0 ); 00228 } 00229 00230 #if defined(MBEDTLS_SELF_TEST) 00231 00232 static const unsigned char base64_test_dec[64] = 00233 { 00234 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD, 00235 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01, 00236 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09, 00237 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13, 00238 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31, 00239 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38, 00240 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B, 00241 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97 00242 }; 00243 00244 static const unsigned char base64_test_enc[] = 00245 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK" 00246 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw=="; 00247 00248 /* 00249 * Checkup routine 00250 */ 00251 int mbedtls_base64_self_test( int verbose ) 00252 { 00253 size_t len; 00254 const unsigned char *src; 00255 unsigned char buffer[128]; 00256 00257 if( verbose != 0 ) 00258 mbedtls_printf( " Base64 encoding test: " ); 00259 00260 src = base64_test_dec; 00261 00262 if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 || 00263 memcmp( base64_test_enc, buffer, 88 ) != 0 ) 00264 { 00265 if( verbose != 0 ) 00266 mbedtls_printf( "failed\n" ); 00267 00268 return( 1 ); 00269 } 00270 00271 if( verbose != 0 ) 00272 mbedtls_printf( "passed\n Base64 decoding test: " ); 00273 00274 src = base64_test_enc; 00275 00276 if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 || 00277 memcmp( base64_test_dec, buffer, 64 ) != 0 ) 00278 { 00279 if( verbose != 0 ) 00280 mbedtls_printf( "failed\n" ); 00281 00282 return( 1 ); 00283 } 00284 00285 if( verbose != 0 ) 00286 mbedtls_printf( "passed\n\n" ); 00287 00288 return( 0 ); 00289 } 00290 00291 #endif /* MBEDTLS_SELF_TEST */ 00292 00293 #endif /* MBEDTLS_BASE64_C */
Generated on Sun Jul 17 2022 08:25:20 by 1.7.2