ctype: use non-locale-specific ctype.h
We also make these constant time, even though we're never distinguishing between bits of a secret using them. From that perspective, though, this is markedly better than the locale-specific table lookups in glibc, even though base64 characters span two cache lines and valid private keys must hit both. Co-authored-by: Samuel Neves <sneves@dei.uc.pt> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Samuel Neves <sneves@dei.uc.pt>
This commit is contained in:
parent
cf2bf09524
commit
13fac76a71
14
src/config.c
14
src/config.c
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <ctype.h>
|
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -19,6 +18,7 @@
|
||||||
#include "containers.h"
|
#include "containers.h"
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
|
#include "ctype.h"
|
||||||
|
|
||||||
#define COMMENT_CHAR '#'
|
#define COMMENT_CHAR '#'
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ static inline bool parse_fwmark(uint32_t *fwmark, uint32_t *flags, const char *v
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isdigit(value[0]))
|
if (!char_is_digit(value[0]))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (strlen(value) > 2 && value[0] == '0' && value[1] == 'x')
|
if (strlen(value) > 2 && value[0] == '0' && value[1] == 'x')
|
||||||
|
@ -141,7 +141,7 @@ static bool parse_keyfile(uint8_t key[static WG_KEY_LEN], const char *path)
|
||||||
dst[WG_KEY_LEN_BASE64 - 1] = '\0';
|
dst[WG_KEY_LEN_BASE64 - 1] = '\0';
|
||||||
|
|
||||||
while ((c = getc(f)) != EOF) {
|
while ((c = getc(f)) != EOF) {
|
||||||
if (!isspace(c)) {
|
if (!char_is_space(c)) {
|
||||||
fprintf(stderr, "Found trailing character in key file: `%c'\n", c);
|
fprintf(stderr, "Found trailing character in key file: `%c'\n", c);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -290,7 +290,7 @@ static inline bool parse_persistent_keepalive(uint16_t *interval, uint32_t *flag
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isdigit(value[0]))
|
if (!char_is_digit(value[0]))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
ret = strtoul(value, &end, 10);
|
ret = strtoul(value, &end, 10);
|
||||||
|
@ -375,7 +375,7 @@ static inline bool parse_allowedips(struct wgpeer *peer, struct wgallowedip **la
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask) {
|
if (mask) {
|
||||||
if (!isdigit(mask[0]))
|
if (!char_is_digit(mask[0]))
|
||||||
goto err;
|
goto err;
|
||||||
cidr = strtoul(mask, &end, 10);
|
cidr = strtoul(mask, &end, 10);
|
||||||
if (*end || (cidr > 32 && new_allowedip->family == AF_INET) || (cidr > 128 && new_allowedip->family == AF_INET6))
|
if (*end || (cidr > 32 && new_allowedip->family == AF_INET) || (cidr > 128 && new_allowedip->family == AF_INET6))
|
||||||
|
@ -501,7 +501,7 @@ bool config_read_line(struct config_ctx *ctx, const char *input)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < len; ++i) {
|
for (size_t i = 0; i < len; ++i) {
|
||||||
if (!isspace(input[i]))
|
if (!char_is_space(input[i]))
|
||||||
line[cleaned_len++] = input[i];
|
line[cleaned_len++] = input[i];
|
||||||
}
|
}
|
||||||
if (!cleaned_len)
|
if (!cleaned_len)
|
||||||
|
@ -555,7 +555,7 @@ static char *strip_spaces(const char *in)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (i = 0, l = 0; i < t; ++i) {
|
for (i = 0, l = 0; i < t; ++i) {
|
||||||
if (!isspace(in[i]))
|
if (!char_is_space(in[i]))
|
||||||
out[l++] = in[i];
|
out[l++] = in[i];
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Specialized constant-time ctype.h reimplementations that aren't locale-specific.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CTYPE_H
|
||||||
|
#define CTYPE_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
static inline bool char_is_space(int c)
|
||||||
|
{
|
||||||
|
unsigned char d = c - 9;
|
||||||
|
return (0x80001FU >> (d & 31)) & (1U >> (d >> 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool char_is_digit(int c)
|
||||||
|
{
|
||||||
|
return (unsigned int)(('0' - 1 - c) & (c - ('9' + 1))) >> (sizeof(c) * 8 - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool char_is_alpha(int c)
|
||||||
|
{
|
||||||
|
return (unsigned int)(('a' - 1 - (c | 32)) & ((c | 32) - ('z' + 1))) >> (sizeof(c) * 8 - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -4,7 +4,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
@ -17,6 +16,7 @@
|
||||||
#include "containers.h"
|
#include "containers.h"
|
||||||
#include "curve25519.h"
|
#include "curve25519.h"
|
||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
|
#include "ctype.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "ipc-uapi-windows.h"
|
#include "ipc-uapi-windows.h"
|
||||||
|
@ -102,7 +102,7 @@ static int userspace_set_device(struct wgdevice *dev)
|
||||||
#define NUM(max) ({ \
|
#define NUM(max) ({ \
|
||||||
unsigned long long num; \
|
unsigned long long num; \
|
||||||
char *end; \
|
char *end; \
|
||||||
if (!isdigit(value[0])) \
|
if (!char_is_digit(value[0])) \
|
||||||
break; \
|
break; \
|
||||||
num = strtoull(value, &end, 10); \
|
num = strtoull(value, &end, 10); \
|
||||||
if (*end || num > max) \
|
if (*end || num > max) \
|
||||||
|
@ -223,7 +223,7 @@ static int userspace_get_device(struct wgdevice **out, const char *iface)
|
||||||
struct wgallowedip *new_allowedip;
|
struct wgallowedip *new_allowedip;
|
||||||
char *end, *mask = value, *ip = strsep(&mask, "/");
|
char *end, *mask = value, *ip = strsep(&mask, "/");
|
||||||
|
|
||||||
if (!mask || !isdigit(mask[0]))
|
if (!mask || !char_is_digit(mask[0]))
|
||||||
break;
|
break;
|
||||||
new_allowedip = calloc(1, sizeof(*new_allowedip));
|
new_allowedip = calloc(1, sizeof(*new_allowedip));
|
||||||
if (!new_allowedip) {
|
if (!new_allowedip) {
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "curve25519.h"
|
#include "curve25519.h"
|
||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
#include "subcommands.h"
|
#include "subcommands.h"
|
||||||
|
#include "ctype.h"
|
||||||
|
|
||||||
int pubkey_main(int argc, char *argv[])
|
int pubkey_main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,7 @@ int pubkey_main(int argc, char *argv[])
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
trailing_char = getc(stdin);
|
trailing_char = getc(stdin);
|
||||||
if (!trailing_char || isspace(trailing_char))
|
if (!trailing_char || char_is_space(trailing_char))
|
||||||
continue;
|
continue;
|
||||||
if (trailing_char == EOF)
|
if (trailing_char == EOF)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -11,6 +10,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include "ctype.h"
|
||||||
|
|
||||||
static bool color_mode(void)
|
static bool color_mode(void)
|
||||||
{
|
{
|
||||||
|
@ -46,7 +46,7 @@ static void filter_ansi(const char *fmt, va_list args)
|
||||||
if (str[i] == '\x1b' && str[i + 1] == '[') {
|
if (str[i] == '\x1b' && str[i + 1] == '[') {
|
||||||
str[i] = str[i + 1] = '\0';
|
str[i] = str[i + 1] = '\0';
|
||||||
for (j = i + 2; j < len; ++j) {
|
for (j = i + 2; j < len; ++j) {
|
||||||
if (isalpha(str[j]))
|
if (char_is_alpha(str[j]))
|
||||||
break;
|
break;
|
||||||
str[j] = '\0';
|
str[j] = '\0';
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue