wg: use key_is_zero for comparing to zeros
Maybe an attacker on the system could use the infoleak in /proc to gauge how long a wg(8) process takes to complete and determine the number of leading zeros. This is somewhat ridiculous, but it's possible somebody somewhere might at somepoint care in the future, so alright. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
		
							parent
							
								
									6c7d67acfe
								
							
						
					
					
						commit
						9ef84af8c0
					
				
							
								
								
									
										10
									
								
								src/config.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/config.c
									
									
									
									
									
								
							@ -387,17 +387,11 @@ bool config_read_init(struct config_ctx *ctx, struct wgdevice **device, bool app
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool key_is_valid(uint8_t key[WG_KEY_LEN])
 | 
			
		||||
{
 | 
			
		||||
	static const uint8_t zero[WG_KEY_LEN] = { 0 };
 | 
			
		||||
	return !!memcmp(key, zero, WG_KEY_LEN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool config_read_finish(struct config_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	size_t i;
 | 
			
		||||
	struct wgpeer *peer;
 | 
			
		||||
	if (ctx->buf.dev->flags & WGDEVICE_REPLACE_PEERS && !key_is_valid(ctx->buf.dev->private_key)) {
 | 
			
		||||
	if (ctx->buf.dev->flags & WGDEVICE_REPLACE_PEERS && key_is_zero(ctx->buf.dev->private_key)) {
 | 
			
		||||
		fprintf(stderr, "No private key configured\n");
 | 
			
		||||
		goto err;
 | 
			
		||||
	}
 | 
			
		||||
@ -405,7 +399,7 @@ bool config_read_finish(struct config_ctx *ctx)
 | 
			
		||||
		ctx->buf.dev->flags |= WGDEVICE_REMOVE_FWMARK;
 | 
			
		||||
 | 
			
		||||
	for_each_wgpeer(ctx->buf.dev, peer, i) {
 | 
			
		||||
		if (!key_is_valid(peer->public_key)) {
 | 
			
		||||
		if (key_is_zero(peer->public_key)) {
 | 
			
		||||
			fprintf(stderr, "A peer is missing a public key\n");
 | 
			
		||||
			goto err;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -77,12 +77,12 @@ 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 i, 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, state = 0;
 | 
			
		||||
 | 
			
		||||
	if (strlen(hex) != WG_KEY_LEN_HEX - 1)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < WG_KEY_LEN_HEX - 1; ++i) {
 | 
			
		||||
	for (unsigned int i = 0; i < WG_KEY_LEN_HEX - 1; ++i) {
 | 
			
		||||
		c = (uint8_t)hex[i];
 | 
			
		||||
		c_num = c ^ 48U;
 | 
			
		||||
		c_num0 = (c_num - 10U) >> 8;
 | 
			
		||||
@ -99,3 +99,13 @@ bool key_from_hex(uint8_t key[static WG_KEY_LEN], const char *hex)
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool key_is_zero(const uint8_t key[static WG_KEY_LEN])
 | 
			
		||||
{
 | 
			
		||||
	uint8_t acc = 0;
 | 
			
		||||
	for (unsigned int i = 0; i < WG_KEY_LEN; ++i) {
 | 
			
		||||
		acc |= key[i];
 | 
			
		||||
		__asm__ ("" : "=r" (acc) : "0" (acc));
 | 
			
		||||
	}
 | 
			
		||||
	return acc == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -16,4 +16,6 @@ bool key_from_base64(uint8_t key[static WG_KEY_LEN], const char *base64);
 | 
			
		||||
void key_to_hex(char hex[static WG_KEY_LEN_HEX], const uint8_t key[static WG_KEY_LEN]);
 | 
			
		||||
bool key_from_hex(uint8_t key[static WG_KEY_LEN], const char *hex);
 | 
			
		||||
 | 
			
		||||
bool key_is_zero(const uint8_t key[static WG_KEY_LEN]);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -170,7 +170,6 @@ out:
 | 
			
		||||
 | 
			
		||||
static int userspace_set_device(struct wgdevice *dev)
 | 
			
		||||
{
 | 
			
		||||
	static const uint8_t zero[WG_KEY_LEN] = { 0 };
 | 
			
		||||
	char hex[WG_KEY_LEN_HEX], ip[INET6_ADDRSTRLEN], host[4096 + 1], service[512 + 1];
 | 
			
		||||
	struct wgpeer *peer;
 | 
			
		||||
	struct wgipmask *ipmask;
 | 
			
		||||
@ -186,7 +185,7 @@ static int userspace_set_device(struct wgdevice *dev)
 | 
			
		||||
 | 
			
		||||
	if (dev->flags & WGDEVICE_REMOVE_PRIVATE_KEY)
 | 
			
		||||
		fprintf(f, "private_key=\n");
 | 
			
		||||
	else if (memcmp(dev->private_key, zero, WG_KEY_LEN)) {
 | 
			
		||||
	else if (!key_is_zero(dev->private_key)) {
 | 
			
		||||
		key_to_hex(hex, dev->private_key);
 | 
			
		||||
		fprintf(f, "private_key=%s\n", hex);
 | 
			
		||||
	}
 | 
			
		||||
@ -208,7 +207,7 @@ static int userspace_set_device(struct wgdevice *dev)
 | 
			
		||||
		}
 | 
			
		||||
		if (peer->flags & WGPEER_REMOVE_PRESHARED_KEY)
 | 
			
		||||
			fprintf(f, "preshared_key=\n");
 | 
			
		||||
		else if (memcmp(peer->preshared_key, zero, WG_KEY_LEN)) {
 | 
			
		||||
		else if (!key_is_zero(peer->preshared_key)) {
 | 
			
		||||
			key_to_hex(hex, peer->preshared_key);
 | 
			
		||||
			fprintf(f, "preshared_key=%s\n", hex);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								src/show.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/show.c
									
									
									
									
									
								
							@ -75,12 +75,10 @@ static void sort_peers(struct wgdevice *device)
 | 
			
		||||
	free(new_device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const uint8_t zero[WG_KEY_LEN] = { 0 };
 | 
			
		||||
 | 
			
		||||
static char *key(const uint8_t key[static WG_KEY_LEN])
 | 
			
		||||
{
 | 
			
		||||
	static char base64[WG_KEY_LEN_BASE64];
 | 
			
		||||
	if (!memcmp(key, zero, WG_KEY_LEN))
 | 
			
		||||
	if (key_is_zero(key))
 | 
			
		||||
		return "(none)";
 | 
			
		||||
	key_to_base64(base64, key);
 | 
			
		||||
	return base64;
 | 
			
		||||
@ -212,9 +210,9 @@ static void pretty_print(struct wgdevice *device)
 | 
			
		||||
 | 
			
		||||
	terminal_printf(TERMINAL_RESET);
 | 
			
		||||
	terminal_printf(TERMINAL_FG_GREEN TERMINAL_BOLD "interface" TERMINAL_RESET ": " TERMINAL_FG_GREEN "%s" TERMINAL_RESET "\n", device->interface);
 | 
			
		||||
	if (memcmp(device->public_key, zero, WG_KEY_LEN))
 | 
			
		||||
	if (!key_is_zero(device->public_key))
 | 
			
		||||
		terminal_printf("  " TERMINAL_BOLD "public key" TERMINAL_RESET ": %s\n", key(device->public_key));
 | 
			
		||||
	if (memcmp(device->private_key, zero, WG_KEY_LEN))
 | 
			
		||||
	if (!key_is_zero(device->private_key))
 | 
			
		||||
		terminal_printf("  " TERMINAL_BOLD "private key" TERMINAL_RESET ": %s\n", masked_key(device->private_key));
 | 
			
		||||
	if (device->port)
 | 
			
		||||
		terminal_printf("  " TERMINAL_BOLD "listening port" TERMINAL_RESET ": %u\n", device->port);
 | 
			
		||||
@ -226,7 +224,7 @@ static void pretty_print(struct wgdevice *device)
 | 
			
		||||
	}
 | 
			
		||||
	for_each_wgpeer(device, peer, i) {
 | 
			
		||||
		terminal_printf(TERMINAL_FG_YELLOW TERMINAL_BOLD "peer" TERMINAL_RESET ": " TERMINAL_FG_YELLOW "%s" TERMINAL_RESET "\n", key(peer->public_key));
 | 
			
		||||
		if (memcmp(peer->preshared_key, zero, WG_KEY_LEN))
 | 
			
		||||
		if (!key_is_zero(peer->preshared_key))
 | 
			
		||||
			terminal_printf("  " TERMINAL_BOLD "preshared key" TERMINAL_RESET ": %s\n", masked_key(peer->preshared_key));
 | 
			
		||||
		if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6)
 | 
			
		||||
			terminal_printf("  " TERMINAL_BOLD "endpoint" TERMINAL_RESET ": %s\n", endpoint(&peer->endpoint.addr));
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,6 @@
 | 
			
		||||
 | 
			
		||||
int showconf_main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	static const uint8_t zero[WG_KEY_LEN] = { 0 };
 | 
			
		||||
	char base64[WG_KEY_LEN_BASE64];
 | 
			
		||||
	char ip[INET6_ADDRSTRLEN];
 | 
			
		||||
	struct wgdevice *device = NULL;
 | 
			
		||||
@ -46,7 +45,7 @@ int showconf_main(int argc, char *argv[])
 | 
			
		||||
		printf("ListenPort = %u\n", device->port);
 | 
			
		||||
	if (device->fwmark)
 | 
			
		||||
		printf("FwMark = 0x%x\n", device->fwmark);
 | 
			
		||||
	if (memcmp(device->private_key, zero, WG_KEY_LEN)) {
 | 
			
		||||
	if (!key_is_zero(device->private_key)) {
 | 
			
		||||
		key_to_base64(base64, device->private_key);
 | 
			
		||||
		printf("PrivateKey = %s\n", base64);
 | 
			
		||||
	}
 | 
			
		||||
@ -54,7 +53,7 @@ int showconf_main(int argc, char *argv[])
 | 
			
		||||
	for_each_wgpeer(device, peer, i) {
 | 
			
		||||
		key_to_base64(base64, peer->public_key);
 | 
			
		||||
		printf("[Peer]\nPublicKey = %s\n", base64);
 | 
			
		||||
		if (memcmp(peer->preshared_key, zero, WG_KEY_LEN)) {
 | 
			
		||||
		if (!key_is_zero(peer->preshared_key)) {
 | 
			
		||||
			key_to_base64(base64, peer->preshared_key);
 | 
			
		||||
			printf("PresharedKey = %s\n", base64);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user