1
7
8
9
10
11
12
13
14
15
16
17
18
21
22
23
24
27
28
29
30
31
32
33
34
38
39
40
41
45
46
47
48
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
81
82
83
84
85
86
87
88
89
90
91
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
113
114
115
118
119
123
124
127
128
129
132
133
136
137
149
150
151
152
156
157
161
162
163
164
168
169
170
171
174
175
176
181
182
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
220
221
222
223
224
225
226
229
230
231
232
240
241
244
245
246
247
255
256
259
260
261
262
263
264
265
/* ... */
#include "common.h"
#if defined(MBEDTLS_BASE64_C)
#include "mbedtls/base64.h"
#include "constant_time_internal.h"
#include <stdint.h>
#if defined(MBEDTLS_SELF_TEST)
#include <string.h>
#include "mbedtls/platform.h"
/* ... */#endif
#define BASE64_SIZE_T_MAX ((size_t) -1)
/* ... */
int mbedtls_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
const unsigned char *src, size_t slen)
{
size_t i, n;
int C1, C2, C3;
unsigned char *p;
if (slen == 0) {
*olen = 0;
return 0;
}if (slen == 0) { ... }
n = slen / 3 + (slen % 3 != 0);
if (n > (BASE64_SIZE_T_MAX - 1) / 4) {
*olen = BASE64_SIZE_T_MAX;
return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
}if (n > (BASE64_SIZE_T_MAX - 1) / 4) { ... }
n *= 4;
if ((dlen < n + 1) || (NULL == dst)) {
*olen = n + 1;
return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
}if ((dlen < n + 1) || (NULL == dst)) { ... }
n = (slen / 3) * 3;
for (i = 0, p = dst; i < n; i += 3) {
C1 = *src++;
C2 = *src++;
C3 = *src++;
*p++ = mbedtls_ct_base64_enc_char((C1 >> 2) & 0x3F);
*p++ = mbedtls_ct_base64_enc_char((((C1 & 3) << 4) + (C2 >> 4))
& 0x3F);
*p++ = mbedtls_ct_base64_enc_char((((C2 & 15) << 2) + (C3 >> 6))
& 0x3F);
*p++ = mbedtls_ct_base64_enc_char(C3 & 0x3F);
}for (i = 0, p = dst; i < n; i += 3) { ... }
if (i < slen) {
C1 = *src++;
C2 = ((i + 1) < slen) ? *src++ : 0;
*p++ = mbedtls_ct_base64_enc_char((C1 >> 2) & 0x3F);
*p++ = mbedtls_ct_base64_enc_char((((C1 & 3) << 4) + (C2 >> 4))
& 0x3F);
if ((i + 1) < slen) {
*p++ = mbedtls_ct_base64_enc_char(((C2 & 15) << 2) & 0x3F);
}if ((i + 1) < slen) { ... } else {
*p++ = '=';
}else { ... }
*p++ = '=';
}if (i < slen) { ... }
*olen = p - dst;
*p = 0;
return 0;
}{ ... }
/* ... */
int mbedtls_base64_decode(unsigned char *dst, size_t dlen, size_t *olen,
const unsigned char *src, size_t slen)
{
size_t i;
size_t n;
uint32_t x;
unsigned accumulated_digits = 0;
unsigned equals = 0;
int spaces_present = 0;
unsigned char *p;
for (i = n = 0; i < slen; i++) {
spaces_present = 0;
while (i < slen && src[i] == ' ') {
++i;
spaces_present = 1;
}while (i < slen && src[i] == ' ') { ... }
if (i == slen) {
break;
}if (i == slen) { ... }
if ((slen - i) >= 2 &&
src[i] == '\r' && src[i + 1] == '\n') {
continue;
}if ((slen - i) >= 2 && src[i] == '\r' && src[i + 1] == '\n') { ... }
if (src[i] == '\n') {
continue;
}if (src[i] == '\n') { ... }
if (spaces_present) {
return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
}if (spaces_present) { ... }
if (src[i] > 127) {
return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
}if (src[i] > 127) { ... }
if (src[i] == '=') {
if (++equals > 2) {
return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
}if (++equals > 2) { ... }
}if (src[i] == '=') { ... } else {
if (equals != 0) {
return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
}if (equals != 0) { ... }
if (mbedtls_ct_base64_dec_value(src[i]) < 0) {
return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
}if (mbedtls_ct_base64_dec_value(src[i]) < 0) { ... }
}else { ... }
n++;
}for (i = n = 0; i < slen; i++) { ... }
if (n == 0) {
*olen = 0;
return 0;
}if (n == 0) { ... }
/* ... */
n = (6 * (n >> 3)) + ((6 * (n & 0x7) + 7) >> 3);
n -= equals;
if (dst == NULL || dlen < n) {
*olen = n;
return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
}if (dst == NULL || dlen < n) { ... }
equals = 0;
for (x = 0, p = dst; i > 0; i--, src++) {
if (*src == '\r' || *src == '\n' || *src == ' ') {
continue;
}if (*src == '\r' || *src == '\n' || *src == ' ') { ... }
x = x << 6;
if (*src == '=') {
++equals;
}if (*src == '=') { ... } else {
x |= mbedtls_ct_base64_dec_value(*src);
}else { ... }
if (++accumulated_digits == 4) {
accumulated_digits = 0;
*p++ = MBEDTLS_BYTE_2(x);
if (equals <= 1) {
*p++ = MBEDTLS_BYTE_1(x);
}if (equals <= 1) { ... }
if (equals <= 0) {
*p++ = MBEDTLS_BYTE_0(x);
}if (equals <= 0) { ... }
}if (++accumulated_digits == 4) { ... }
}for (x = 0, p = dst; i > 0; i--, src++) { ... }
*olen = p - dst;
return 0;
}{ ... }
#if defined(MBEDTLS_SELF_TEST)
static const unsigned char base64_test_dec[64] =
{
0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
...};
static const unsigned char base64_test_enc[] =
"JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
"swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
/* ... */
int mbedtls_base64_self_test(int verbose)
{
size_t len;
const unsigned char *src;
unsigned char buffer[128];
if (verbose != 0) {
mbedtls_printf(" Base64 encoding test: ");
}if (verbose != 0) { ... }
src = base64_test_dec;
if (mbedtls_base64_encode(buffer, sizeof(buffer), &len, src, 64) != 0 ||
memcmp(base64_test_enc, buffer, 88) != 0) {
if (verbose != 0) {
mbedtls_printf("failed\n");
}if (verbose != 0) { ... }
return 1;
}if (mbedtls_base64_encode(buffer, sizeof(buffer), &len, src, 64) != 0 || memcmp(base64_test_enc, buffer, 88) != 0) { ... }
if (verbose != 0) {
mbedtls_printf("passed\n Base64 decoding test: ");
}if (verbose != 0) { ... }
src = base64_test_enc;
if (mbedtls_base64_decode(buffer, sizeof(buffer), &len, src, 88) != 0 ||
memcmp(base64_test_dec, buffer, 64) != 0) {
if (verbose != 0) {
mbedtls_printf("failed\n");
}if (verbose != 0) { ... }
return 1;
}if (mbedtls_base64_decode(buffer, sizeof(buffer), &len, src, 88) != 0 || memcmp(base64_test_dec, buffer, 64) != 0) { ... }
if (verbose != 0) {
mbedtls_printf("passed\n\n");
}if (verbose != 0) { ... }
return 0;
}mbedtls_base64_self_test (int verbose) { ... }
/* ... */
#endif
/* ... */
#endif