tizen 2.4 release
[external/nettle.git] / base64-decode.c
1 /* base64-encode.c
2  *
3  */
4
5 /* nettle, low-level cryptographics library
6  *
7  * Copyright (C) 2002 Niels Möller
8  *  
9  * The nettle library is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or (at your
12  * option) any later version.
13  * 
14  * The nettle library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
17  * License for more details.
18  * 
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with the nettle library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22  * MA 02111-1301, USA.
23  */
24
25 #if HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <assert.h>
30 #include <stdlib.h>
31
32 #include "base64.h"
33
34 #define TABLE_INVALID -1
35 #define TABLE_SPACE -2
36 #define TABLE_END -3
37
38 static const signed char
39 decode_table[0x100] =
40 {
41   /* White space is HT, VT, FF, CR, LF and SPC */
42   -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1, 
43   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
44   -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
45   52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -3, -1, -1,
46   -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
47   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
48   -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
49   41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
50   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
51   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
52   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
53   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
54   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
55   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
56   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
57   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
58 };
59
60 void
61 base64_decode_init(struct base64_decode_ctx *ctx)
62 {
63   ctx->word = ctx->bits = ctx->padding = 0;
64 }
65
66 int
67 base64_decode_single(struct base64_decode_ctx *ctx,
68                      uint8_t *dst,
69                      uint8_t src)
70 {
71   int data;
72   
73   data = decode_table[src];
74
75   switch(data)
76     {
77     default:
78       assert(data >= 0 && data < 0x40);
79
80       if (ctx->padding)
81         return -1;
82       
83       ctx->word = ctx->word << 6 | data;
84       ctx->bits += 6;
85
86       if (ctx->bits >= 8)
87         {
88           ctx->bits -= 8;
89           dst[0] = ctx->word >> ctx->bits;
90           return 1;
91         }
92       else return 0;
93
94     case TABLE_INVALID:
95       return -1;
96
97     case TABLE_SPACE:
98       return 0;
99       
100     case TABLE_END:
101       /* There can be at most two padding characters. */
102       if (!ctx->bits || ctx->padding > 2)
103         return -1;
104       
105       if (ctx->word & ( (1<<ctx->bits) - 1))
106         /* We shouldn't have any leftover bits */
107         return -1;
108
109       ctx->padding++;
110       ctx->bits -= 2;
111       return 0;
112     }
113 }
114
115 int
116 base64_decode_update(struct base64_decode_ctx *ctx,
117                      unsigned *dst_length,
118                      uint8_t *dst,
119                      unsigned src_length,
120                      const uint8_t *src)
121 {
122   unsigned done;
123   unsigned i;
124
125   assert(*dst_length >= BASE64_DECODE_LENGTH(src_length));
126   
127   for (i = 0, done = 0; i<src_length; i++)
128     switch(base64_decode_single(ctx, dst + done, src[i]))
129       {
130       case -1:
131         return 0;
132       case 1:
133         done++;
134         /* Fall through */
135       case 0:
136         break;
137       default:
138         abort();
139       }
140   
141   assert(done <= BASE64_DECODE_LENGTH(src_length));
142
143   *dst_length = done;
144   return 1;
145 }
146
147 int
148 base64_decode_final(struct base64_decode_ctx *ctx)
149 {
150   return ctx->bits == 0;
151 }