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