blob: 02dd281b6af0eb8c0ab743faf3ad36bf316dd010 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1521 base64 encoding/decoding
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19
Gilles Peskinedb09ef62020-06-03 01:43:33 +020020#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000021
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022#if defined(MBEDTLS_BASE64_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000023
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020024# include "mbedtls/base64.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000025
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020026# include <stdint.h>
Paul Bakker5c2364c2012-10-01 14:41:15 +000027
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020028# if defined(MBEDTLS_SELF_TEST)
29# include <string.h>
30# if defined(MBEDTLS_PLATFORM_C)
31# include "mbedtls/platform.h"
32# else
33# include <stdio.h>
34# define mbedtls_printf printf
35# endif /* MBEDTLS_PLATFORM_C */
36# endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010037
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020038static const unsigned char base64_enc_map[64] = {
39 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
40 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
41 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
42 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
43 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
Paul Bakker5121ce52009-01-03 21:22:43 +000044};
45
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020046static const unsigned char base64_dec_map[128] = {
47 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
48 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
49 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 62, 127,
50 127, 127, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
51 127, 64, 127, 127, 127, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
52 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
53 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, 29, 30, 31, 32, 33,
54 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
55 49, 50, 51, 127, 127, 127, 127, 127
Paul Bakker5121ce52009-01-03 21:22:43 +000056};
57
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020058# define BASE64_SIZE_T_MAX ((size_t)-1) /* SIZE_T_MAX is not standard */
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +010059
Paul Elliott3e790812021-02-25 12:28:49 +000060/*
Paul Elliott0544d492021-03-01 19:15:43 +000061 * Constant flow conditional assignment to unsigned char
Paul Elliottbe165bd2021-03-04 14:34:50 +000062 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020063static void mbedtls_base64_cond_assign_uchar(unsigned char *dest,
64 const unsigned char *const src,
65 unsigned char condition)
Paul Elliottdadd10d2021-02-05 17:49:23 +000066{
Paul Elliott88f2eb62021-03-03 15:31:17 +000067 /* MSVC has a warning about unary minus on unsigned integer types,
68 * but this is well-defined and precisely what we want to do here. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020069# if defined(_MSC_VER)
70# pragma warning(push)
71# pragma warning(disable : 4146)
72# endif
Paul Elliottdadd10d2021-02-05 17:49:23 +000073
Paul Elliott07fa1f12021-03-03 17:21:17 +000074 /* Generate bitmask from condition, mask will either be 0xFF or 0 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020075 unsigned char mask = (condition | -condition);
Paul Elliott3ffd1342021-03-03 17:11:32 +000076 mask >>= 7;
77 mask = -mask;
Paul Elliott88f2eb62021-03-03 15:31:17 +000078
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020079# if defined(_MSC_VER)
80# pragma warning(pop)
81# endif
Paul Elliott88f2eb62021-03-03 15:31:17 +000082
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020083 *dest = ((*src) & mask) | ((*dest) & ~mask);
Paul Elliottdadd10d2021-02-05 17:49:23 +000084}
85
86/*
Paul Elliott0544d492021-03-01 19:15:43 +000087 * Constant flow conditional assignment to uint_32
Paul Elliottbe165bd2021-03-04 14:34:50 +000088 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020089static void mbedtls_base64_cond_assign_uint32(uint32_t *dest,
90 const uint32_t src,
91 uint32_t condition)
Paul Elliott0544d492021-03-01 19:15:43 +000092{
Paul Elliott88f2eb62021-03-03 15:31:17 +000093 /* MSVC has a warning about unary minus on unsigned integer types,
94 * but this is well-defined and precisely what we want to do here. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020095# if defined(_MSC_VER)
96# pragma warning(push)
97# pragma warning(disable : 4146)
98# endif
Paul Elliott0544d492021-03-01 19:15:43 +000099
Paul Elliott88f2eb62021-03-03 15:31:17 +0000100 /* Generate bitmask from condition, mask will either be 0xFFFFFFFF or 0 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200101 uint32_t mask = (condition | -condition);
Paul Elliott3ffd1342021-03-03 17:11:32 +0000102 mask >>= 31;
103 mask = -mask;
Paul Elliott88f2eb62021-03-03 15:31:17 +0000104
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200105# if defined(_MSC_VER)
106# pragma warning(pop)
107# endif
Paul Elliott88f2eb62021-03-03 15:31:17 +0000108
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200109 *dest = (src & mask) | ((*dest) & ~mask);
Paul Elliott0544d492021-03-01 19:15:43 +0000110}
111
Paul Elliott0544d492021-03-01 19:15:43 +0000112/*
Paul Elliott3e790812021-02-25 12:28:49 +0000113 * Constant flow check for equality
Paul Elliottbe165bd2021-03-04 14:34:50 +0000114 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200115static unsigned char mbedtls_base64_eq(size_t in_a, size_t in_b)
Paul Elliottdadd10d2021-02-05 17:49:23 +0000116{
Paul Elliott717ba772021-03-01 17:49:42 +0000117 size_t difference = in_a ^ in_b;
Paul Elliottdadd10d2021-02-05 17:49:23 +0000118
Paul Elliott3e790812021-02-25 12:28:49 +0000119 /* MSVC has a warning about unary minus on unsigned integer types,
120 * but this is well-defined and precisely what we want to do here. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200121# if defined(_MSC_VER)
122# pragma warning(push)
123# pragma warning(disable : 4146)
124# endif
Paul Elliott3e790812021-02-25 12:28:49 +0000125
Paul Elliottdadd10d2021-02-05 17:49:23 +0000126 difference |= -difference;
Paul Elliott3e790812021-02-25 12:28:49 +0000127
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200128# if defined(_MSC_VER)
129# pragma warning(pop)
130# endif
Paul Elliott3e790812021-02-25 12:28:49 +0000131
Paul Elliott717ba772021-03-01 17:49:42 +0000132 /* cope with the varying size of size_t per platform */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200133 difference >>= (sizeof(difference) * 8 - 1);
Paul Elliott717ba772021-03-01 17:49:42 +0000134
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200135 return (unsigned char)(1 ^ difference);
Paul Elliottdadd10d2021-02-05 17:49:23 +0000136}
137
138/*
Paul Elliott3e790812021-02-25 12:28:49 +0000139 * Constant flow lookup into table.
Paul Elliottbe165bd2021-03-04 14:34:50 +0000140 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200141static unsigned char
142mbedtls_base64_table_lookup(const unsigned char *const table,
143 const size_t table_size,
144 const size_t table_index)
Paul Elliottdadd10d2021-02-05 17:49:23 +0000145{
146 size_t i;
147 unsigned char result = 0;
148
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200149 for (i = 0; i < table_size; ++i) {
150 mbedtls_base64_cond_assign_uchar(&result, &table[i],
151 mbedtls_base64_eq(i, table_index));
Paul Elliottdadd10d2021-02-05 17:49:23 +0000152 }
153
154 return result;
155}
156
Paul Bakker5121ce52009-01-03 21:22:43 +0000157/*
158 * Encode a buffer into base64 format
159 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200160int mbedtls_base64_encode(unsigned char *dst,
161 size_t dlen,
162 size_t *olen,
163 const unsigned char *src,
164 size_t slen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000165{
Paul Bakker23986e52011-04-24 08:57:21 +0000166 size_t i, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000167 int C1, C2, C3;
168 unsigned char *p;
169
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200170 if (slen == 0) {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100171 *olen = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200172 return 0;
Manuel Pégourié-Gonnard65fc6a82015-01-28 16:49:26 +0000173 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000174
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200175 n = slen / 3 + (slen % 3 != 0);
Paul Bakker5121ce52009-01-03 21:22:43 +0000176
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200177 if (n > (BASE64_SIZE_T_MAX - 1) / 4) {
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +0100178 *olen = BASE64_SIZE_T_MAX;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200179 return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
Paul Bakker5121ce52009-01-03 21:22:43 +0000180 }
181
Manuel Pégourié-Gonnard0aa45c22015-09-30 16:30:28 +0200182 n *= 4;
183
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200184 if ((dlen < n + 1) || (NULL == dst)) {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100185 *olen = n + 1;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200186 return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
Paul Bakker5121ce52009-01-03 21:22:43 +0000187 }
188
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200189 n = (slen / 3) * 3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000190
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200191 for (i = 0, p = dst; i < n; i += 3) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000192 C1 = *src++;
193 C2 = *src++;
194 C3 = *src++;
195
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200196 *p++ = mbedtls_base64_table_lookup(
197 base64_enc_map, sizeof(base64_enc_map), ((C1 >> 2) & 0x3F));
Paul Elliottdadd10d2021-02-05 17:49:23 +0000198
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200199 *p++ =
200 mbedtls_base64_table_lookup(base64_enc_map, sizeof(base64_enc_map),
201 ((((C1 & 3) << 4) + (C2 >> 4)) & 0x3F));
Paul Elliottdadd10d2021-02-05 17:49:23 +0000202
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200203 *p++ = mbedtls_base64_table_lookup(
204 base64_enc_map, sizeof(base64_enc_map),
205 ((((C2 & 15) << 2) + (C3 >> 6)) & 0x3F));
Paul Elliottdadd10d2021-02-05 17:49:23 +0000206
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200207 *p++ = mbedtls_base64_table_lookup(base64_enc_map,
208 sizeof(base64_enc_map), (C3 & 0x3F));
Paul Bakker5121ce52009-01-03 21:22:43 +0000209 }
210
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200211 if (i < slen) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000212 C1 = *src++;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200213 C2 = ((i + 1) < slen) ? *src++ : 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000214
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200215 *p++ = mbedtls_base64_table_lookup(
216 base64_enc_map, sizeof(base64_enc_map), ((C1 >> 2) & 0x3F));
Paul Elliottdadd10d2021-02-05 17:49:23 +0000217
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200218 *p++ =
219 mbedtls_base64_table_lookup(base64_enc_map, sizeof(base64_enc_map),
220 ((((C1 & 3) << 4) + (C2 >> 4)) & 0x3F));
Paul Bakker5121ce52009-01-03 21:22:43 +0000221
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200222 if ((i + 1) < slen)
223 *p++ = mbedtls_base64_table_lookup(base64_enc_map,
224 sizeof(base64_enc_map),
225 (((C2 & 15) << 2) & 0x3F));
226 else
227 *p++ = '=';
Paul Bakker5121ce52009-01-03 21:22:43 +0000228
229 *p++ = '=';
230 }
231
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100232 *olen = p - dst;
Paul Bakker5121ce52009-01-03 21:22:43 +0000233 *p = 0;
234
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200235 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000236}
237
238/*
239 * Decode a base64-formatted buffer
240 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200241int mbedtls_base64_decode(unsigned char *dst,
242 size_t dlen,
243 size_t *olen,
244 const unsigned char *src,
245 size_t slen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000246{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000247 size_t i, n;
248 uint32_t j, x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000249 unsigned char *p;
Paul Elliott6e152fa2021-03-01 18:33:09 +0000250 unsigned char dec_map_lookup;
Paul Bakker5121ce52009-01-03 21:22:43 +0000251
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200252 /* First pass: check for validity and get output length */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200253 for (i = n = j = 0; i < slen; i++) {
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200254 /* Skip spaces before checking for EOL */
255 x = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200256 while (i < slen && src[i] == ' ') {
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200257 ++i;
258 ++x;
259 }
260
261 /* Spaces at end of buffer are OK */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200262 if (i == slen)
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200263 break;
264
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200265 if ((slen - i) >= 2 && src[i] == '\r' && src[i + 1] == '\n')
Paul Bakker5121ce52009-01-03 21:22:43 +0000266 continue;
267
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200268 if (src[i] == '\n')
Paul Bakker5121ce52009-01-03 21:22:43 +0000269 continue;
270
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200271 /* Space inside a line is an error */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200272 if (x != 0)
273 return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
Manuel Pégourié-Gonnard64938c62014-10-15 21:45:39 +0200274
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200275 if (src[i] == '=' && ++j > 2)
276 return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
Paul Bakker5121ce52009-01-03 21:22:43 +0000277
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200278 dec_map_lookup = mbedtls_base64_table_lookup(
279 base64_dec_map, sizeof(base64_dec_map), src[i]);
Paul Elliott6e152fa2021-03-01 18:33:09 +0000280
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200281 if (src[i] > 127 || dec_map_lookup == 127)
282 return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
Paul Bakker5121ce52009-01-03 21:22:43 +0000283
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200284 if (dec_map_lookup < 64 && j != 0)
285 return MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
Paul Bakker5121ce52009-01-03 21:22:43 +0000286
287 n++;
288 }
289
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200290 if (n == 0) {
Simon Butchera45aa132015-10-05 00:26:36 +0100291 *olen = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200292 return 0;
Simon Butchera45aa132015-10-05 00:26:36 +0100293 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000294
Simon Butchera29c5e9e2017-02-02 08:46:53 +0000295 /* The following expression is to calculate the following formula without
296 * risk of integer overflow in n:
297 * n = ( ( n * 6 ) + 7 ) >> 3;
298 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200299 n = (6 * (n >> 3)) + ((6 * (n & 0x7) + 7) >> 3);
Paul Bakkerd5983182014-07-04 13:50:31 +0200300 n -= j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000301
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200302 if (dst == NULL || dlen < n) {
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100303 *olen = n;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200304 return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL;
Paul Bakker5121ce52009-01-03 21:22:43 +0000305 }
306
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200307 for (j = 3, n = x = 0, p = dst; i > 0; i--, src++) {
308 if (*src == '\r' || *src == '\n' || *src == ' ')
Paul Bakker5121ce52009-01-03 21:22:43 +0000309 continue;
310
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200311 dec_map_lookup = mbedtls_base64_table_lookup(
312 base64_dec_map, sizeof(base64_dec_map), *src);
Paul Elliott6e152fa2021-03-01 18:33:09 +0000313
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200314 mbedtls_base64_cond_assign_uint32(
315 &j, j - 1, mbedtls_base64_eq(dec_map_lookup, 64));
316 x = (x << 6) | (dec_map_lookup & 0x3F);
Paul Bakker5121ce52009-01-03 21:22:43 +0000317
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200318 if (++n == 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000319 n = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200320 if (j > 0)
321 *p++ = (unsigned char)(x >> 16);
322 if (j > 1)
323 *p++ = (unsigned char)(x >> 8);
324 if (j > 2)
325 *p++ = (unsigned char)(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000326 }
327 }
328
Manuel Pégourié-Gonnardba561362015-06-02 16:30:35 +0100329 *olen = p - dst;
Paul Bakker5121ce52009-01-03 21:22:43 +0000330
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200331 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000332}
333
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200334# if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200336static const unsigned char base64_test_dec[64] = {
337 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD, 0xBF, 0x17, 0xD9,
338 0xA2, 0xC4, 0x17, 0x1A, 0x01, 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3,
339 0xD7, 0x09, 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13, 0xCA,
340 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31, 0x6C, 0x08, 0x34, 0xFF,
341 0x8D, 0xC2, 0x6C, 0x38, 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50,
342 0x4B, 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
Paul Bakker5121ce52009-01-03 21:22:43 +0000343};
344
345static const unsigned char base64_test_enc[] =
346 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
347 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
348
349/*
350 * Checkup routine
351 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200352int mbedtls_base64_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000353{
Paul Bakker23986e52011-04-24 08:57:21 +0000354 size_t len;
Paul Bakker3c2122f2013-06-24 19:03:14 +0200355 const unsigned char *src;
356 unsigned char buffer[128];
Paul Bakker5121ce52009-01-03 21:22:43 +0000357
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200358 if (verbose != 0)
359 mbedtls_printf(" Base64 encoding test: ");
Paul Bakker5121ce52009-01-03 21:22:43 +0000360
Paul Bakker3c2122f2013-06-24 19:03:14 +0200361 src = base64_test_dec;
Paul Bakker5121ce52009-01-03 21:22:43 +0000362
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200363 if (mbedtls_base64_encode(buffer, sizeof(buffer), &len, src, 64) != 0 ||
364 memcmp(base64_test_enc, buffer, 88) != 0) {
365 if (verbose != 0)
366 mbedtls_printf("failed\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000367
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200368 return 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000369 }
370
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200371 if (verbose != 0)
372 mbedtls_printf("passed\n Base64 decoding test: ");
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
Paul Bakker3c2122f2013-06-24 19:03:14 +0200374 src = base64_test_enc;
Paul Bakker5121ce52009-01-03 21:22:43 +0000375
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200376 if (mbedtls_base64_decode(buffer, sizeof(buffer), &len, src, 88) != 0 ||
377 memcmp(base64_test_dec, buffer, 64) != 0) {
378 if (verbose != 0)
379 mbedtls_printf("failed\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000380
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200381 return 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000382 }
383
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200384 if (verbose != 0)
385 mbedtls_printf("passed\n\n");
Paul Bakker5121ce52009-01-03 21:22:43 +0000386
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200387 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000388}
389
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200390# endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000391
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392#endif /* MBEDTLS_BASE64_C */