67
67
68
68
/* Encoding. */
69
69
70
-
static const unsigned char data_bin2ascii[65] =
71
-
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
72
-
73
-
#define conv_bin2ascii(a) (data_bin2ascii[(a) & 0x3f])
70
+
static uint8_t conv_bin2ascii(uint8_t a) {
71
+
/* Since PEM is sometimes used to carry private keys, we encode base64 data
72
+
* itself in constant-time. */
73
+
a &= 0x3f;
74
+
uint8_t ret = constant_time_select_8(constant_time_eq_8(a, 62), '+', '/');
75
+
ret = constant_time_select_8(constant_time_lt_8(a, 62), a - 52 + '0', ret);
76
+
ret = constant_time_select_8(constant_time_lt_8(a, 52), a - 26 + 'a', ret);
77
+
ret = constant_time_select_8(constant_time_lt_8(a, 26), a + 'A', ret);
78
+
return ret;
79
+
}
74
80
75
81
OPENSSL_COMPILE_ASSERT(sizeof(((EVP_ENCODE_CTX *)(NULL))->data) % 3 == 0,
76
82
data_length_must_be_multiple_of_base64_chunk_size);
@@ -229,29 +235,28 @@ void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) {
229
235
OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX));
230
236
}
231
237
232
-
/* kBase64ASCIIToBinData maps characters (c < 128) to their base64 value, or
233
-
* else 0xff if they are invalid. As a special case, the padding character
234
-
* ('=') is mapped to zero. */
235
-
static const uint8_t kBase64ASCIIToBinData[128] = {
236
-
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff,
237
-
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
238
-
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff,
239
-
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
240
-
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
241
-
0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
242
-
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
243
-
0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
244
-
0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
245
-
0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
246
-
0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
247
-
};
248
-
249
238
static uint8_t base64_ascii_to_bin(uint8_t a) {
250
-
if (a >= 128) {
251
-
return 0xFF;
252
-
}
253
-
254
-
return kBase64ASCIIToBinData[a];
239
+
/* Since PEM is sometimes used to carry private keys, we decode base64 data
240
+
* itself in constant-time. */
241
+
const uint8_t is_upper =
242
+
constant_time_ge_8(a, 'A') & constant_time_ge_8('Z', a);
243
+
const uint8_t is_lower =
244
+
constant_time_ge_8(a, 'a') & constant_time_ge_8('z', a);
245
+
const uint8_t is_digit =
246
+
constant_time_ge_8(a, '0') & constant_time_ge_8('9', a);
247
+
const uint8_t is_plus = constant_time_eq_8(a, '+');
248
+
const uint8_t is_slash = constant_time_eq_8(a, '/');
249
+
const uint8_t is_equals = constant_time_eq_8(a, '=');
250
+
251
+
uint8_t ret = 0xff; /* 0xff signals invalid. */
252
+
ret = constant_time_select_8(is_upper, a - 'A', ret); /* [0,26) */
253
+
ret = constant_time_select_8(is_lower, a - 'a' + 26, ret); /* [26,52) */
254
+
ret = constant_time_select_8(is_digit, a - '0' + 52, ret); /* [52,62) */
255
+
ret = constant_time_select_8(is_plus, 62, ret);
256
+
ret = constant_time_select_8(is_slash, 63, ret);
257
+
/* Padding maps to zero, to be further handled by the caller. */
258
+
ret = constant_time_select_8(is_equals, 0, ret);
259
+
return ret;
255
260
}
256
261
257
262
/* base64_decode_quad decodes a single “quad” (i.e. four characters) of base64
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4