aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2018-05-30 21:32:27 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2018-05-31 01:24:51 +0200
commitfc07df7d4c5d87a4789b13c2df6a482ebf9e924d (patch)
tree665074a29a61b754c0ce1990ebb34a09a21606c1
parentdevice: do not assume dst is always valid (diff)
downloadwireguard-monolithic-historical-fc07df7d4c5d87a4789b13c2df6a482ebf9e924d.tar.xz
wireguard-monolithic-historical-fc07df7d4c5d87a4789b13c2df6a482ebf9e924d.zip
tools: constanter time encoding
-rw-r--r--contrib/examples/embeddable-wg-library/wireguard.c14
-rw-r--r--src/tools/encoding.c36
2 files changed, 28 insertions, 22 deletions
diff --git a/contrib/examples/embeddable-wg-library/wireguard.c b/contrib/examples/embeddable-wg-library/wireguard.c
index 16ddd9a..560d7ab 100644
--- a/contrib/examples/embeddable-wg-library/wireguard.c
+++ b/contrib/examples/embeddable-wg-library/wireguard.c
@@ -1559,25 +1559,25 @@ int wg_key_from_base64(wg_key key, const wg_key_b64_string base64)
{
unsigned int i;
int val;
+ volatile uint8_t ret = 0;
- errno = EINVAL;
- if (strlen(base64) != sizeof(wg_key_b64_string) - 1 || base64[sizeof(wg_key_b64_string) - 2] != '=')
+ if (strlen(base64) != sizeof(wg_key_b64_string) - 1 || base64[sizeof(wg_key_b64_string) - 2] != '=') {
+ errno = EINVAL;
goto out;
+ }
for (i = 0; i < 32 / 3; ++i) {
val = decode_base64(&base64[i * 4]);
- if (val < 0)
- goto out;
+ ret |= (uint32_t)val >> 31;
key[i * 3 + 0] = (val >> 16) & 0xff;
key[i * 3 + 1] = (val >> 8) & 0xff;
key[i * 3 + 2] = val & 0xff;
}
val = decode_base64((const char[]){ base64[i * 4 + 0], base64[i * 4 + 1], base64[i * 4 + 2], 'A' });
- if (val < 0 || val & 0xff)
- goto out;
+ ret |= ((uint32_t)val >> 31) | (val & 0xff);
key[i * 3 + 0] = (val >> 16) & 0xff;
key[i * 3 + 1] = (val >> 8) & 0xff;
- errno = 0;
+ errno = EINVAL & ~((ret - 1) >> 8);
out:
return -errno;
}
diff --git a/src/tools/encoding.c b/src/tools/encoding.c
index cb1b123..a9ed694 100644
--- a/src/tools/encoding.c
+++ b/src/tools/encoding.c
@@ -50,6 +50,7 @@ static inline int decode_base64(const char src[4])
bool key_from_base64(uint8_t key[static WG_KEY_LEN], const char *base64)
{
unsigned int i;
+ volatile uint8_t ret = 0;
int val;
if (strlen(base64) != WG_KEY_LEN_BASE64 - 1 || base64[WG_KEY_LEN_BASE64 - 2] != '=')
@@ -57,18 +58,17 @@ bool key_from_base64(uint8_t key[static WG_KEY_LEN], const char *base64)
for (i = 0; i < WG_KEY_LEN / 3; ++i) {
val = decode_base64(&base64[i * 4]);
- if (val < 0)
- return false;
+ ret |= (uint32_t)val >> 31;
key[i * 3 + 0] = (val >> 16) & 0xff;
key[i * 3 + 1] = (val >> 8) & 0xff;
key[i * 3 + 2] = val & 0xff;
}
val = decode_base64((const char[]){ base64[i * 4 + 0], base64[i * 4 + 1], base64[i * 4 + 2], 'A' });
- if (val < 0 || val & 0xff)
- return false;
+ ret |= ((uint32_t)val >> 31) | (val & 0xff);
key[i * 3 + 0] = (val >> 16) & 0xff;
key[i * 3 + 1] = (val >> 8) & 0xff;
- return true;
+
+ return 1 & ((ret - 1) >> 8);
}
void key_to_hex(char hex[static WG_KEY_LEN_HEX], const uint8_t key[static WG_KEY_LEN])
@@ -84,27 +84,33 @@ void key_to_hex(char hex[static WG_KEY_LEN_HEX], const uint8_t key[static WG_KEY
bool key_from_hex(uint8_t key[static WG_KEY_LEN], const char *hex)
{
- uint8_t c, c_acc = 0, c_alpha0, c_alpha, c_num0, c_num, c_val, state = 0;
+ uint8_t c, c_acc = 0, c_alpha0, c_alpha, c_num0, c_num, c_val;
+ volatile uint8_t ret = 0;
if (strlen(hex) != WG_KEY_LEN_HEX - 1)
return false;
- for (unsigned int i = 0; i < WG_KEY_LEN_HEX - 1; ++i) {
+ for (unsigned int i = 0; i < WG_KEY_LEN_HEX - 1; i += 2) {
c = (uint8_t)hex[i];
c_num = c ^ 48U;
c_num0 = (c_num - 10U) >> 8;
c_alpha = (c & ~32U) - 55U;
c_alpha0 = ((c_alpha - 10U) ^ (c_alpha - 16U)) >> 8;
- if (!(c_num0 | c_alpha0))
- return false;
+ ret |= ((c_num0 | c_alpha0) - 1) >> 8;
c_val = (c_num0 & c_num) | (c_alpha0 & c_alpha);
- if (!state)
- c_acc = c_val * 16U;
- else
- key[i / 2] = c_acc | c_val;
- state = ~state;
+ c_acc = c_val * 16U;
+
+ c = (uint8_t)hex[i + 1];
+ c_num = c ^ 48U;
+ c_num0 = (c_num - 10U) >> 8;
+ c_alpha = (c & ~32U) - 55U;
+ c_alpha0 = ((c_alpha - 10U) ^ (c_alpha - 16U)) >> 8;
+ ret |= ((c_num0 | c_alpha0) - 1) >> 8;
+ c_val = (c_num0 & c_num) | (c_alpha0 & c_alpha);
+ key[i / 2] = c_acc | c_val;
}
- return true;
+
+ return 1 & ((ret - 1) >> 8);
}
bool key_is_zero(const uint8_t key[static WG_KEY_LEN])