1 /**
2 * Author......: See docs/credits.txt
3 * License.....: MIT
4 */
5
6 #include "common.h"
7 #include "types.h"
8 #include "convert.h"
9
10 /*
11 Source:
12 http://www.unicode.org/versions/Unicode7.0.0/UnicodeStandard-7.0.pdf
13 page 124, 3.9 "Unicode Encoding Forms", "UTF-8"
14
15 Table 3-7. Well-Formed UTF-8 Byte Sequences
16 -----------------------------------------------------------------------------
17 | Code Points | First Byte | Second Byte | Third Byte | Fourth Byte |
18 | U+0000..U+007F | 00..7F | | | |
19 | U+0080..U+07FF | C2..DF | 80..BF | | |
20 | U+0800..U+0FFF | E0 | A0..BF | 80..BF | |
21 | U+1000..U+CFFF | E1..EC | 80..BF | 80..BF | |
22 | U+D000..U+D7FF | ED | 80..9F | 80..BF | |
23 | U+E000..U+FFFF | EE..EF | 80..BF | 80..BF | |
24 | U+10000..U+3FFFF | F0 | 90..BF | 80..BF | 80..BF |
25 | U+40000..U+FFFFF | F1..F3 | 80..BF | 80..BF | 80..BF |
26 | U+100000..U+10FFFF | F4 | 80..8F | 80..BF | 80..BF |
27 -----------------------------------------------------------------------------
28 */
29
printable_utf8(const u8 * buf,const size_t len)30 static bool printable_utf8 (const u8 *buf, const size_t len)
31 {
32 // there's 9 different code point types for utf8 and ...
33
34 const int cp_types[256] =
35 {
36 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
37 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
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,
48 -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
49 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
50 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 5,
51 6, 7, 7, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
52 };
53
54 // ... they can be directly translated into a fixed length sequence of bytes
55
56 const size_t cp_lens[9] = { 1, 2, 3, 3, 3, 3, 4, 4, 4 };
57
58 for (size_t pos = 0; pos < len; pos++)
59 {
60 const u8 c0 = buf[pos];
61
62 const int cp_type = cp_types[c0];
63
64 if (cp_type == -1) return false;
65
66 // make sure to not read outside the buffer
67
68 const size_t cp_len = cp_lens[cp_type];
69
70 if ((pos + cp_len) > len) return false;
71
72 // multibyte from here
73
74 if (cp_len >= 2)
75 {
76 pos++;
77
78 const u8 c1 = buf[pos];
79
80 switch (cp_type)
81 {
82 case 2: if ((c1 < 0xa0) || (c1 > 0xbf)) return false; break;
83 case 4: if ((c1 < 0x80) || (c1 > 0x9f)) return false; break;
84 case 6: if ((c1 < 0x90) || (c1 > 0xbf)) return false; break;
85 case 8: if ((c1 < 0x80) || (c1 > 0x8f)) return false; break;
86 default: if ((c1 < 0x80) || (c1 > 0xbf)) return false; break;
87 }
88
89 for (size_t j = 2; j < cp_len; j++)
90 {
91 pos++;
92
93 const u8 cx = buf[pos];
94
95 if ((cx < 0x80) || (cx > 0xbf)) return false;
96 }
97 }
98 }
99
100 // another round in order to suppress some handpicked control characters from being printed to console
101 // taken from here: https://utf8-chartable.de/unicode-utf8-table.pl
102 // we could inline with the above loop but this way it's easier to understand
103
104 for (size_t pos = 0; pos < len; pos++)
105 {
106 const u8 c0 = buf[pos + 0];
107
108 if (c0 <= 0x1f) return false;
109 if (c0 == 0x7f) return false;
110
111 const size_t left = len - pos;
112
113 if (left >= 2)
114 {
115 const u8 c1 = buf[pos + 1];
116
117 if (c0 == 0xc2)
118 {
119 if ((c1 >= 0x80) && (c1 <= 0x9f)) return false;
120 }
121 }
122 }
123
124 return true;
125 }
126
printable_ascii(const u8 * buf,const size_t len)127 static bool printable_ascii (const u8 *buf, const size_t len)
128 {
129 for (size_t i = 0; i < len; i++)
130 {
131 const u8 c = buf[i];
132
133 if (c < 0x20) return false;
134 if (c > 0x7e) return false;
135 }
136
137 return true;
138 }
139
matches_separator(const u8 * buf,const size_t len,const char separator)140 static bool matches_separator (const u8 *buf, const size_t len, const char separator)
141 {
142 for (size_t i = 0; i < len; i++)
143 {
144 const char c = (char) buf[i];
145
146 if (c == separator) return true;
147 }
148
149 return false;
150 }
151
is_hexify(const u8 * buf,const size_t len)152 bool is_hexify (const u8 *buf, const size_t len)
153 {
154 if (len < 6) return false; // $HEX[] = 6
155
156 // length of the hex string must be a multiple of 2
157 // and the length of "$HEX[]" is 6 (also an even length)
158 // Therefore the overall length must be an even number:
159
160 if ((len & 1) == 1) return false;
161
162 if (buf[0] != '$') return (false);
163 if (buf[1] != 'H') return (false);
164 if (buf[2] != 'E') return (false);
165 if (buf[3] != 'X') return (false);
166 if (buf[4] != '[') return (false);
167 if (buf[len - 1] != ']') return (false);
168
169 if (is_valid_hex_string (buf + 5, len - 6) == false) return false;
170
171 return true;
172 }
173
exec_unhexify(const u8 * in_buf,const size_t in_len,u8 * out_buf,const size_t out_sz)174 size_t exec_unhexify (const u8 *in_buf, const size_t in_len, u8 *out_buf, const size_t out_sz)
175 {
176 size_t i, j;
177
178 for (i = 0, j = 5; j < in_len - 1; i += 1, j += 2)
179 {
180 const u8 c = hex_to_u8 (&in_buf[j]);
181
182 out_buf[i] = c;
183 }
184
185 memset (out_buf + i, 0, out_sz - i);
186
187 return (i);
188 }
189
need_hexify(const u8 * buf,const size_t len,const char separator,bool always_ascii)190 bool need_hexify (const u8 *buf, const size_t len, const char separator, bool always_ascii)
191 {
192 bool rc = false;
193
194 if (always_ascii == true)
195 {
196 if (printable_ascii (buf, len) == false)
197 {
198 rc = true;
199 }
200 }
201 else
202 {
203 if (printable_utf8 (buf, len) == false)
204 {
205 rc = true;
206 }
207 }
208
209 if (rc == false)
210 {
211 if (matches_separator (buf, len, separator) == true)
212 {
213 rc = true;
214 }
215 }
216
217 // also test if the password is of the format $HEX[]:
218
219 if (rc == false)
220 {
221 if (is_hexify (buf, len))
222 {
223 rc = true;
224 }
225 }
226
227 return rc;
228 }
229
exec_hexify(const u8 * buf,const size_t len,u8 * out)230 void exec_hexify (const u8 *buf, const size_t len, u8 *out)
231 {
232 const size_t max_len = (len > PW_MAX) ? PW_MAX : len;
233
234 for (int i = (int) max_len - 1, j = i * 2; i >= 0; i -= 1, j -= 2)
235 {
236 u8_to_hex (buf[i], out + j);
237 }
238
239 out[max_len * 2] = 0;
240 }
241
is_valid_base64a_string(const u8 * s,const size_t len)242 bool is_valid_base64a_string (const u8 *s, const size_t len)
243 {
244 for (size_t i = 0; i < len; i++)
245 {
246 const u8 c = s[i];
247
248 if (is_valid_base64a_char (c) == false) return false;
249 }
250
251 return true;
252 }
253
is_valid_base64a_char(const u8 c)254 bool is_valid_base64a_char (const u8 c)
255 {
256 if ((c >= '0') && (c <= '9')) return true;
257 if ((c >= 'A') && (c <= 'Z')) return true;
258 if ((c >= 'a') && (c <= 'z')) return true;
259
260 if (c == '+') return true;
261 if (c == '/') return true;
262 if (c == '=') return true;
263
264 return false;
265 }
266
is_valid_base64b_string(const u8 * s,const size_t len)267 bool is_valid_base64b_string (const u8 *s, const size_t len)
268 {
269 for (size_t i = 0; i < len; i++)
270 {
271 const u8 c = s[i];
272
273 if (is_valid_base64b_char (c) == false) return false;
274 }
275
276 return true;
277 }
278
is_valid_base64b_char(const u8 c)279 bool is_valid_base64b_char (const u8 c)
280 {
281 if ((c >= '0') && (c <= '9')) return true;
282 if ((c >= 'A') && (c <= 'Z')) return true;
283 if ((c >= 'a') && (c <= 'z')) return true;
284
285 if (c == '.') return true;
286 if (c == '/') return true;
287 if (c == '=') return true;
288
289 return false;
290 }
291
is_valid_base64c_string(const u8 * s,const size_t len)292 bool is_valid_base64c_string (const u8 *s, const size_t len)
293 {
294 for (size_t i = 0; i < len; i++)
295 {
296 const u8 c = s[i];
297
298 if (is_valid_base64c_char (c) == false) return false;
299 }
300
301 return true;
302 }
303
is_valid_base64c_char(const u8 c)304 bool is_valid_base64c_char (const u8 c)
305 {
306 if ((c >= '0') && (c <= '9')) return true;
307 if ((c >= 'A') && (c <= 'Z')) return true;
308 if ((c >= 'a') && (c <= 'z')) return true;
309
310 if (c == '_') return true;
311 if (c == '-') return true;
312 if (c == '=') return true;
313
314 return false;
315 }
316
is_valid_hex_string(const u8 * s,const size_t len)317 bool is_valid_hex_string (const u8 *s, const size_t len)
318 {
319 for (size_t i = 0; i < len; i++)
320 {
321 const u8 c = s[i];
322
323 if (is_valid_hex_char (c) == false) return false;
324 }
325
326 return true;
327 }
328
is_valid_hex_char(const u8 c)329 bool is_valid_hex_char (const u8 c)
330 {
331 if ((c >= '0') && (c <= '9')) return true;
332 if ((c >= 'A') && (c <= 'F')) return true;
333 if ((c >= 'a') && (c <= 'f')) return true;
334
335 return false;
336 }
337
is_valid_float_string(const u8 * s,const size_t len)338 bool is_valid_float_string (const u8 *s, const size_t len)
339 {
340 for (size_t i = 0; i < len; i++)
341 {
342 const u8 c = s[i];
343
344 if (is_valid_float_char (c) == false) return false;
345 }
346
347 return true;
348 }
349
is_valid_float_char(const u8 c)350 bool is_valid_float_char (const u8 c)
351 {
352 if ((c >= '0') && (c <= '9')) return true;
353
354 if (c == '.') return true;
355
356 return false;
357 }
358
is_valid_digit_string(const u8 * s,const size_t len)359 bool is_valid_digit_string (const u8 *s, const size_t len)
360 {
361 for (size_t i = 0; i < len; i++)
362 {
363 const u8 c = s[i];
364
365 if (is_valid_digit_char (c) == false) return false;
366 }
367
368 return true;
369 }
370
is_valid_digit_char(const u8 c)371 bool is_valid_digit_char (const u8 c)
372 {
373 if ((c >= '0') && (c <= '9')) return true;
374
375 return false;
376 }
377
hex_convert(const u8 c)378 u8 hex_convert (const u8 c)
379 {
380 return (c & 15) + (c >> 6) * 9;
381 }
382
hex_to_u8(const u8 hex[2])383 u8 hex_to_u8 (const u8 hex[2])
384 {
385 u8 v = 0;
386
387 v |= (hex_convert (hex[1]) << 0);
388 v |= (hex_convert (hex[0]) << 4);
389
390 return (v);
391 }
392
hex_to_u32(const u8 hex[8])393 u32 hex_to_u32 (const u8 hex[8])
394 {
395 u32 v = 0;
396
397 v |= ((u32) hex_convert (hex[1]) << 0);
398 v |= ((u32) hex_convert (hex[0]) << 4);
399 v |= ((u32) hex_convert (hex[3]) << 8);
400 v |= ((u32) hex_convert (hex[2]) << 12);
401 v |= ((u32) hex_convert (hex[5]) << 16);
402 v |= ((u32) hex_convert (hex[4]) << 20);
403 v |= ((u32) hex_convert (hex[7]) << 24);
404 v |= ((u32) hex_convert (hex[6]) << 28);
405
406 return (v);
407 }
408
hex_to_u64(const u8 hex[16])409 u64 hex_to_u64 (const u8 hex[16])
410 {
411 u64 v = 0;
412
413 v |= ((u64) hex_convert (hex[ 1]) << 0);
414 v |= ((u64) hex_convert (hex[ 0]) << 4);
415 v |= ((u64) hex_convert (hex[ 3]) << 8);
416 v |= ((u64) hex_convert (hex[ 2]) << 12);
417 v |= ((u64) hex_convert (hex[ 5]) << 16);
418 v |= ((u64) hex_convert (hex[ 4]) << 20);
419 v |= ((u64) hex_convert (hex[ 7]) << 24);
420 v |= ((u64) hex_convert (hex[ 6]) << 28);
421 v |= ((u64) hex_convert (hex[ 9]) << 32);
422 v |= ((u64) hex_convert (hex[ 8]) << 36);
423 v |= ((u64) hex_convert (hex[11]) << 40);
424 v |= ((u64) hex_convert (hex[10]) << 44);
425 v |= ((u64) hex_convert (hex[13]) << 48);
426 v |= ((u64) hex_convert (hex[12]) << 52);
427 v |= ((u64) hex_convert (hex[15]) << 56);
428 v |= ((u64) hex_convert (hex[14]) << 60);
429
430 return (v);
431 }
432
u8_to_hex(const u8 v,u8 hex[2])433 void u8_to_hex (const u8 v, u8 hex[2])
434 {
435 const u8 tbl[0x10] =
436 {
437 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
438 'a', 'b', 'c', 'd', 'e', 'f',
439 };
440
441 hex[1] = tbl[v >> 0 & 15];
442 hex[0] = tbl[v >> 4 & 15];
443 }
444
u32_to_hex(const u32 v,u8 hex[8])445 void u32_to_hex (const u32 v, u8 hex[8])
446 {
447 const u8 tbl[0x10] =
448 {
449 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
450 'a', 'b', 'c', 'd', 'e', 'f',
451 };
452
453 hex[1] = tbl[v >> 0 & 15];
454 hex[0] = tbl[v >> 4 & 15];
455 hex[3] = tbl[v >> 8 & 15];
456 hex[2] = tbl[v >> 12 & 15];
457 hex[5] = tbl[v >> 16 & 15];
458 hex[4] = tbl[v >> 20 & 15];
459 hex[7] = tbl[v >> 24 & 15];
460 hex[6] = tbl[v >> 28 & 15];
461 }
462
u64_to_hex(const u64 v,u8 hex[16])463 void u64_to_hex (const u64 v, u8 hex[16])
464 {
465 const u8 tbl[0x10] =
466 {
467 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
468 'a', 'b', 'c', 'd', 'e', 'f',
469 };
470
471 hex[ 1] = tbl[v >> 0 & 15];
472 hex[ 0] = tbl[v >> 4 & 15];
473 hex[ 3] = tbl[v >> 8 & 15];
474 hex[ 2] = tbl[v >> 12 & 15];
475 hex[ 5] = tbl[v >> 16 & 15];
476 hex[ 4] = tbl[v >> 20 & 15];
477 hex[ 7] = tbl[v >> 24 & 15];
478 hex[ 6] = tbl[v >> 28 & 15];
479 hex[ 9] = tbl[v >> 32 & 15];
480 hex[ 8] = tbl[v >> 36 & 15];
481 hex[11] = tbl[v >> 40 & 15];
482 hex[10] = tbl[v >> 44 & 15];
483 hex[13] = tbl[v >> 48 & 15];
484 hex[12] = tbl[v >> 52 & 15];
485 hex[15] = tbl[v >> 56 & 15];
486 hex[14] = tbl[v >> 60 & 15];
487 }
488
int_to_base32(const u8 c)489 u8 int_to_base32 (const u8 c)
490 {
491 const u8 tbl[0x20] =
492 {
493 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
494 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
495 };
496
497 return tbl[c];
498 }
499
base32_to_int(const u8 c)500 u8 base32_to_int (const u8 c)
501 {
502 if ((c >= 'A') && (c <= 'Z')) return c - 'A';
503 if ((c >= '2') && (c <= '7')) return c - '2' + 26;
504
505 return 0;
506 }
507
int_to_itoa32(const u8 c)508 u8 int_to_itoa32 (const u8 c)
509 {
510 const u8 tbl[0x20] =
511 {
512 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
513 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
514 };
515
516 return tbl[c];
517 }
518
itoa32_to_int(const u8 c)519 u8 itoa32_to_int (const u8 c)
520 {
521 if ((c >= '0') && (c <= '9')) return c - '0';
522 if ((c >= 'a') && (c <= 'v')) return c - 'a' + 10;
523
524 return 0;
525 }
526
int_to_itoa64(const u8 c)527 u8 int_to_itoa64 (const u8 c)
528 {
529 const u8 tbl[0x40] =
530 {
531 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
532 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54,
533 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
534 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
535 };
536
537 return tbl[c];
538 }
539
itoa64_to_int(const u8 c)540 u8 itoa64_to_int (const u8 c)
541 {
542 const u8 tbl[0x100] =
543 {
544 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
545 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
546 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x01,
547 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
548 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
549 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24,
550 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
551 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x01, 0x02, 0x03, 0x04,
552 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
553 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
554 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
555 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x01, 0x02, 0x03, 0x04,
556 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
557 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
558 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
559 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x01, 0x02, 0x03, 0x04,
560 };
561
562 return tbl[c];
563 }
564
int_to_base64(const u8 c)565 u8 int_to_base64 (const u8 c)
566 {
567 const u8 tbl[0x40] =
568 {
569 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
570 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
571 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
572 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x2f,
573 };
574
575 return tbl[c];
576 }
577
base64_to_int(const u8 c)578 u8 base64_to_int (const u8 c)
579 {
580 const u8 tbl[0x100] =
581 {
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3f,
585 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
587 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
588 0x00, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
589 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598 };
599
600 return tbl[c];
601 }
602
603 // alternate base64 using ./ instead of +/, used in python passlib hashes
int_to_ab64(const u8 c)604 u8 int_to_ab64 (const u8 c)
605 {
606 const u8 tbl[0x40] =
607 {
608 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
609 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
610 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
611 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2e, 0x2f,
612 };
613
614 return tbl[c];
615 }
616
ab64_to_int(const u8 c)617 u8 ab64_to_int (const u8 c)
618 {
619 const u8 tbl[0x100] =
620 {
621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3f,
624 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
626 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
627 0x00, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
628 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637 };
638
639 return tbl[c];
640 }
641
int_to_base64url(const u8 c)642 u8 int_to_base64url (const u8 c)
643 {
644 const u8 tbl[0x40] =
645 {
646 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
647 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
648 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
649 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2d, 0x5f,
650 };
651
652 return tbl[c];
653 }
654
base64url_to_int(const u8 c)655 u8 base64url_to_int (const u8 c)
656 {
657 const u8 tbl[0x100] =
658 {
659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
661 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00,
662 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
664 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x3f,
665 0x00, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
666 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
667 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
668 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675 };
676
677 return tbl[c];
678 }
679
int_to_bf64(const u8 c)680 u8 int_to_bf64 (const u8 c)
681 {
682 const u8 tbl[0x40] =
683 {
684 0x2e, 0x2f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e,
685 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64,
686 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74,
687 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
688 };
689
690 return tbl[c];
691 }
692
bf64_to_int(const u8 c)693 u8 bf64_to_int (const u8 c)
694 {
695 const u8 tbl[0x100] =
696 {
697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
699 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
700 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
701 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
702 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00,
703 0x00, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
704 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00,
705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
706 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
707 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
708 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
713 };
714
715 return tbl[c];
716 }
717
int_to_lotus64(const u8 c)718 u8 int_to_lotus64 (const u8 c)
719 {
720 if (c < 10) return '0' + c;
721 if (c < 36) return 'A' + c - 10;
722 if (c < 62) return 'a' + c - 36;
723 if (c == 62) return '+';
724 if (c == 63) return '/';
725
726 return 0;
727 }
728
lotus64_to_int(const u8 c)729 u8 lotus64_to_int (const u8 c)
730 {
731 if ((c >= '0') && (c <= '9')) return c - '0';
732 if ((c >= 'A') && (c <= 'Z')) return c - 'A' + 10;
733 if ((c >= 'a') && (c <= 'z')) return c - 'a' + 36;
734 if (c == '+') return 62;
735 if (c == '/') return 63;
736
737 return 0;
738 }
739
base32_decode(u8 (* f)(const u8),const u8 * in_buf,const size_t in_len,u8 * out_buf)740 size_t base32_decode (u8 (*f) (const u8), const u8 *in_buf, const size_t in_len, u8 *out_buf)
741 {
742 const u8 *in_ptr = in_buf;
743
744 u8 *out_ptr = out_buf;
745
746 for (size_t i = 0; i < in_len; i += 8)
747 {
748 const u8 f0 = ((i + 0) < in_len) ? in_ptr[0] : 0;
749 const u8 f1 = ((i + 1) < in_len) ? in_ptr[1] : 0;
750 const u8 f2 = ((i + 2) < in_len) ? in_ptr[2] : 0;
751 const u8 f3 = ((i + 3) < in_len) ? in_ptr[3] : 0;
752 const u8 f4 = ((i + 4) < in_len) ? in_ptr[4] : 0;
753 const u8 f5 = ((i + 5) < in_len) ? in_ptr[5] : 0;
754 const u8 f6 = ((i + 6) < in_len) ? in_ptr[6] : 0;
755 const u8 f7 = ((i + 7) < in_len) ? in_ptr[7] : 0;
756
757 const u8 out_val0 = f (f0 & 0x7f);
758 const u8 out_val1 = f (f1 & 0x7f);
759 const u8 out_val2 = f (f2 & 0x7f);
760 const u8 out_val3 = f (f3 & 0x7f);
761 const u8 out_val4 = f (f4 & 0x7f);
762 const u8 out_val5 = f (f5 & 0x7f);
763 const u8 out_val6 = f (f6 & 0x7f);
764 const u8 out_val7 = f (f7 & 0x7f);
765
766 out_ptr[0] = ((out_val0 << 3) & 0xf8) | ((out_val1 >> 2) & 0x07);
767 out_ptr[1] = ((out_val1 << 6) & 0xc0) | ((out_val2 << 1) & 0x3e) | ((out_val3 >> 4) & 0x01);
768 out_ptr[2] = ((out_val3 << 4) & 0xf0) | ((out_val4 >> 1) & 0x0f);
769 out_ptr[3] = ((out_val4 << 7) & 0x80) | ((out_val5 << 2) & 0x7c) | ((out_val6 >> 3) & 0x03);
770 out_ptr[4] = ((out_val6 << 5) & 0xe0) | ((out_val7 >> 0) & 0x1f);
771
772 in_ptr += 8;
773 out_ptr += 5;
774 }
775
776 size_t tmp_len = 0;
777
778 for (size_t i = 0; i < in_len; i++, tmp_len++)
779 {
780 if (in_buf[i] != '=') continue;
781
782 break;
783 }
784
785 size_t out_len = (tmp_len * 5) / 8;
786
787 return out_len;
788 }
789
base32_encode(u8 (* f)(const u8),const u8 * in_buf,const size_t in_len,u8 * out_buf)790 size_t base32_encode (u8 (*f) (const u8), const u8 *in_buf, const size_t in_len, u8 *out_buf)
791 {
792 const u8 *in_ptr = in_buf;
793
794 u8 *out_ptr = out_buf;
795
796 for (size_t i = 0; i < in_len; i += 5)
797 {
798 const u8 f0 = ((i + 0) < in_len) ? in_ptr[0] : 0;
799 const u8 f1 = ((i + 1) < in_len) ? in_ptr[1] : 0;
800 const u8 f2 = ((i + 2) < in_len) ? in_ptr[2] : 0;
801 const u8 f3 = ((i + 3) < in_len) ? in_ptr[3] : 0;
802 const u8 f4 = ((i + 4) < in_len) ? in_ptr[4] : 0;
803
804 const u8 out_val0 = f ( ((f0 >> 3) & 0x1f));
805 const u8 out_val1 = f (((f0 << 2) & 0x1c) | ((f1 >> 6) & 0x03));
806 const u8 out_val2 = f ( ((f1 >> 1) & 0x1f));
807 const u8 out_val3 = f (((f1 << 4) & 0x10) | ((f2 >> 4) & 0x0f));
808 const u8 out_val4 = f (((f2 << 1) & 0x1e) | ((f3 >> 7) & 0x01));
809 const u8 out_val5 = f ( ((f3 >> 2) & 0x1f));
810 const u8 out_val6 = f (((f3 << 3) & 0x18) | ((f4 >> 5) & 0x07));
811 const u8 out_val7 = f ( ((f4 >> 0) & 0x1f));
812
813 out_ptr[0] = out_val0 & 0x7f;
814 out_ptr[1] = out_val1 & 0x7f;
815 out_ptr[2] = out_val2 & 0x7f;
816 out_ptr[3] = out_val3 & 0x7f;
817 out_ptr[4] = out_val4 & 0x7f;
818 out_ptr[5] = out_val5 & 0x7f;
819 out_ptr[6] = out_val6 & 0x7f;
820 out_ptr[7] = out_val7 & 0x7f;
821
822 in_ptr += 5;
823 out_ptr += 8;
824 }
825
826 int out_len = (int) (((0.5 + in_len) * 8) / 5); // ceil (in_len * 8 / 5)
827
828 while (out_len % 8)
829 {
830 out_buf[out_len] = '=';
831
832 out_len++;
833 }
834
835 return out_len;
836 }
837
base64_decode(u8 (* f)(const u8),const u8 * in_buf,const size_t in_len,u8 * out_buf)838 size_t base64_decode (u8 (*f) (const u8), const u8 *in_buf, const size_t in_len, u8 *out_buf)
839 {
840 const u8 *in_ptr = in_buf;
841
842 u8 *out_ptr = out_buf;
843
844 for (size_t i = 0; i < in_len; i += 4)
845 {
846 const u8 f0 = ((i + 0) < in_len) ? in_ptr[0] : 0;
847 const u8 f1 = ((i + 1) < in_len) ? in_ptr[1] : 0;
848 const u8 f2 = ((i + 2) < in_len) ? in_ptr[2] : 0;
849 const u8 f3 = ((i + 3) < in_len) ? in_ptr[3] : 0;
850
851 const u8 out_val0 = f (f0 & 0x7f);
852 const u8 out_val1 = f (f1 & 0x7f);
853 const u8 out_val2 = f (f2 & 0x7f);
854 const u8 out_val3 = f (f3 & 0x7f);
855
856 out_ptr[0] = ((out_val0 << 2) & 0xfc) | ((out_val1 >> 4) & 0x03);
857 out_ptr[1] = ((out_val1 << 4) & 0xf0) | ((out_val2 >> 2) & 0x0f);
858 out_ptr[2] = ((out_val2 << 6) & 0xc0) | ((out_val3 >> 0) & 0x3f);
859
860 in_ptr += 4;
861 out_ptr += 3;
862 }
863
864 size_t tmp_len = 0;
865
866 for (size_t i = 0; i < in_len; i++, tmp_len++)
867 {
868 if (in_buf[i] != '=') continue;
869
870 break;
871 }
872
873 size_t out_len = (tmp_len * 6) / 8;
874
875 return out_len;
876 }
877
base64_encode(u8 (* f)(const u8),const u8 * in_buf,const size_t in_len,u8 * out_buf)878 size_t base64_encode (u8 (*f) (const u8), const u8 *in_buf, const size_t in_len, u8 *out_buf)
879 {
880 const u8 *in_ptr = in_buf;
881
882 u8 *out_ptr = out_buf;
883
884 for (size_t i = 0; i < in_len; i += 3)
885 {
886 const u8 f0 = ((i + 0) < in_len) ? in_ptr[0] : 0;
887 const u8 f1 = ((i + 1) < in_len) ? in_ptr[1] : 0;
888 const u8 f2 = ((i + 2) < in_len) ? in_ptr[2] : 0;
889
890 const u8 out_val0 = f ( ((f0 >> 2) & 0x3f));
891 const u8 out_val1 = f (((f0 << 4) & 0x30) | ((f1 >> 4) & 0x0f));
892 const u8 out_val2 = f (((f1 << 2) & 0x3c) | ((f2 >> 6) & 0x03));
893 const u8 out_val3 = f ( ((f2 >> 0) & 0x3f));
894
895 out_ptr[0] = out_val0 & 0x7f;
896 out_ptr[1] = out_val1 & 0x7f;
897 out_ptr[2] = out_val2 & 0x7f;
898 out_ptr[3] = out_val3 & 0x7f;
899
900 in_ptr += 3;
901 out_ptr += 4;
902 }
903
904 int out_len = (int) (((0.5 + in_len) * 8) / 6); // ceil (in_len * 8 / 6)
905
906 while (out_len % 4)
907 {
908 out_buf[out_len] = '=';
909
910 out_len++;
911 }
912
913 return out_len;
914 }
915
lowercase(u8 * buf,const size_t len)916 void lowercase (u8 *buf, const size_t len)
917 {
918 for (size_t i = 0; i < len; i++) buf[i] = (u8) tolower ((int) buf[i]);
919 }
920
uppercase(u8 * buf,const size_t len)921 void uppercase (u8 *buf, const size_t len)
922 {
923 for (size_t i = 0; i < len; i++) buf[i] = (u8) toupper ((int) buf[i]);
924 }
925
v8a_from_v32(const u32 v32)926 u8 v8a_from_v32 (const u32 v32)
927 {
928 vconv32_t v;
929
930 v.v32 = v32;
931
932 return v.v8.a;
933 }
934
v8b_from_v32(const u32 v32)935 u8 v8b_from_v32 (const u32 v32)
936 {
937 vconv32_t v;
938
939 v.v32 = v32;
940
941 return v.v8.b;
942 }
943
v8c_from_v32(const u32 v32)944 u8 v8c_from_v32 (const u32 v32)
945 {
946 vconv32_t v;
947
948 v.v32 = v32;
949
950 return v.v8.c;
951 }
952
v8d_from_v32(const u32 v32)953 u8 v8d_from_v32 (const u32 v32)
954 {
955 vconv32_t v;
956
957 v.v32 = v32;
958
959 return v.v8.d;
960 }
961
v16a_from_v32(const u32 v32)962 u16 v16a_from_v32 (const u32 v32)
963 {
964 vconv32_t v;
965
966 v.v32 = v32;
967
968 return v.v16.a;
969 }
970
v16b_from_v32(const u32 v32)971 u16 v16b_from_v32 (const u32 v32)
972 {
973 vconv32_t v;
974
975 v.v32 = v32;
976
977 return v.v16.b;
978 }
979
v32_from_v16ab(const u16 v16a,const u16 v16b)980 u32 v32_from_v16ab (const u16 v16a, const u16 v16b)
981 {
982 vconv32_t v;
983
984 v.v16.a = v16a;
985 v.v16.b = v16b;
986
987 return v.v32;
988 }
989
v32a_from_v64(const u64 v64)990 u32 v32a_from_v64 (const u64 v64)
991 {
992 vconv64_t v;
993
994 v.v64 = v64;
995
996 return v.v32.a;
997 }
998
v32b_from_v64(const u64 v64)999 u32 v32b_from_v64 (const u64 v64)
1000 {
1001 vconv64_t v;
1002
1003 v.v64 = v64;
1004
1005 return v.v32.b;
1006 }
1007
v64_from_v32ab(const u32 v32a,const u32 v32b)1008 u64 v64_from_v32ab (const u32 v32a, const u32 v32b)
1009 {
1010 vconv64_t v;
1011
1012 v.v32.a = v32a;
1013 v.v32.b = v32b;
1014
1015 return v.v64;
1016 }
1017
hex_decode(const u8 * in_buf,const int in_len,u8 * out_buf)1018 int hex_decode (const u8 *in_buf, const int in_len, u8 *out_buf)
1019 {
1020 for (int i = 0, j = 0; i < in_len; i += 2, j += 1)
1021 {
1022 out_buf[j] = hex_to_u8 (&in_buf[i]);
1023 }
1024
1025 return in_len / 2;
1026 }
1027
hex_encode(const u8 * in_buf,const int in_len,u8 * out_buf)1028 int hex_encode (const u8 *in_buf, const int in_len, u8 *out_buf)
1029 {
1030 for (int i = 0, j = 0; i < in_len; i += 1, j += 2)
1031 {
1032 u8_to_hex (in_buf[i], &out_buf[j]);
1033 }
1034
1035 return in_len * 2;
1036 }
1037