packages: clean up the package folder
[openwrt.git] / package / utils / px5g / src / library / base64.c
1 /*
2  *  RFC 1521 base64 encoding/decoding
3  *
4  *  Based on XySSL: Copyright (C) 2006-2008  Christophe Devine
5  *
6  *  Copyright (C) 2009  Paul Bakker <polarssl_maintainer at polarssl dot org>
7  *
8  *  All rights reserved.
9  *
10  *  Redistribution and use in source and binary forms, with or without
11  *  modification, are permitted provided that the following conditions
12  *  are met:
13  *  
14  *    * Redistributions of source code must retain the above copyright
15  *      notice, this list of conditions and the following disclaimer.
16  *    * Redistributions in binary form must reproduce the above copyright
17  *      notice, this list of conditions and the following disclaimer in the
18  *      documentation and/or other materials provided with the distribution.
19  *    * Neither the names of PolarSSL or XySSL nor the names of its contributors
20  *      may be used to endorse or promote products derived from this software
21  *      without specific prior written permission.
22  *  
23  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 #include "polarssl/config.h"
37
38 #if defined(POLARSSL_BASE64_C)
39
40 #include "polarssl/base64.h"
41
42 static const unsigned char base64_enc_map[64] =
43 {
44     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
45     'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
46     'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
47     'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
48     'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
49     'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
50     '8', '9', '+', '/'
51 };
52
53 static const unsigned char base64_dec_map[128] =
54 {
55     127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
56     127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
57     127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
58     127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
59     127, 127, 127,  62, 127, 127, 127,  63,  52,  53,
60      54,  55,  56,  57,  58,  59,  60,  61, 127, 127,
61     127,  64, 127, 127, 127,   0,   1,   2,   3,   4,
62       5,   6,   7,   8,   9,  10,  11,  12,  13,  14,
63      15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
64      25, 127, 127, 127, 127, 127, 127,  26,  27,  28,
65      29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
66      39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
67      49,  50,  51, 127, 127, 127, 127, 127
68 };
69
70 /*
71  * Encode a buffer into base64 format
72  */
73 int base64_encode( unsigned char *dst, int *dlen,
74                    unsigned char *src, int  slen )
75 {
76     int i, n;
77     int C1, C2, C3;
78     unsigned char *p;
79
80     if( slen == 0 )
81         return( 0 );
82
83     n = (slen << 3) / 6;
84
85     switch( (slen << 3) - (n * 6) )
86     {
87         case  2: n += 3; break;
88         case  4: n += 2; break;
89         default: break;
90     }
91
92     if( *dlen < n + 1 )
93     {
94         *dlen = n + 1;
95         return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
96     }
97
98     n = (slen / 3) * 3;
99
100     for( i = 0, p = dst; i < n; i += 3 )
101     {
102         C1 = *src++;
103         C2 = *src++;
104         C3 = *src++;
105
106         *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
107         *p++ = base64_enc_map[(((C1 &  3) << 4) + (C2 >> 4)) & 0x3F];
108         *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
109         *p++ = base64_enc_map[C3 & 0x3F];
110     }
111
112     if( i < slen )
113     {
114         C1 = *src++;
115         C2 = ((i + 1) < slen) ? *src++ : 0;
116
117         *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
118         *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
119
120         if( (i + 1) < slen )
121              *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
122         else *p++ = '=';
123
124         *p++ = '=';
125     }
126
127     *dlen = p - dst;
128     *p = 0;
129
130     return( 0 );
131 }
132
133 /*
134  * Decode a base64-formatted buffer
135  */
136 int base64_decode( unsigned char *dst, int *dlen,
137                    unsigned char *src, int  slen )
138 {
139     int i, j, n;
140     unsigned long x;
141     unsigned char *p;
142
143     for( i = j = n = 0; i < slen; i++ )
144     {
145         if( ( slen - i ) >= 2 &&
146             src[i] == '\r' && src[i + 1] == '\n' )
147             continue;
148
149         if( src[i] == '\n' )
150             continue;
151
152         if( src[i] == '=' && ++j > 2 )
153             return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
154
155         if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
156             return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
157
158         if( base64_dec_map[src[i]] < 64 && j != 0 )
159             return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
160
161         n++;
162     }
163
164     if( n == 0 )
165         return( 0 );
166
167     n = ((n * 6) + 7) >> 3;
168
169     if( *dlen < n )
170     {
171         *dlen = n;
172         return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
173     }
174
175    for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
176    {
177         if( *src == '\r' || *src == '\n' )
178             continue;
179
180         j -= ( base64_dec_map[*src] == 64 );
181         x  = (x << 6) | ( base64_dec_map[*src] & 0x3F );
182
183         if( ++n == 4 )
184         {
185             n = 0;
186             if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
187             if( j > 1 ) *p++ = (unsigned char)( x >>  8 );
188             if( j > 2 ) *p++ = (unsigned char)( x       );
189         }
190     }
191
192     *dlen = p - dst;
193
194     return( 0 );
195 }
196
197 #if defined(POLARSSL_SELF_TEST)
198
199 #include <string.h>
200 #include <stdio.h>
201
202 static const unsigned char base64_test_dec[64] =
203 {
204     0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
205     0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
206     0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
207     0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
208     0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
209     0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
210     0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
211     0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
212 };
213
214 static const unsigned char base64_test_enc[] =
215     "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
216     "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
217
218 /*
219  * Checkup routine
220  */
221 int base64_self_test( int verbose )
222 {
223     int len;
224     unsigned char *src, buffer[128];
225
226     if( verbose != 0 )
227         printf( "  Base64 encoding test: " );
228
229     len = sizeof( buffer );
230     src = (unsigned char *) base64_test_dec;
231
232     if( base64_encode( buffer, &len, src, 64 ) != 0 ||
233          memcmp( base64_test_enc, buffer, 88 ) != 0 ) 
234     {
235         if( verbose != 0 )
236             printf( "failed\n" );
237
238         return( 1 );
239     }
240
241     if( verbose != 0 )
242         printf( "passed\n  Base64 decoding test: " );
243
244     len = sizeof( buffer );
245     src = (unsigned char *) base64_test_enc;
246
247     if( base64_decode( buffer, &len, src, 88 ) != 0 ||
248          memcmp( base64_test_dec, buffer, 64 ) != 0 )
249     {
250         if( verbose != 0 )
251             printf( "failed\n" );
252
253         return( 1 );
254     }
255
256     if( verbose != 0 )
257         printf( "passed\n\n" );
258
259     return( 0 );
260 }
261
262 #endif
263
264 #endif