1 /*
2 // Copyright (C) 2022 Beken Corporation
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "base_64.h"
16 #include <string.h>
17 #include <common/bk_include.h>
18 #include <os/mem.h>
19
20 #if CFG_USE_BASE64
21 #define DTABLE_LEN 256
22
23 /* ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ */
24 static const unsigned char base_64_table[64] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
25 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
26 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a',
27 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
28 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
29 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1',
30 '2', '3', '4', '5', '6', '7', '8', '9', '+',
31 '/'
32 };
33 /**
34 *calculate a string base64_encode length
35 *
36 */
base64_calc_encode_length(unsigned int src_Len)37 unsigned int base64_calc_encode_length(unsigned int src_Len)
38 {
39 unsigned int enc_len = 0;
40 enc_len = src_Len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
41 enc_len += enc_len / 72; /* line feeds */
42 enc_len++; /* nul termination ('\0') */
43 return enc_len;
44 }
45
46 /**
47 * Base64_encode - Base64 encode
48 * @src: Data to be encoded
49 * @len: Length of the data to be encoded
50 * @out_len: Pointer to output length variable, or %NULL if not used
51 * @out:Pointer to save encoding buf
52 * Returns:1:succeed,0:failed
53 */
base64_encode(const unsigned char * src,int len,int * out_len,unsigned char * out)54 unsigned char base64_encode(const unsigned char *src, int len,
55 int *out_len, unsigned char *out)
56 {
57 unsigned char *pos;
58 const unsigned char *end, *in;
59 int line_len;
60
61 if (out == ((unsigned char *)0))
62 return 0;
63
64 end = src + len;
65 in = src;
66 pos = out;
67 line_len = 0;
68 while (end - in >= 3) {
69 *pos++ = base_64_table[in[0] >> 2];
70 *pos++ = base_64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
71 *pos++ = base_64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
72 *pos++ = base_64_table[in[2] & 0x3f];
73 in += 3;
74 line_len += 4;
75 if (line_len >= 72) {
76 *pos++ = '\n';
77 line_len = 0;
78 }
79 }
80
81 if (end - in) {
82 *pos++ = base_64_table[in[0] >> 2];
83 if (end - in == 1) {
84 *pos++ = base_64_table[(in[0] & 0x03) << 4];
85 *pos++ = '=';
86 } else {
87 *pos++ = base_64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
88 *pos++ = base_64_table[(in[1] & 0x0f) << 2];
89 }
90 *pos++ = '=';
91 line_len += 4;
92 }
93
94 if (line_len)
95 *pos++ = '\n';
96
97 *pos = '\0';
98 if (out_len)
99 (*out_len) = pos - out;
100 return 1;
101 }
102
103 /**
104 *calculate a string base64_encode length
105 *
106 */
base64_calc_decode_length(const unsigned char * src,unsigned int src_Len)107 unsigned int base64_calc_decode_length(const unsigned char *src, unsigned int src_Len)
108 {
109 unsigned int dec_len;
110 unsigned char *dtable;
111 unsigned int i;
112
113 dtable = (unsigned char *)os_zalloc(DTABLE_LEN);
114 if (NULL == dtable)
115 return 0;
116
117 os_memset(dtable, 0x80, 256);
118 for (i = 0; i < sizeof(base_64_table); i++)
119 dtable[base_64_table[i]] = i;
120 dtable['='] = 0;
121
122 dec_len = 0;
123 for (i = 0; i < src_Len; i++) {
124 if (dtable[src[i]] != 0x80)
125 dec_len++;
126 }
127 if (dec_len % 4)
128 dec_len = 0;
129 return dec_len;
130 }
131
132
133 /**
134 * base64_decode - Base64 decode
135 * @src: Data to be decoded
136 * @len: Length of the data to be decoded
137 * @out_len: Pointer to output length variable
138 * @out:Pointer to save encoding buf
139 * Returns:1:succeed,0:failed
140 */
base64_decode(const unsigned char * src,int len,int * out_len,unsigned char * out)141 unsigned char base64_decode(const unsigned char *src, int len,
142 int *out_len, unsigned char *out)
143 {
144 unsigned char *pos, in[4], block[4], tmp;
145 unsigned int i, count;
146 unsigned char *dtable;
147
148 dtable = (unsigned char *)os_zalloc(DTABLE_LEN);
149 if (NULL == dtable) {
150 (*out_len) = 0;
151 return 0;
152 }
153
154 os_memset(dtable, 0x80, 256);
155 for (i = 0; i < sizeof(base_64_table); i++)
156 dtable[base_64_table[i]] = i;
157 dtable['='] = 0;
158
159 count = 0;
160 for (i = 0; i < len; i++) {
161 if (dtable[src[i]] != 0x80)
162 count++;
163 }
164
165 if (count % 4)
166 return 0;
167 if (out == ((unsigned char *)0)) {
168 *out_len = (count * 3) / 4;
169 return 0;
170 }
171 pos = out;
172
173 count = 0;
174 for (i = 0; i < len; i++) {
175 tmp = dtable[src[i]];
176 if (tmp == 0x80) //'\n'
177 continue;
178
179 in[count] = src[i];
180 block[count] = tmp;
181 count++;
182 if (count == 4) {
183 *pos++ = (block[0] << 2) | (block[1] >> 4);
184 *pos++ = (block[1] << 4) | (block[2] >> 2);
185 *pos++ = (block[2] << 6) | block[3];
186 count = 0;
187 }
188 }
189
190 if (pos > out) {
191 if (in[2] == '=')
192 pos -= 2;
193 else if (in[3] == '=')
194 pos--;
195 }
196
197 (*out_len) = pos - out;
198
199 return 1;
200 }
201 #endif
202 // eof
203
204