1 /*
2 * Copyright (c) 2010 by Internet Systems Consortium, Inc. ("ISC")
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
14 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 /*
18 * Copyright (c) 2006 Christian Biere <christianbiere@gmx.de>
19 * All rights reserved.
20 *
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
23 * are met:
24 *
25 * 1. Redistributions of source code must retain the above copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. Neither the name of the authors nor the names of its contributors
31 * may be used to endorse or promote products derived from this software
32 * without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
45 */
46
47 /*
48 * See RFC 4648 for details about Base 32 hex encoding:
49 * http://tools.ietf.org/html/rfc4648
50 */
51
52 #include <stdint.h>
53 #include <string.h>
54
55 #include "b32_encode.h"
56
57 static const char base32_alphabet[32] = {
58 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
59 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
60 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
61 'U', 'V'
62 };
63
64 /**
65 * Encode in base32 `len' bytes of `data' into the buffer `dst'.
66 *
67 * @param dst destination buffer
68 * @param size length of destination
69 * @param data start of data to encode
70 * @param len amount of bytes to encode
71 *
72 * @return the amount of bytes generated into the destination.
73 */
74 size_t
base32_encode(char * dst,size_t size,const void * data,size_t len)75 base32_encode(char *dst, size_t size, const void *data, size_t len)
76 {
77 size_t i = 0;
78 const uint8_t *p = data;
79 const char *end = &dst[size];
80 char *q = dst;
81
82 do {
83 size_t j, k;
84 uint8_t x[5];
85 char s[8];
86
87 switch (len - i) {
88 case 4:
89 k = 7;
90 break;
91 case 3:
92 k = 5;
93 break;
94 case 2:
95 k = 3;
96 break;
97 case 1:
98 k = 2;
99 break;
100 default:
101 k = 8;
102 }
103
104 for (j = 0; j < 5; j++)
105 x[j] = i < len ? p[i++] : 0;
106
107 s[0] = (x[0] >> 3);
108 s[1] = ((x[0] & 0x07) << 2) | (x[1] >> 6);
109 s[2] = (x[1] >> 1) & 0x1f;
110 s[3] = ((x[1] & 0x01) << 4) | (x[2] >> 4);
111 s[4] = ((x[2] & 0x0f) << 1) | (x[3] >> 7);
112 s[5] = (x[3] >> 2) & 0x1f;
113 s[6] = ((x[3] & 0x03) << 3) | (x[4] >> 5);
114 s[7] = x[4] & 0x1f;
115
116 for (j = 0; j < k && q != end; j++) {
117 *q++ = base32_alphabet[(uint8_t) s[j]];
118 }
119
120 if (end == q) {
121 break;
122 }
123
124 } while (i < len);
125
126 return q - dst;
127 }
128