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