]> git.ipfire.org Git - thirdparty/wireguard-tools.git/commitdiff
wg: constanter time encoding
authorJason A. Donenfeld <Jason@zx2c4.com>
Wed, 30 May 2018 19:32:27 +0000 (21:32 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Wed, 30 May 2018 23:24:51 +0000 (01:24 +0200)
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
contrib/embeddable-wg-library/wireguard.c
src/encoding.c

index 16ddd9a0824503e07fe3d4277898c4c30be98190..560d7ab1e32630f683b1ced4a1dda8ba33f27d9a 100644 (file)
@@ -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;
 }
index cb1b123b59fc06fd5c949416cb12054148867b2a..a9ed69454be364d4cdd52b8525d20fceb29502d6 100644 (file)
@@ -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])