2 * Copyright (C) 1996-2019 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
10 * Copied from Nettle 3.4 under GPLv2, with adjustments
16 #if !HAVE_NETTLE_BASE64_H || !HAVE_NETTLE34_BASE64
20 Copyright (C) 2002 Niels Möller
22 This file is part of GNU Nettle.
24 GNU Nettle is free software: you can redistribute it and/or
25 modify it under the terms of either:
27 * the GNU Lesser General Public License as published by the Free
28 Software Foundation; either version 3 of the License, or (at your
29 option) any later version.
33 * the GNU General Public License as published by the Free
34 Software Foundation; either version 2 of the License, or (at your
35 option) any later version.
37 or both in parallel, as here.
39 GNU Nettle is distributed in the hope that it will be useful,
40 but WITHOUT ANY WARRANTY; without even the implied warranty of
41 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
42 General Public License for more details.
44 You should have received copies of the GNU General Public License and
45 the GNU Lesser General Public License along with this program. If
46 not, see http://www.gnu.org/licenses/.
49 #define TABLE_INVALID -1
50 #define TABLE_SPACE -2
54 base64_decode_init(struct base64_decode_ctx
*ctx
)
56 static const signed char base64_decode_table
[0x100] =
58 /* White space is HT, VT, FF, CR, LF and SPC */
59 -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1,
60 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
61 -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
62 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -3, -1, -1,
63 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
64 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
65 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
66 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
67 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
68 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
69 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
70 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
71 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
72 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
73 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
74 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
77 ctx
->word
= ctx
->bits
= ctx
->padding
= 0;
78 ctx
->table
= base64_decode_table
;
82 base64_decode_single(struct base64_decode_ctx
*ctx
,
86 int data
= ctx
->table
[(uint8_t) src
];
91 assert(data
>= 0 && data
< 0x40);
96 ctx
->word
= ctx
->word
<< 6 | data
;
102 dst
[0] = ctx
->word
>> ctx
->bits
;
114 /* There can be at most two padding characters. */
115 if (!ctx
->bits
|| ctx
->padding
> 2)
118 if (ctx
->word
& ( (1<<ctx
->bits
) - 1))
119 /* We shouldn't have any leftover bits */
129 base64_decode_update(struct base64_decode_ctx
*ctx
,
138 for (i
= 0, done
= 0; i
<src_length
; i
++)
139 switch(base64_decode_single(ctx
, dst
+ done
, src
[i
]))
152 assert(done
<= BASE64_DECODE_LENGTH(src_length
));
159 base64_decode_final(struct base64_decode_ctx
*ctx
)
161 return ctx
->bits
== 0;
164 /* base64-encode.c */
166 #define ENCODE(alphabet,x) ((alphabet)[0x3F & (x)])
169 encode_raw(const char *alphabet
,
170 char *dst
, size_t length
, const uint8_t *src
)
172 const uint8_t *in
= src
+ length
;
173 char *out
= dst
+ BASE64_ENCODE_RAW_LENGTH(length
);
175 unsigned left_over
= length
% 3;
185 *--out
= ENCODE(alphabet
, (in
[0] << 4));
189 *--out
= ENCODE(alphabet
, (in
[1] << 2));
190 *--out
= ENCODE(alphabet
, ((in
[0] << 4) | (in
[1] >> 4)));
196 *--out
= ENCODE(alphabet
, (in
[0] >> 2));
202 *--out
= ENCODE(alphabet
, (in
[2]));
203 *--out
= ENCODE(alphabet
, ((in
[1] << 2) | (in
[2] >> 6)));
204 *--out
= ENCODE(alphabet
, ((in
[0] << 4) | (in
[1] >> 4)));
205 *--out
= ENCODE(alphabet
, (in
[0] >> 2));
211 static const char base64_encode_table
[64] =
212 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
213 "abcdefghijklmnopqrstuvwxyz"
217 base64_encode_raw(char *dst
, size_t length
, const uint8_t *src
)
219 encode_raw(base64_encode_table
, dst
, length
, src
);
223 base64_encode_group(char *dst
, uint32_t group
)
225 *dst
++ = ENCODE(base64_encode_table
, (group
>> 18));
226 *dst
++ = ENCODE(base64_encode_table
, (group
>> 12));
227 *dst
++ = ENCODE(base64_encode_table
, (group
>> 6));
228 *dst
++ = ENCODE(base64_encode_table
, group
);
232 base64_encode_init(struct base64_encode_ctx
*ctx
)
234 ctx
->word
= ctx
->bits
= 0;
235 ctx
->alphabet
= base64_encode_table
;
238 /* Encodes a single byte. */
240 base64_encode_single(struct base64_encode_ctx
*ctx
,
245 unsigned word
= ctx
->word
<< 8 | src
;
246 unsigned bits
= ctx
->bits
+ 8;
251 dst
[done
++] = ENCODE(ctx
->alphabet
, (word
>> bits
));
262 /* Returns the number of output characters. DST should point to an
263 * area of size at least BASE64_ENCODE_LENGTH(length). */
265 base64_encode_update(struct base64_encode_ctx
*ctx
,
271 size_t left
= length
;
275 while (ctx
->bits
&& left
)
278 done
+= base64_encode_single(ctx
, dst
+ done
, *src
++);
281 left_over
= left
% 3;
282 bulk
= left
- left_over
;
288 encode_raw(ctx
->alphabet
, dst
+ done
, bulk
, src
);
289 done
+= BASE64_ENCODE_RAW_LENGTH(bulk
);
297 done
+= base64_encode_single(ctx
, dst
+ done
, *src
++);
300 assert(done
<= BASE64_ENCODE_LENGTH(length
));
305 /* DST should point to an area of size at least
306 * BASE64_ENCODE_FINAL_SIZE */
308 base64_encode_final(struct base64_encode_ctx
*ctx
,
312 unsigned bits
= ctx
->bits
;
316 dst
[done
++] = ENCODE(ctx
->alphabet
, (ctx
->word
<< (6 - ctx
->bits
)));
317 for (; bits
< 6; bits
+= 2)
323 assert(done
<= BASE64_ENCODE_FINAL_LENGTH
);
327 #endif /* !HAVE_NETTLE_BASE64_H || !HAVE_NETTLE34_BASE64 */