2 * Copyright (C) 1996-2017 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.0 under GPLv2, with adjustments
16 #if !HAVE_NETTLE_BASE64_H || !HAVE_NETTLE30_BASE64
22 static const uint8_t encode_table
[64] =
23 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
24 "abcdefghijklmnopqrstuvwxyz"
27 #define ENCODE(x) (encode_table[0x3F & (x)])
29 static const signed char decode_table
[0x100] =
31 /* White space is HT, VT, FF, CR, LF and SPC */
32 -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1,
33 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
34 -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
35 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -3, -1, -1,
36 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
37 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
38 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
39 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
40 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
41 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
42 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
43 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
44 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
45 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
46 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
50 #define TABLE_INVALID -1
51 #define TABLE_SPACE -2
54 #define BASE64_VALUE_SZ 256
55 int base64_value
[BASE64_VALUE_SZ
];
58 base64_decode_init(struct base64_decode_ctx
*ctx
)
60 ctx
->word
= ctx
->bits
= ctx
->padding
= 0;
64 base64_decode_single(struct base64_decode_ctx
*ctx
, uint8_t *dst
, uint8_t src
)
66 int data
= decode_table
[src
];
70 assert(data
>= 0 && data
< 0x40);
75 ctx
->word
= ctx
->word
<< 6 | data
;
80 dst
[0] = ctx
->word
>> ctx
->bits
;
92 /* There can be at most two padding characters. */
93 if (!ctx
->bits
|| ctx
->padding
> 2)
96 if (ctx
->word
& ( (1<<ctx
->bits
) - 1))
97 /* We shouldn't have any leftover bits */
107 base64_decode_update(struct base64_decode_ctx
*ctx
,
116 for (i
= 0, done
= 0; i
< src_length
; i
++) {
117 switch(base64_decode_single(ctx
, dst
+ done
, src
[i
])) {
130 assert(done
<= BASE64_DECODE_LENGTH(src_length
));
137 base64_decode_final(struct base64_decode_ctx
*ctx
)
139 return ctx
->bits
== 0;
143 base64_encode_raw(uint8_t *dst
, size_t length
, const uint8_t *src
)
145 const uint8_t *in
= src
+ length
;
146 uint8_t *out
= dst
+ BASE64_ENCODE_RAW_LENGTH(length
);
148 unsigned left_over
= length
% 3;
156 *--out
= ENCODE(in
[0] << 4);
160 *--out
= ENCODE( in
[1] << 2);
161 *--out
= ENCODE((in
[0] << 4) | (in
[1] >> 4));
167 *--out
= ENCODE(in
[0] >> 2);
172 *--out
= ENCODE( in
[2]);
173 *--out
= ENCODE((in
[1] << 2) | (in
[2] >> 6));
174 *--out
= ENCODE((in
[0] << 4) | (in
[1] >> 4));
175 *--out
= ENCODE( in
[0] >> 2);
182 base64_encode_init(struct base64_encode_ctx
*ctx
)
184 ctx
->word
= ctx
->bits
= 0;
187 /* Encodes a single byte. */
189 base64_encode_single(struct base64_encode_ctx
*ctx
,
194 unsigned word
= ctx
->word
<< 8 | src
;
195 unsigned bits
= ctx
->bits
+ 8;
199 dst
[done
++] = ENCODE(word
>> bits
);
210 /* Returns the number of output characters. DST should point to an
211 * area of size at least BASE64_ENCODE_LENGTH(length). */
213 base64_encode_update(struct base64_encode_ctx
*ctx
,
219 size_t left
= length
;
223 while (ctx
->bits
&& left
) {
225 done
+= base64_encode_single(ctx
, dst
+ done
, *src
++);
228 left_over
= left
% 3;
229 bulk
= left
- left_over
;
234 base64_encode_raw(dst
+ done
, bulk
, src
);
235 done
+= BASE64_ENCODE_RAW_LENGTH(bulk
);
242 done
+= base64_encode_single(ctx
, dst
+ done
, *src
++);
245 assert(done
<= BASE64_ENCODE_LENGTH(length
));
250 /* DST should point to an area of size at least
251 * BASE64_ENCODE_FINAL_SIZE */
253 base64_encode_final(struct base64_encode_ctx
*ctx
,
257 unsigned bits
= ctx
->bits
;
260 dst
[done
++] = ENCODE(ctx
->word
<< (6 - ctx
->bits
));
261 for (; bits
< 6; bits
+= 2)
267 assert(done
<= BASE64_ENCODE_FINAL_LENGTH
);
271 #endif /* !HAVE_NETTLE_BASE64_H || !HAVE_NETTLE30_BASE64 */