Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers base64.c Source File

base64.c

00001 /*
00002  *  RFC 1521 base64 encoding/decoding
00003  *
00004  *  Copyright (C) 2006-2014, Brainspark B.V.
00005  *
00006  *  This file is part of PolarSSL (http://www.polarssl.org)
00007  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
00008  *
00009  *  All rights reserved.
00010  *
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License along
00022  *  with this program; if not, write to the Free Software Foundation, Inc.,
00023  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00024  */
00025 
00026 #if !defined(POLARSSL_CONFIG_FILE)
00027 #include "polarssl/config.h"
00028 #else
00029 #include POLARSSL_CONFIG_FILE
00030 #endif
00031 
00032 #if defined(POLARSSL_BASE64_C)
00033 
00034 #include "polarssl/base64.h"
00035 
00036 #if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
00037 #include <basetsd.h>
00038 typedef UINT32 uint32_t;
00039 #else
00040 #include <inttypes.h>
00041 #endif
00042 
00043 #if defined(POLARSSL_PLATFORM_C)
00044 #include "polarssl/platform.h"
00045 #else
00046 #define polarssl_printf printf
00047 #endif
00048 
00049 static const unsigned char base64_enc_map[64] =
00050 {
00051     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
00052     'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
00053     'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
00054     'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
00055     'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
00056     'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
00057     '8', '9', '+', '/'
00058 };
00059 
00060 static const unsigned char base64_dec_map[128] =
00061 {
00062     127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
00063     127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
00064     127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
00065     127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
00066     127, 127, 127,  62, 127, 127, 127,  63,  52,  53,
00067      54,  55,  56,  57,  58,  59,  60,  61, 127, 127,
00068     127,  64, 127, 127, 127,   0,   1,   2,   3,   4,
00069       5,   6,   7,   8,   9,  10,  11,  12,  13,  14,
00070      15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
00071      25, 127, 127, 127, 127, 127, 127,  26,  27,  28,
00072      29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
00073      39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
00074      49,  50,  51, 127, 127, 127, 127, 127
00075 };
00076 
00077 /*
00078  * Encode a buffer into base64 format
00079  */
00080 int base64_encode( unsigned char *dst, size_t *dlen,
00081                    const unsigned char *src, size_t slen )
00082 {
00083     size_t i, n;
00084     int C1, C2, C3;
00085     unsigned char *p;
00086 
00087     if( slen == 0 )
00088         return( 0 );
00089 
00090     n = (slen << 3) / 6;
00091 
00092     switch( (slen << 3) - (n * 6) )
00093     {
00094         case  2: n += 3; break;
00095         case  4: n += 2; break;
00096         default: break;
00097     }
00098 
00099     if( *dlen < n + 1 )
00100     {
00101         *dlen = n + 1;
00102         return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
00103     }
00104 
00105     n = (slen / 3) * 3;
00106 
00107     for( i = 0, p = dst; i < n; i += 3 )
00108     {
00109         C1 = *src++;
00110         C2 = *src++;
00111         C3 = *src++;
00112 
00113         *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
00114         *p++ = base64_enc_map[(((C1 &  3) << 4) + (C2 >> 4)) & 0x3F];
00115         *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
00116         *p++ = base64_enc_map[C3 & 0x3F];
00117     }
00118 
00119     if( i < slen )
00120     {
00121         C1 = *src++;
00122         C2 = ((i + 1) < slen) ? *src++ : 0;
00123 
00124         *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
00125         *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
00126 
00127         if( (i + 1) < slen )
00128              *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
00129         else *p++ = '=';
00130 
00131         *p++ = '=';
00132     }
00133 
00134     *dlen = p - dst;
00135     *p = 0;
00136 
00137     return( 0 );
00138 }
00139 
00140 /*
00141  * Decode a base64-formatted buffer
00142  */
00143 int base64_decode( unsigned char *dst, size_t *dlen,
00144                    const unsigned char *src, size_t slen )
00145 {
00146     size_t i, n;
00147     uint32_t j, x;
00148     unsigned char *p;
00149 
00150     for( i = n = j = 0; i < slen; i++ )
00151     {
00152         if( ( slen - i ) >= 2 &&
00153             src[i] == '\r' && src[i + 1] == '\n' )
00154             continue;
00155 
00156         if( src[i] == '\n' )
00157             continue;
00158 
00159         if( src[i] == '=' && ++j > 2 )
00160             return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
00161 
00162         if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
00163             return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
00164 
00165         if( base64_dec_map[src[i]] < 64 && j != 0 )
00166             return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
00167 
00168         n++;
00169     }
00170 
00171     if( n == 0 )
00172         return( 0 );
00173 
00174     n = ((n * 6) + 7) >> 3;
00175 
00176     if( dst == NULL || *dlen < n )
00177     {
00178         *dlen = n;
00179         return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
00180     }
00181 
00182    for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
00183    {
00184         if( *src == '\r' || *src == '\n' )
00185             continue;
00186 
00187         j -= ( base64_dec_map[*src] == 64 );
00188         x  = (x << 6) | ( base64_dec_map[*src] & 0x3F );
00189 
00190         if( ++n == 4 )
00191         {
00192             n = 0;
00193             if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
00194             if( j > 1 ) *p++ = (unsigned char)( x >>  8 );
00195             if( j > 2 ) *p++ = (unsigned char)( x       );
00196         }
00197     }
00198 
00199     *dlen = p - dst;
00200 
00201     return( 0 );
00202 }
00203 
00204 #if defined(POLARSSL_SELF_TEST)
00205 
00206 #include <string.h>
00207 #include <stdio.h>
00208 
00209 static const unsigned char base64_test_dec[64] =
00210 {
00211     0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
00212     0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
00213     0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
00214     0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
00215     0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
00216     0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
00217     0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
00218     0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
00219 };
00220 
00221 static const unsigned char base64_test_enc[] =
00222     "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
00223     "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
00224 
00225 /*
00226  * Checkup routine
00227  */
00228 int base64_self_test( int verbose )
00229 {
00230     size_t len;
00231     const unsigned char *src;
00232     unsigned char buffer[128];
00233 
00234     if( verbose != 0 )
00235         polarssl_printf( "  Base64 encoding test: " );
00236 
00237     len = sizeof( buffer );
00238     src = base64_test_dec;
00239 
00240     if( base64_encode( buffer, &len, src, 64 ) != 0 ||
00241          memcmp( base64_test_enc, buffer, 88 ) != 0 )
00242     {
00243         if( verbose != 0 )
00244             polarssl_printf( "failed\n" );
00245 
00246         return( 1 );
00247     }
00248 
00249     if( verbose != 0 )
00250         polarssl_printf( "passed\n  Base64 decoding test: " );
00251 
00252     len = sizeof( buffer );
00253     src = base64_test_enc;
00254 
00255     if( base64_decode( buffer, &len, src, 88 ) != 0 ||
00256          memcmp( base64_test_dec, buffer, 64 ) != 0 )
00257     {
00258         if( verbose != 0 )
00259             polarssl_printf( "failed\n" );
00260 
00261         return( 1 );
00262     }
00263 
00264     if( verbose != 0 )
00265         polarssl_printf( "passed\n\n" );
00266 
00267     return( 0 );
00268 }
00269 
00270 #endif /* POLARSSL_SELF_TEST */
00271 
00272 #endif /* POLARSSL_BASE64_C */
00273 
00274