• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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