1 #include "byte.h"
2 #include "dns.h"
3
4 static const char base32_digits[32] = "0123456789bcdfghjklmnpqrstuvwxyz";
5
dns_base32_bytessize(long long len)6 long long dns_base32_bytessize(long long len) {
7
8 if (len < 0) return 0;
9 len = (8 * len + 4) / 5;
10 return len + (len + 49) / 50;
11 }
12
dns_base32_encodebytes(unsigned char * out,const unsigned char * in,long long len)13 void dns_base32_encodebytes(unsigned char *out, const unsigned char *in, long long len) {
14
15 unsigned long long i, x, v, vbits;
16
17 if (len < 0) return;
18
19 x = v = vbits = 0;
20 for (i = 0; i < len; ++i) {
21 v |= ((unsigned long long)in[i]) << vbits;
22 vbits += 8;
23 do {
24 out[++x] = base32_digits[v & 31];
25 v >>= 5;
26 vbits -= 5;
27 if (x == 50) {
28 *out = x;
29 out += 1 + x;
30 x = 0;
31 }
32 } while (vbits >= 5);
33 }
34
35 if (vbits) out[++x] = base32_digits[v & 31];
36 if (x) *out = x;
37 }
38
dns_base32_encodekey(unsigned char * out,const unsigned char * key)39 void dns_base32_encodekey(unsigned char *out, const unsigned char *key) {
40
41 unsigned long long i, v, vbits;
42
43 byte_copy(out, 4, "\66x1a");
44 out += 4;
45
46 v = vbits = 0;
47 for (i = 0; i < 32; ++i) {
48 v |= ((unsigned long long)key[i]) << vbits;
49 vbits += 8;
50 do {
51 *out++ = base32_digits[v & 31];
52 v >>= 5;
53 vbits -= 5;
54 } while (vbits >= 5);
55 }
56 }
57
58 static const unsigned char val[128] = {
59 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
60 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
61 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
62 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
63 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
64 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
65 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
66 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
67 0xff, 0xff, 0x0a, 0x0b, 0x0c, 0xff, 0x0d, 0x0e,
68 0x0f, 0xff, 0x10, 0x11, 0x12, 0x13, 0x14, 0xff,
69 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
70 0x1d, 0x1e, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
71 0xff, 0xff, 0x0a, 0x0b, 0x0c, 0xff, 0x0d, 0x0e,
72 0x0f, 0xff, 0x10, 0x11, 0x12, 0x13, 0x14, 0xff,
73 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
74 0x1d, 0x1e, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff
75 };
76
77
78
base32_decode(unsigned char * out,const unsigned char * in,long long len,int mode)79 long long base32_decode(unsigned char *out, const unsigned char *in, long long len, int mode) {
80
81 long long i;
82 unsigned long long x, v, vbits;
83 unsigned char *out0 = out;
84
85 if (len < 0) return 0;
86
87 v = vbits = 0;
88 for (i = 0; i < len; ++i) {
89 if (in[i] & 0x80) return 0;
90 x = val[in[i]];
91 if (x > 0x1f) return 0;
92 v |= x << vbits;
93 vbits += 5;
94 if (vbits >= 8) {
95 *out++ = v;
96 v >>= 8;
97 vbits -= 8;
98 }
99 }
100
101 if (mode) {
102 if (vbits)
103 *out++ = v;
104 }
105 else if (vbits >= 5 || v)
106 return 0;
107
108 return out - out0;
109 }
110