global: style nits
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
		
							parent
							
								
									d9d0a2cbed
								
							
						
					
					
						commit
						b1dd8d711e
					
				
							
								
								
									
										11
									
								
								src/config.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/config.c
									
									
									
									
									
								
							@ -222,6 +222,7 @@ static inline bool parse_allowedips(struct wgpeer *peer, struct wgallowedip **la
 | 
			
		||||
{
 | 
			
		||||
	struct wgallowedip *allowedip = *last_allowedip, *new_allowedip;
 | 
			
		||||
	char *mask, *mutable = strdup(value), *sep;
 | 
			
		||||
 | 
			
		||||
	if (!mutable) {
 | 
			
		||||
		perror("strdup");
 | 
			
		||||
		return false;
 | 
			
		||||
@ -235,6 +236,7 @@ static inline bool parse_allowedips(struct wgpeer *peer, struct wgallowedip **la
 | 
			
		||||
	while ((mask = strsep(&sep, ","))) {
 | 
			
		||||
		unsigned long cidr = ULONG_MAX;
 | 
			
		||||
		char *end, *ip = strsep(&mask, "/");
 | 
			
		||||
 | 
			
		||||
		new_allowedip = calloc(1, sizeof(struct wgallowedip));
 | 
			
		||||
		if (!new_allowedip) {
 | 
			
		||||
			perror("calloc");
 | 
			
		||||
@ -281,6 +283,7 @@ static bool process_line(struct config_ctx *ctx, const char *line)
 | 
			
		||||
	}
 | 
			
		||||
	if (!strcasecmp(line, "[Peer]")) {
 | 
			
		||||
		struct wgpeer *new_peer = calloc(1, sizeof(struct wgpeer));
 | 
			
		||||
 | 
			
		||||
		if (!new_peer) {
 | 
			
		||||
			perror("calloc");
 | 
			
		||||
			return false;
 | 
			
		||||
@ -345,6 +348,7 @@ bool config_read_line(struct config_ctx *ctx, const char *input)
 | 
			
		||||
	size_t len = strlen(input), cleaned_len = 0;
 | 
			
		||||
	char *line = calloc(len + 1, sizeof(char));
 | 
			
		||||
	bool ret = true;
 | 
			
		||||
 | 
			
		||||
	if (!line) {
 | 
			
		||||
		perror("calloc");
 | 
			
		||||
		ret = false;
 | 
			
		||||
@ -384,6 +388,7 @@ bool config_read_init(struct config_ctx *ctx, bool append)
 | 
			
		||||
struct wgdevice *config_read_finish(struct config_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct wgpeer *peer;
 | 
			
		||||
 | 
			
		||||
	for_each_wgpeer(ctx->device, peer) {
 | 
			
		||||
		if (key_is_zero(peer->public_key)) {
 | 
			
		||||
			fprintf(stderr, "A peer is missing a public key\n");
 | 
			
		||||
@ -416,6 +421,7 @@ static bool read_keyfile(char dst[WG_KEY_LEN_BASE64], const char *path)
 | 
			
		||||
		/* If we're at the end and we didn't read anything, we're /dev/null. */
 | 
			
		||||
		if (!ferror(f) && feof(f) && !ftell(f)) {
 | 
			
		||||
			static const uint8_t zeros[WG_KEY_LEN] = { 0 };
 | 
			
		||||
 | 
			
		||||
			key_to_base64(dst, zeros);
 | 
			
		||||
			ret = true;
 | 
			
		||||
			goto out;
 | 
			
		||||
@ -466,6 +472,7 @@ struct wgdevice *config_read_cmd(char *argv[], int argc)
 | 
			
		||||
	struct wgdevice *device = calloc(1, sizeof(struct wgdevice));
 | 
			
		||||
	struct wgpeer *peer = NULL;
 | 
			
		||||
	struct wgallowedip *allowedip = NULL;
 | 
			
		||||
 | 
			
		||||
	if (!device) {
 | 
			
		||||
		perror("calloc");
 | 
			
		||||
		return false;
 | 
			
		||||
@ -483,6 +490,7 @@ struct wgdevice *config_read_cmd(char *argv[], int argc)
 | 
			
		||||
			argc -= 2;
 | 
			
		||||
		} else if (!strcmp(argv[0], "private-key") && argc >= 2 && !peer) {
 | 
			
		||||
			char key_line[WG_KEY_LEN_BASE64];
 | 
			
		||||
 | 
			
		||||
			if (read_keyfile(key_line, argv[1])) {
 | 
			
		||||
				if (!parse_key(device->private_key, key_line))
 | 
			
		||||
					goto error;
 | 
			
		||||
@ -493,6 +501,7 @@ struct wgdevice *config_read_cmd(char *argv[], int argc)
 | 
			
		||||
			argc -= 2;
 | 
			
		||||
		} else if (!strcmp(argv[0], "peer") && argc >= 2) {
 | 
			
		||||
			struct wgpeer *new_peer = calloc(1, sizeof(struct wgpeer));
 | 
			
		||||
 | 
			
		||||
			allowedip = NULL;
 | 
			
		||||
			if (!new_peer) {
 | 
			
		||||
				perror("calloc");
 | 
			
		||||
@ -518,6 +527,7 @@ struct wgdevice *config_read_cmd(char *argv[], int argc)
 | 
			
		||||
			argc -= 2;
 | 
			
		||||
		} else if (!strcmp(argv[0], "allowed-ips") && argc >= 2 && peer) {
 | 
			
		||||
			char *line = strip_spaces(argv[1]);
 | 
			
		||||
 | 
			
		||||
			if (!line)
 | 
			
		||||
				goto error;
 | 
			
		||||
			if (!parse_allowedips(peer, &allowedip, line)) {
 | 
			
		||||
@ -534,6 +544,7 @@ struct wgdevice *config_read_cmd(char *argv[], int argc)
 | 
			
		||||
			argc -= 2;
 | 
			
		||||
		} else if (!strcmp(argv[0], "preshared-key") && argc >= 2 && peer) {
 | 
			
		||||
			char key_line[WG_KEY_LEN_BASE64];
 | 
			
		||||
 | 
			
		||||
			if (read_keyfile(key_line, argv[1])) {
 | 
			
		||||
				if (!parse_key(peer->preshared_key, key_line))
 | 
			
		||||
					goto error;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										243
									
								
								src/curve25519.c
									
									
									
									
									
								
							
							
						
						
									
										243
									
								
								src/curve25519.c
									
									
									
									
									
								
							@ -107,7 +107,7 @@ static __always_inline void fscalar_product(felem output, const felem in, const
 | 
			
		||||
static __always_inline void fmul(felem output, const felem in2, const felem in)
 | 
			
		||||
{
 | 
			
		||||
	uint128_t t[5];
 | 
			
		||||
	limb r0,r1,r2,r3,r4,s0,s1,s2,s3,s4,c;
 | 
			
		||||
	limb r0, r1, r2, r3, r4, s0, s1, s2, s3, s4, c;
 | 
			
		||||
 | 
			
		||||
	r0 = in[0];
 | 
			
		||||
	r1 = in[1];
 | 
			
		||||
@ -156,8 +156,8 @@ static __always_inline void fmul(felem output, const felem in2, const felem in)
 | 
			
		||||
static __always_inline void fsquare_times(felem output, const felem in, limb count)
 | 
			
		||||
{
 | 
			
		||||
	uint128_t t[5];
 | 
			
		||||
	limb r0,r1,r2,r3,r4,c;
 | 
			
		||||
	limb d0,d1,d2,d4,d419;
 | 
			
		||||
	limb r0, r1, r2, r3, r4, c;
 | 
			
		||||
	limb d0, d1, d2, d4, d419;
 | 
			
		||||
 | 
			
		||||
	r0 = in[0];
 | 
			
		||||
	r1 = in[1];
 | 
			
		||||
@ -186,7 +186,7 @@ static __always_inline void fsquare_times(felem output, const felem in, limb cou
 | 
			
		||||
		r0 +=   c * 19; c = r0 >> 51; r0 = r0 & 0x7ffffffffffffUL;
 | 
			
		||||
		r1 +=   c;      c = r1 >> 51; r1 = r1 & 0x7ffffffffffffUL;
 | 
			
		||||
		r2 +=   c;
 | 
			
		||||
	} while(--count);
 | 
			
		||||
	} while (--count);
 | 
			
		||||
 | 
			
		||||
	output[0] = r0;
 | 
			
		||||
	output[1] = r1;
 | 
			
		||||
@ -302,6 +302,7 @@ static void fmonty(limb *x2, limb *z2, /* output 2Q */
 | 
			
		||||
			 limb *x3, limb *z3, /* output Q + Q' */
 | 
			
		||||
			 limb *x, limb *z,   /* input Q */
 | 
			
		||||
			 limb *xprime, limb *zprime, /* input Q' */
 | 
			
		||||
 | 
			
		||||
			 const limb *qmqp /* input Q - Q' */)
 | 
			
		||||
{
 | 
			
		||||
	limb origx[5], origxprime[5], zzz[5], xx[5], zz[5], xxprime[5], zzprime[5], zzzprime[5];
 | 
			
		||||
@ -339,11 +340,12 @@ static void fmonty(limb *x2, limb *z2, /* output 2Q */
 | 
			
		||||
 */
 | 
			
		||||
static void swap_conditional(limb a[static 5], limb b[static 5], limb iswap)
 | 
			
		||||
{
 | 
			
		||||
	unsigned i;
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
	const limb swap = -iswap;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 5; ++i) {
 | 
			
		||||
		const limb x = swap & (a[i] ^ b[i]);
 | 
			
		||||
 | 
			
		||||
		a[i] ^= x;
 | 
			
		||||
		b[i] ^= x;
 | 
			
		||||
	}
 | 
			
		||||
@ -362,12 +364,13 @@ static void cmult(limb *resultx, limb *resultz, const uint8_t *n, const limb *q)
 | 
			
		||||
	limb e[5] = {0}, f[5] = {1}, g[5] = {0}, h[5] = {1};
 | 
			
		||||
	limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h;
 | 
			
		||||
 | 
			
		||||
	unsigned i, j;
 | 
			
		||||
	unsigned int i, j;
 | 
			
		||||
 | 
			
		||||
	memcpy(nqpqx, q, sizeof(limb) * 5);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 32; ++i) {
 | 
			
		||||
		uint8_t byte = n[31 - i];
 | 
			
		||||
 | 
			
		||||
		for (j = 0; j < 8; ++j) {
 | 
			
		||||
			const limb bit = byte >> 7;
 | 
			
		||||
 | 
			
		||||
@ -404,7 +407,7 @@ static void cmult(limb *resultx, limb *resultz, const uint8_t *n, const limb *q)
 | 
			
		||||
 | 
			
		||||
static void crecip(felem out, const felem z)
 | 
			
		||||
{
 | 
			
		||||
	felem a,t0,b,c;
 | 
			
		||||
	felem a, t0, b, c;
 | 
			
		||||
 | 
			
		||||
	/* 2 */ fsquare_times(a, z, 1); // a = 2
 | 
			
		||||
	/* 8 */ fsquare_times(t0, a, 2);
 | 
			
		||||
@ -454,12 +457,14 @@ typedef int64_t limb;
 | 
			
		||||
 * significant first. The value of the field element is:
 | 
			
		||||
 *   x[0] + 2^26·x[1] + x^51·x[2] + 2^102·x[3] + ...
 | 
			
		||||
 *
 | 
			
		||||
 * i.e. the limbs are 26, 25, 26, 25, ... bits wide. */
 | 
			
		||||
 * i.e. the limbs are 26, 25, 26, 25, ... bits wide.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Sum two numbers: output += in */
 | 
			
		||||
static void fsum(limb *output, const limb *in)
 | 
			
		||||
{
 | 
			
		||||
	unsigned i;
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 10; i += 2) {
 | 
			
		||||
		output[0 + i] = output[0 + i] + in[0 + i];
 | 
			
		||||
		output[1 + i] = output[1 + i] + in[1 + i];
 | 
			
		||||
@ -467,10 +472,12 @@ static void fsum(limb *output, const limb *in)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Find the difference of two numbers: output = in - output
 | 
			
		||||
 * (note the order of the arguments!). */
 | 
			
		||||
 * (note the order of the arguments!).
 | 
			
		||||
 */
 | 
			
		||||
static void fdifference(limb *output, const limb *in)
 | 
			
		||||
{
 | 
			
		||||
	unsigned i;
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 10; ++i) {
 | 
			
		||||
		output[i] = in[i] - output[i];
 | 
			
		||||
	}
 | 
			
		||||
@ -479,7 +486,8 @@ static void fdifference(limb *output, const limb *in)
 | 
			
		||||
/* Multiply a number by a scalar: output = in * scalar */
 | 
			
		||||
static void fscalar_product(limb *output, const limb *in, const limb scalar)
 | 
			
		||||
{
 | 
			
		||||
	unsigned i;
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 10; ++i) {
 | 
			
		||||
		output[i] = in[i] * scalar;
 | 
			
		||||
	}
 | 
			
		||||
@ -490,7 +498,8 @@ static void fscalar_product(limb *output, const limb *in, const limb scalar)
 | 
			
		||||
 * output must be distinct to both inputs. The inputs are reduced coefficient
 | 
			
		||||
 * form, the output is not.
 | 
			
		||||
 *
 | 
			
		||||
 * output[x] <= 14 * the largest product of the input limbs. */
 | 
			
		||||
 * output[x] <= 14 * the largest product of the input limbs.
 | 
			
		||||
 */
 | 
			
		||||
static void fproduct(limb *output, const limb *in2, const limb *in)
 | 
			
		||||
{
 | 
			
		||||
	output[0] =       ((limb) ((int32_t) in2[0])) * ((int32_t) in[0]);
 | 
			
		||||
@ -598,13 +607,15 @@ static void fproduct(limb *output, const limb *in2, const limb *in)
 | 
			
		||||
/* Reduce a long form to a short form by taking the input mod 2^255 - 19.
 | 
			
		||||
 *
 | 
			
		||||
 * On entry: |output[i]| < 14*2^54
 | 
			
		||||
 * On exit: |output[0..8]| < 280*2^54 */
 | 
			
		||||
 * On exit: |output[0..8]| < 280*2^54
 | 
			
		||||
 */
 | 
			
		||||
static void freduce_degree(limb *output)
 | 
			
		||||
{
 | 
			
		||||
	/* Each of these shifts and adds ends up multiplying the value by 19.
 | 
			
		||||
	 *
 | 
			
		||||
	 * For output[0..8], the absolute entry value is < 14*2^54 and we add, at
 | 
			
		||||
	 * most, 19*14*2^54 thus, on exit, |output[0..8]| < 280*2^54. */
 | 
			
		||||
	 * most, 19*14*2^54 thus, on exit, |output[0..8]| < 280*2^54.
 | 
			
		||||
	 */
 | 
			
		||||
	output[8] += output[18] << 4;
 | 
			
		||||
	output[8] += output[18] << 1;
 | 
			
		||||
	output[8] += output[18];
 | 
			
		||||
@ -640,7 +651,8 @@ static void freduce_degree(limb *output)
 | 
			
		||||
 | 
			
		||||
/* return v / 2^26, using only shifts and adds.
 | 
			
		||||
 *
 | 
			
		||||
 * On entry: v can take any value. */
 | 
			
		||||
 * On entry: v can take any value.
 | 
			
		||||
 */
 | 
			
		||||
static inline limb div_by_2_26(const limb v)
 | 
			
		||||
{
 | 
			
		||||
	/* High word of v; no shift needed. */
 | 
			
		||||
@ -655,7 +667,8 @@ static inline limb div_by_2_26(const limb v)
 | 
			
		||||
 | 
			
		||||
/* return v / (2^25), using only shifts and adds.
 | 
			
		||||
 *
 | 
			
		||||
 * On entry: v can take any value. */
 | 
			
		||||
 * On entry: v can take any value.
 | 
			
		||||
 */
 | 
			
		||||
static inline limb div_by_2_25(const limb v)
 | 
			
		||||
{
 | 
			
		||||
	/* High word of v; no shift needed*/
 | 
			
		||||
@ -670,10 +683,11 @@ static inline limb div_by_2_25(const limb v)
 | 
			
		||||
 | 
			
		||||
/* Reduce all coefficients of the short form input so that |x| < 2^26.
 | 
			
		||||
 *
 | 
			
		||||
 * On entry: |output[i]| < 280*2^54 */
 | 
			
		||||
 * On entry: |output[i]| < 280*2^54
 | 
			
		||||
 */
 | 
			
		||||
static void freduce_coefficients(limb *output)
 | 
			
		||||
{
 | 
			
		||||
	unsigned i;
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
 | 
			
		||||
	output[10] = 0;
 | 
			
		||||
 | 
			
		||||
@ -682,7 +696,8 @@ static void freduce_coefficients(limb *output)
 | 
			
		||||
		/* The entry condition (that |output[i]| < 280*2^54) means that over is, at
 | 
			
		||||
		 * most, 280*2^28 in the first iteration of this loop. This is added to the
 | 
			
		||||
		 * next limb and we can approximate the resulting bound of that limb by
 | 
			
		||||
		 * 281*2^54. */
 | 
			
		||||
		 * 281*2^54.
 | 
			
		||||
		 */
 | 
			
		||||
		output[i] -= over << 26;
 | 
			
		||||
		output[i+1] += over;
 | 
			
		||||
 | 
			
		||||
@ -691,7 +706,8 @@ static void freduce_coefficients(limb *output)
 | 
			
		||||
		 * be approximated as 281*2^54.
 | 
			
		||||
		 *
 | 
			
		||||
		 * For subsequent iterations of the loop, 281*2^54 remains a conservative
 | 
			
		||||
		 * bound and no overflow occurs. */
 | 
			
		||||
		 * bound and no overflow occurs.
 | 
			
		||||
		 */
 | 
			
		||||
		over = div_by_2_25(output[i+1]);
 | 
			
		||||
		output[i+1] -= over << 25;
 | 
			
		||||
		output[i+2] += over;
 | 
			
		||||
@ -704,15 +720,18 @@ static void freduce_coefficients(limb *output)
 | 
			
		||||
	output[10] = 0;
 | 
			
		||||
 | 
			
		||||
	/* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19*281*2^29
 | 
			
		||||
	 * So |over| will be no more than 2^16. */
 | 
			
		||||
	 * So |over| will be no more than 2^16.
 | 
			
		||||
	 */
 | 
			
		||||
	{
 | 
			
		||||
		limb over = div_by_2_26(output[0]);
 | 
			
		||||
 | 
			
		||||
		output[0] -= over << 26;
 | 
			
		||||
		output[1] += over;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 2^16 < 2^26. The
 | 
			
		||||
	 * bound on |output[1]| is sufficient to meet our needs. */
 | 
			
		||||
	 * bound on |output[1]| is sufficient to meet our needs.
 | 
			
		||||
	 */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* A helpful wrapper around fproduct: output = in * in2.
 | 
			
		||||
@ -720,10 +739,12 @@ static void freduce_coefficients(limb *output)
 | 
			
		||||
 * On entry: |in[i]| < 2^27 and |in2[i]| < 2^27.
 | 
			
		||||
 *
 | 
			
		||||
 * output must be distinct to both inputs. The output is reduced degree
 | 
			
		||||
 * (indeed, one need only provide storage for 10 limbs) and |output[i]| < 2^26. */
 | 
			
		||||
 * (indeed, one need only provide storage for 10 limbs) and |output[i]| < 2^26.
 | 
			
		||||
 */
 | 
			
		||||
static void fmul(limb *output, const limb *in, const limb *in2)
 | 
			
		||||
{
 | 
			
		||||
	limb t[19];
 | 
			
		||||
 | 
			
		||||
	fproduct(t, in, in2);
 | 
			
		||||
	/* |t[i]| < 14*2^54 */
 | 
			
		||||
	freduce_degree(t);
 | 
			
		||||
@ -737,7 +758,8 @@ static void fmul(limb *output, const limb *in, const limb *in2)
 | 
			
		||||
 * output must be distinct from the input. The inputs are reduced coefficient
 | 
			
		||||
 * form, the output is not.
 | 
			
		||||
 *
 | 
			
		||||
 * output[x] <= 14 * the largest product of the input limbs. */
 | 
			
		||||
 * output[x] <= 14 * the largest product of the input limbs.
 | 
			
		||||
 */
 | 
			
		||||
static void fsquare_inner(limb *output, const limb *in)
 | 
			
		||||
{
 | 
			
		||||
	output[0] =       ((limb) ((int32_t) in[0])) * ((int32_t) in[0]);
 | 
			
		||||
@ -803,14 +825,17 @@ static void fsquare_inner(limb *output, const limb *in)
 | 
			
		||||
 * 2^27.
 | 
			
		||||
 *
 | 
			
		||||
 * On exit: The |output| argument is in reduced coefficients form (indeed, one
 | 
			
		||||
 * need only provide storage for 10 limbs) and |out[i]| < 2^26. */
 | 
			
		||||
 * need only provide storage for 10 limbs) and |out[i]| < 2^26.
 | 
			
		||||
 */
 | 
			
		||||
static void fsquare(limb *output, const limb *in)
 | 
			
		||||
{
 | 
			
		||||
	limb t[19];
 | 
			
		||||
 | 
			
		||||
	fsquare_inner(t, in);
 | 
			
		||||
	/* |t[i]| < 14*2^54 because the largest product of two limbs will be <
 | 
			
		||||
	 * 2^(27+27) and fsquare_inner adds together, at most, 14 of those
 | 
			
		||||
	 * products. */
 | 
			
		||||
	 * products.
 | 
			
		||||
	 */
 | 
			
		||||
	freduce_degree(t);
 | 
			
		||||
	freduce_coefficients(t);
 | 
			
		||||
	/* |t[i]| < 2^26 */
 | 
			
		||||
@ -820,7 +845,7 @@ static void fsquare(limb *output, const limb *in)
 | 
			
		||||
/* Take a little-endian, 32-byte number and expand it into polynomial form */
 | 
			
		||||
static void fexpand(limb *output, const uint8_t *input)
 | 
			
		||||
{
 | 
			
		||||
#define F(n,start,shift,mask) \
 | 
			
		||||
#define F(n, start, shift, mask) \
 | 
			
		||||
	output[n] = ((((limb) input[start + 0]) | \
 | 
			
		||||
		      ((limb) input[start + 1]) << 8 | \
 | 
			
		||||
		      ((limb) input[start + 2]) << 16 | \
 | 
			
		||||
@ -855,7 +880,8 @@ static int32_t int32_t_eq(int32_t a, int32_t b)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* int32_t_gte returns 0xffffffff if a >= b and zero otherwise, where a and b are
 | 
			
		||||
 * both non-negative. */
 | 
			
		||||
 * both non-negative.
 | 
			
		||||
 */
 | 
			
		||||
static int32_t int32_t_gte(int32_t a, int32_t b)
 | 
			
		||||
{
 | 
			
		||||
	a -= b;
 | 
			
		||||
@ -866,7 +892,8 @@ static int32_t int32_t_gte(int32_t a, int32_t b)
 | 
			
		||||
/* Take a fully reduced polynomial form number and contract it into a
 | 
			
		||||
 * little-endian, 32-byte array.
 | 
			
		||||
 *
 | 
			
		||||
 * On entry: |input_limbs[i]| < 2^26 */
 | 
			
		||||
 * On entry: |input_limbs[i]| < 2^26
 | 
			
		||||
 */
 | 
			
		||||
static void fcontract(uint8_t *output, limb *input_limbs)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
@ -883,31 +910,37 @@ static void fcontract(uint8_t *output, limb *input_limbs)
 | 
			
		||||
		for (i = 0; i < 9; ++i) {
 | 
			
		||||
			if ((i & 1) == 1) {
 | 
			
		||||
				/* This calculation is a time-invariant way to make input[i]
 | 
			
		||||
				 * non-negative by borrowing from the next-larger limb. */
 | 
			
		||||
				 * non-negative by borrowing from the next-larger limb.
 | 
			
		||||
				 */
 | 
			
		||||
				const int32_t mask = input[i] >> 31;
 | 
			
		||||
				const int32_t carry = -((input[i] & mask) >> 25);
 | 
			
		||||
 | 
			
		||||
				input[i] = input[i] + (carry << 25);
 | 
			
		||||
				input[i+1] = input[i+1] - carry;
 | 
			
		||||
			} else {
 | 
			
		||||
				const int32_t mask = input[i] >> 31;
 | 
			
		||||
				const int32_t carry = -((input[i] & mask) >> 26);
 | 
			
		||||
 | 
			
		||||
				input[i] = input[i] + (carry << 26);
 | 
			
		||||
				input[i+1] = input[i+1] - carry;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* There's no greater limb for input[9] to borrow from, but we can multiply
 | 
			
		||||
		 * by 19 and borrow from input[0], which is valid mod 2^255-19. */
 | 
			
		||||
		 * by 19 and borrow from input[0], which is valid mod 2^255-19.
 | 
			
		||||
		 */
 | 
			
		||||
		{
 | 
			
		||||
			const int32_t mask = input[9] >> 31;
 | 
			
		||||
			const int32_t carry = -((input[9] & mask) >> 25);
 | 
			
		||||
 | 
			
		||||
			input[9] = input[9] + (carry << 25);
 | 
			
		||||
			input[0] = input[0] - (carry * 19);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* After the first iteration, input[1..9] are non-negative and fit within
 | 
			
		||||
		 * 25 or 26 bits, depending on position. However, input[0] may be
 | 
			
		||||
		 * negative. */
 | 
			
		||||
		 * negative.
 | 
			
		||||
		 */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* The first borrow-propagation pass above ended with every limb
 | 
			
		||||
@ -923,20 +956,24 @@ static void fcontract(uint8_t *output, limb *input_limbs)
 | 
			
		||||
	{
 | 
			
		||||
		const int32_t mask = input[0] >> 31;
 | 
			
		||||
		const int32_t carry = -((input[0] & mask) >> 26);
 | 
			
		||||
 | 
			
		||||
		input[0] = input[0] + (carry << 26);
 | 
			
		||||
		input[1] = input[1] - carry;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* All input[i] are now non-negative. However, there might be values between
 | 
			
		||||
	 * 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */
 | 
			
		||||
	 * 2^25 and 2^26 in a limb which is, nominally, 25 bits wide.
 | 
			
		||||
	 */
 | 
			
		||||
	for (j = 0; j < 2; j++) {
 | 
			
		||||
		for (i = 0; i < 9; i++) {
 | 
			
		||||
			if ((i & 1) == 1) {
 | 
			
		||||
				const int32_t carry = input[i] >> 25;
 | 
			
		||||
 | 
			
		||||
				input[i] &= 0x1ffffff;
 | 
			
		||||
				input[i+1] += carry;
 | 
			
		||||
			} else {
 | 
			
		||||
				const int32_t carry = input[i] >> 26;
 | 
			
		||||
 | 
			
		||||
				input[i] &= 0x3ffffff;
 | 
			
		||||
				input[i+1] += carry;
 | 
			
		||||
			}
 | 
			
		||||
@ -944,6 +981,7 @@ static void fcontract(uint8_t *output, limb *input_limbs)
 | 
			
		||||
 | 
			
		||||
		{
 | 
			
		||||
			const int32_t carry = input[9] >> 25;
 | 
			
		||||
 | 
			
		||||
			input[9] &= 0x1ffffff;
 | 
			
		||||
			input[0] += 19*carry;
 | 
			
		||||
		}
 | 
			
		||||
@ -954,11 +992,13 @@ static void fcontract(uint8_t *output, limb *input_limbs)
 | 
			
		||||
	 * < 2^26 + 2*19, because the carry was, at most, two.
 | 
			
		||||
	 *
 | 
			
		||||
	 * If the second pass carried from input[9] again then input[0] is < 2*19 and
 | 
			
		||||
	 * the input[9] -> input[0] carry didn't push input[0] out of bounds. */
 | 
			
		||||
	 * the input[9] -> input[0] carry didn't push input[0] out of bounds.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	/* It still remains the case that input might be between 2^255-19 and 2^255.
 | 
			
		||||
	 * In this case, input[1..9] must take their maximum value and input[0] must
 | 
			
		||||
	 * be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */
 | 
			
		||||
	 * be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed.
 | 
			
		||||
	 */
 | 
			
		||||
	mask = int32_t_gte(input[0], 0x3ffffed);
 | 
			
		||||
	for (i = 1; i < 10; i++) {
 | 
			
		||||
		if ((i & 1) == 1) {
 | 
			
		||||
@ -969,7 +1009,8 @@ static void fcontract(uint8_t *output, limb *input_limbs)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus
 | 
			
		||||
	 * this conditionally subtracts 2^255-19. */
 | 
			
		||||
	 * this conditionally subtracts 2^255-19.
 | 
			
		||||
	 */
 | 
			
		||||
	input[0] -= mask & 0x3ffffed;
 | 
			
		||||
 | 
			
		||||
	for (i = 1; i < 10; i++) {
 | 
			
		||||
@ -995,16 +1036,16 @@ static void fcontract(uint8_t *output, limb *input_limbs)
 | 
			
		||||
	output[s+3]  = (input[i] >> 24) & 0xff;
 | 
			
		||||
	output[0] = 0;
 | 
			
		||||
	output[16] = 0;
 | 
			
		||||
	F(0,0);
 | 
			
		||||
	F(1,3);
 | 
			
		||||
	F(2,6);
 | 
			
		||||
	F(3,9);
 | 
			
		||||
	F(4,12);
 | 
			
		||||
	F(5,16);
 | 
			
		||||
	F(6,19);
 | 
			
		||||
	F(7,22);
 | 
			
		||||
	F(8,25);
 | 
			
		||||
	F(9,28);
 | 
			
		||||
	F(0, 0);
 | 
			
		||||
	F(1, 3);
 | 
			
		||||
	F(2, 6);
 | 
			
		||||
	F(3, 9);
 | 
			
		||||
	F(4, 12);
 | 
			
		||||
	F(5, 16);
 | 
			
		||||
	F(6, 19);
 | 
			
		||||
	F(7, 22);
 | 
			
		||||
	F(8, 25);
 | 
			
		||||
	F(9, 28);
 | 
			
		||||
#undef F
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1018,11 +1059,13 @@ static void fcontract(uint8_t *output, limb *input_limbs)
 | 
			
		||||
 *   qmqp: short form, preserved
 | 
			
		||||
 *
 | 
			
		||||
 * On entry and exit, the absolute value of the limbs of all inputs and outputs
 | 
			
		||||
 * are < 2^26. */
 | 
			
		||||
 * are < 2^26.
 | 
			
		||||
 */
 | 
			
		||||
static void fmonty(limb *x2, limb *z2,  /* output 2Q */
 | 
			
		||||
		   limb *x3, limb *z3,  /* output Q + Q' */
 | 
			
		||||
		   limb *x, limb *z,    /* input Q */
 | 
			
		||||
		   limb *xprime, limb *zprime,  /* input Q' */
 | 
			
		||||
 | 
			
		||||
		   const limb *qmqp /* input Q - Q' */)
 | 
			
		||||
{
 | 
			
		||||
	limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19],
 | 
			
		||||
@ -1042,7 +1085,8 @@ static void fmonty(limb *x2, limb *z2,  /* output 2Q */
 | 
			
		||||
	fproduct(xxprime, xprime, z);
 | 
			
		||||
	/* |xxprime[i]| < 14*2^54: the largest product of two limbs will be <
 | 
			
		||||
	 * 2^(27+27) and fproduct adds together, at most, 14 of those products.
 | 
			
		||||
	 * (Approximating that to 2^58 doesn't work out.) */
 | 
			
		||||
	 * (Approximating that to 2^58 doesn't work out.)
 | 
			
		||||
	 */
 | 
			
		||||
	fproduct(zzprime, x, zprime);
 | 
			
		||||
	/* |zzprime[i]| < 14*2^54 */
 | 
			
		||||
	freduce_degree(xxprime);
 | 
			
		||||
@ -1103,14 +1147,16 @@ static void fmonty(limb *x2, limb *z2,  /* output 2Q */
 | 
			
		||||
 * wrong results.  Also, the two limb arrays must be in reduced-coefficient,
 | 
			
		||||
 * reduced-degree form: the values in a[10..19] or b[10..19] aren't swapped,
 | 
			
		||||
 * and all all values in a[0..9],b[0..9] must have magnitude less than
 | 
			
		||||
 * INT32_MAX. */
 | 
			
		||||
 * INT32_MAX.
 | 
			
		||||
 */
 | 
			
		||||
static void swap_conditional(limb a[static 19], limb b[static 19], limb iswap)
 | 
			
		||||
{
 | 
			
		||||
	unsigned i;
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
	const int32_t swap = (int32_t) -iswap;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 10; ++i) {
 | 
			
		||||
		const int32_t x = swap & ( ((int32_t)a[i]) ^ ((int32_t)b[i]) );
 | 
			
		||||
		const int32_t x = swap & (((int32_t)a[i]) ^ ((int32_t)b[i]));
 | 
			
		||||
 | 
			
		||||
		a[i] = ((int32_t)a[i]) ^ x;
 | 
			
		||||
		b[i] = ((int32_t)b[i]) ^ x;
 | 
			
		||||
	}
 | 
			
		||||
@ -1120,7 +1166,8 @@ static void swap_conditional(limb a[static 19], limb b[static 19], limb iswap)
 | 
			
		||||
 *
 | 
			
		||||
 *   resultx/resultz: the x coordinate of the resulting curve point (short form)
 | 
			
		||||
 *   n: a little endian, 32-byte number
 | 
			
		||||
 *   q: a point of the curve (short form) */
 | 
			
		||||
 *   q: a point of the curve (short form)
 | 
			
		||||
 */
 | 
			
		||||
static void cmult(limb *resultx, limb *resultz, const uint8_t *n, const limb *q)
 | 
			
		||||
{
 | 
			
		||||
	limb a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0};
 | 
			
		||||
@ -1128,12 +1175,13 @@ static void cmult(limb *resultx, limb *resultz, const uint8_t *n, const limb *q)
 | 
			
		||||
	limb e[19] = {0}, f[19] = {1}, g[19] = {0}, h[19] = {1};
 | 
			
		||||
	limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h;
 | 
			
		||||
 | 
			
		||||
	unsigned i, j;
 | 
			
		||||
	unsigned int i, j;
 | 
			
		||||
 | 
			
		||||
	memcpy(nqpqx, q, sizeof(limb) * 10);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 32; ++i) {
 | 
			
		||||
		uint8_t byte = n[31 - i];
 | 
			
		||||
 | 
			
		||||
		for (j = 0; j < 8; ++j) {
 | 
			
		||||
			const limb bit = byte >> 7;
 | 
			
		||||
 | 
			
		||||
@ -1182,57 +1230,57 @@ static void crecip(limb *out, const limb *z)
 | 
			
		||||
	limb t1[10];
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	/* 2 */ fsquare(z2,z);
 | 
			
		||||
	/* 4 */ fsquare(t1,z2);
 | 
			
		||||
	/* 8 */ fsquare(t0,t1);
 | 
			
		||||
	/* 9 */ fmul(z9,t0,z);
 | 
			
		||||
	/* 11 */ fmul(z11,z9,z2);
 | 
			
		||||
	/* 22 */ fsquare(t0,z11);
 | 
			
		||||
	/* 2^5 - 2^0 = 31 */ fmul(z2_5_0,t0,z9);
 | 
			
		||||
	/* 2 */ fsquare(z2, z);
 | 
			
		||||
	/* 4 */ fsquare(t1, z2);
 | 
			
		||||
	/* 8 */ fsquare(t0, t1);
 | 
			
		||||
	/* 9 */ fmul(z9, t0, z);
 | 
			
		||||
	/* 11 */ fmul(z11, z9, z2);
 | 
			
		||||
	/* 22 */ fsquare(t0, z11);
 | 
			
		||||
	/* 2^5 - 2^0 = 31 */ fmul(z2_5_0, t0, z9);
 | 
			
		||||
 | 
			
		||||
	/* 2^6 - 2^1 */ fsquare(t0,z2_5_0);
 | 
			
		||||
	/* 2^7 - 2^2 */ fsquare(t1,t0);
 | 
			
		||||
	/* 2^8 - 2^3 */ fsquare(t0,t1);
 | 
			
		||||
	/* 2^9 - 2^4 */ fsquare(t1,t0);
 | 
			
		||||
	/* 2^10 - 2^5 */ fsquare(t0,t1);
 | 
			
		||||
	/* 2^10 - 2^0 */ fmul(z2_10_0,t0,z2_5_0);
 | 
			
		||||
	/* 2^6 - 2^1 */ fsquare(t0, z2_5_0);
 | 
			
		||||
	/* 2^7 - 2^2 */ fsquare(t1, t0);
 | 
			
		||||
	/* 2^8 - 2^3 */ fsquare(t0, t1);
 | 
			
		||||
	/* 2^9 - 2^4 */ fsquare(t1, t0);
 | 
			
		||||
	/* 2^10 - 2^5 */ fsquare(t0, t1);
 | 
			
		||||
	/* 2^10 - 2^0 */ fmul(z2_10_0, t0, z2_5_0);
 | 
			
		||||
 | 
			
		||||
	/* 2^11 - 2^1 */ fsquare(t0,z2_10_0);
 | 
			
		||||
	/* 2^12 - 2^2 */ fsquare(t1,t0);
 | 
			
		||||
	/* 2^20 - 2^10 */ for (i = 2; i < 10; i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
 | 
			
		||||
	/* 2^20 - 2^0 */ fmul(z2_20_0,t1,z2_10_0);
 | 
			
		||||
	/* 2^11 - 2^1 */ fsquare(t0, z2_10_0);
 | 
			
		||||
	/* 2^12 - 2^2 */ fsquare(t1, t0);
 | 
			
		||||
	/* 2^20 - 2^10 */ for (i = 2; i < 10; i += 2) { fsquare(t0, t1); fsquare(t1, t0); }
 | 
			
		||||
	/* 2^20 - 2^0 */ fmul(z2_20_0, t1, z2_10_0);
 | 
			
		||||
 | 
			
		||||
	/* 2^21 - 2^1 */ fsquare(t0,z2_20_0);
 | 
			
		||||
	/* 2^22 - 2^2 */ fsquare(t1,t0);
 | 
			
		||||
	/* 2^40 - 2^20 */ for (i = 2; i < 20; i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
 | 
			
		||||
	/* 2^40 - 2^0 */ fmul(t0,t1,z2_20_0);
 | 
			
		||||
	/* 2^21 - 2^1 */ fsquare(t0, z2_20_0);
 | 
			
		||||
	/* 2^22 - 2^2 */ fsquare(t1, t0);
 | 
			
		||||
	/* 2^40 - 2^20 */ for (i = 2; i < 20; i += 2) { fsquare(t0, t1); fsquare(t1, t0); }
 | 
			
		||||
	/* 2^40 - 2^0 */ fmul(t0, t1, z2_20_0);
 | 
			
		||||
 | 
			
		||||
	/* 2^41 - 2^1 */ fsquare(t1,t0);
 | 
			
		||||
	/* 2^42 - 2^2 */ fsquare(t0,t1);
 | 
			
		||||
	/* 2^50 - 2^10 */ for (i = 2; i < 10; i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
 | 
			
		||||
	/* 2^50 - 2^0 */ fmul(z2_50_0,t0,z2_10_0);
 | 
			
		||||
	/* 2^41 - 2^1 */ fsquare(t1, t0);
 | 
			
		||||
	/* 2^42 - 2^2 */ fsquare(t0, t1);
 | 
			
		||||
	/* 2^50 - 2^10 */ for (i = 2; i < 10; i += 2) { fsquare(t1, t0); fsquare(t0, t1); }
 | 
			
		||||
	/* 2^50 - 2^0 */ fmul(z2_50_0, t0, z2_10_0);
 | 
			
		||||
 | 
			
		||||
	/* 2^51 - 2^1 */ fsquare(t0,z2_50_0);
 | 
			
		||||
	/* 2^52 - 2^2 */ fsquare(t1,t0);
 | 
			
		||||
	/* 2^100 - 2^50 */ for (i = 2; i < 50; i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
 | 
			
		||||
	/* 2^100 - 2^0 */ fmul(z2_100_0,t1,z2_50_0);
 | 
			
		||||
	/* 2^51 - 2^1 */ fsquare(t0, z2_50_0);
 | 
			
		||||
	/* 2^52 - 2^2 */ fsquare(t1, t0);
 | 
			
		||||
	/* 2^100 - 2^50 */ for (i = 2; i < 50; i += 2) { fsquare(t0, t1); fsquare(t1, t0); }
 | 
			
		||||
	/* 2^100 - 2^0 */ fmul(z2_100_0, t1, z2_50_0);
 | 
			
		||||
 | 
			
		||||
	/* 2^101 - 2^1 */ fsquare(t1,z2_100_0);
 | 
			
		||||
	/* 2^102 - 2^2 */ fsquare(t0,t1);
 | 
			
		||||
	/* 2^200 - 2^100 */ for (i = 2; i < 100; i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
 | 
			
		||||
	/* 2^200 - 2^0 */ fmul(t1,t0,z2_100_0);
 | 
			
		||||
	/* 2^101 - 2^1 */ fsquare(t1, z2_100_0);
 | 
			
		||||
	/* 2^102 - 2^2 */ fsquare(t0, t1);
 | 
			
		||||
	/* 2^200 - 2^100 */ for (i = 2; i < 100; i += 2) { fsquare(t1, t0); fsquare(t0, t1); }
 | 
			
		||||
	/* 2^200 - 2^0 */ fmul(t1, t0, z2_100_0);
 | 
			
		||||
 | 
			
		||||
	/* 2^201 - 2^1 */ fsquare(t0,t1);
 | 
			
		||||
	/* 2^202 - 2^2 */ fsquare(t1,t0);
 | 
			
		||||
	/* 2^250 - 2^50 */ for (i = 2; i < 50; i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
 | 
			
		||||
	/* 2^250 - 2^0 */ fmul(t0,t1,z2_50_0);
 | 
			
		||||
	/* 2^201 - 2^1 */ fsquare(t0, t1);
 | 
			
		||||
	/* 2^202 - 2^2 */ fsquare(t1, t0);
 | 
			
		||||
	/* 2^250 - 2^50 */ for (i = 2; i < 50; i += 2) { fsquare(t0, t1); fsquare(t1, t0); }
 | 
			
		||||
	/* 2^250 - 2^0 */ fmul(t0, t1, z2_50_0);
 | 
			
		||||
 | 
			
		||||
	/* 2^251 - 2^1 */ fsquare(t1,t0);
 | 
			
		||||
	/* 2^252 - 2^2 */ fsquare(t0,t1);
 | 
			
		||||
	/* 2^253 - 2^3 */ fsquare(t1,t0);
 | 
			
		||||
	/* 2^254 - 2^4 */ fsquare(t0,t1);
 | 
			
		||||
	/* 2^255 - 2^5 */ fsquare(t1,t0);
 | 
			
		||||
	/* 2^255 - 21 */ fmul(out,t1,z11);
 | 
			
		||||
	/* 2^251 - 2^1 */ fsquare(t1, t0);
 | 
			
		||||
	/* 2^252 - 2^2 */ fsquare(t0, t1);
 | 
			
		||||
	/* 2^253 - 2^3 */ fsquare(t1, t0);
 | 
			
		||||
	/* 2^254 - 2^4 */ fsquare(t0, t1);
 | 
			
		||||
	/* 2^255 - 2^5 */ fsquare(t1, t0);
 | 
			
		||||
	/* 2^255 - 21 */ fmul(out, t1, z11);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void curve25519(uint8_t mypublic[static CURVE25519_POINT_SIZE], const uint8_t secret[static CURVE25519_POINT_SIZE], const uint8_t basepoint[static CURVE25519_POINT_SIZE])
 | 
			
		||||
@ -1254,5 +1302,6 @@ void curve25519(uint8_t mypublic[static CURVE25519_POINT_SIZE], const uint8_t se
 | 
			
		||||
void curve25519_generate_public(uint8_t pub[static CURVE25519_POINT_SIZE], const uint8_t secret[static CURVE25519_POINT_SIZE])
 | 
			
		||||
{
 | 
			
		||||
	static const uint8_t basepoint[CURVE25519_POINT_SIZE] = { 9 };
 | 
			
		||||
 | 
			
		||||
	curve25519(pub, secret, basepoint);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,7 @@
 | 
			
		||||
static inline void encode_base64(char dest[4], const uint8_t src[3])
 | 
			
		||||
{
 | 
			
		||||
	const uint8_t input[] = { (src[0] >> 2) & 63, ((src[0] << 4) | (src[1] >> 4)) & 63, ((src[1] << 2) | (src[2] >> 6)) & 63, src[2] & 63 };
 | 
			
		||||
 | 
			
		||||
	for (unsigned int i = 0; i < 4; ++i)
 | 
			
		||||
		dest[i] = input[i] + 'A'
 | 
			
		||||
			  + (((25 - input[i]) >> 8) & 6)
 | 
			
		||||
@ -21,6 +22,7 @@ static inline void encode_base64(char dest[4], const uint8_t src[3])
 | 
			
		||||
void key_to_base64(char base64[static WG_KEY_LEN_BASE64], const uint8_t key[static WG_KEY_LEN])
 | 
			
		||||
{
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < WG_KEY_LEN / 3; ++i)
 | 
			
		||||
		encode_base64(&base64[i * 4], &key[i * 3]);
 | 
			
		||||
	encode_base64(&base64[i * 4], (const uint8_t[]){ key[i * 3 + 0], key[i * 3 + 1], 0 });
 | 
			
		||||
@ -31,6 +33,7 @@ void key_to_base64(char base64[static WG_KEY_LEN_BASE64], const uint8_t key[stat
 | 
			
		||||
static inline int decode_base64(const char src[4])
 | 
			
		||||
{
 | 
			
		||||
	int val = 0;
 | 
			
		||||
 | 
			
		||||
	for (unsigned int i = 0; i < 4; ++i)
 | 
			
		||||
		val |= (-1
 | 
			
		||||
			    + ((((('A' - 1) - src[i]) & (src[i] - ('Z' + 1))) >> 8) & (src[i] - 64))
 | 
			
		||||
@ -46,6 +49,7 @@ bool key_from_base64(uint8_t key[static WG_KEY_LEN], const char *base64)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
	int val;
 | 
			
		||||
 | 
			
		||||
	if (strlen(base64) != WG_KEY_LEN_BASE64 - 1 || base64[WG_KEY_LEN_BASE64 - 2] != '=')
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
@ -68,6 +72,7 @@ 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])
 | 
			
		||||
{
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < WG_KEY_LEN; ++i) {
 | 
			
		||||
		hex[i * 2] = 87U + (key[i] >> 4) + ((((key[i] >> 4) - 10U) >> 8) & ~38U);
 | 
			
		||||
		hex[i * 2 + 1] = 87U + (key[i] & 0xf) + ((((key[i] & 0xf) - 10U) >> 8) & ~38U);
 | 
			
		||||
@ -103,6 +108,7 @@ 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])
 | 
			
		||||
{
 | 
			
		||||
	volatile uint8_t acc = 0;
 | 
			
		||||
 | 
			
		||||
	for (unsigned int i = 0; i < WG_KEY_LEN; ++i) {
 | 
			
		||||
		acc |= key[i];
 | 
			
		||||
		__asm__ ("" : "=r" (acc) : "0" (acc));
 | 
			
		||||
 | 
			
		||||
@ -337,6 +337,7 @@ static int userspace_get_device(struct wgdevice **out, const char *interface)
 | 
			
		||||
			dev->flags |= WGDEVICE_HAS_FWMARK;
 | 
			
		||||
		} else if (!strcmp(key, "public_key")) {
 | 
			
		||||
			struct wgpeer *new_peer = calloc(1, sizeof(struct wgpeer));
 | 
			
		||||
 | 
			
		||||
			if (!new_peer) {
 | 
			
		||||
				ret = -ENOMEM;
 | 
			
		||||
				goto err;
 | 
			
		||||
@ -396,6 +397,7 @@ static int userspace_get_device(struct wgdevice **out, const char *interface)
 | 
			
		||||
		} else if (peer && !strcmp(key, "allowed_ip")) {
 | 
			
		||||
			struct wgallowedip *new_allowedip;
 | 
			
		||||
			char *end, *cidr = strchr(value, '/');
 | 
			
		||||
 | 
			
		||||
			if (!cidr || strlen(cidr) <= 1)
 | 
			
		||||
				break;
 | 
			
		||||
			*cidr++ = '\0';
 | 
			
		||||
@ -450,6 +452,7 @@ err:
 | 
			
		||||
static int parse_linkinfo(const struct nlattr *attr, void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct inflatable_buffer *buffer = data;
 | 
			
		||||
 | 
			
		||||
	if (mnl_attr_get_type(attr) == IFLA_INFO_KIND && !strcmp("wireguard", mnl_attr_get_str(attr)))
 | 
			
		||||
		buffer->good = true;
 | 
			
		||||
	return MNL_CB_OK;
 | 
			
		||||
@ -458,6 +461,7 @@ static int parse_linkinfo(const struct nlattr *attr, void *data)
 | 
			
		||||
static int parse_infomsg(const struct nlattr *attr, void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct inflatable_buffer *buffer = data;
 | 
			
		||||
 | 
			
		||||
	if (mnl_attr_get_type(attr) == IFLA_LINKINFO)
 | 
			
		||||
		return mnl_attr_parse_nested(attr, parse_linkinfo, data);
 | 
			
		||||
	else if (mnl_attr_get_type(attr) == IFLA_IFNAME)
 | 
			
		||||
@ -565,6 +569,7 @@ again:
 | 
			
		||||
 | 
			
		||||
	if (!peer) {
 | 
			
		||||
		uint32_t flags = 0;
 | 
			
		||||
 | 
			
		||||
		if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
 | 
			
		||||
			mnl_attr_put(nlh, WGDEVICE_A_PRIVATE_KEY, sizeof(dev->private_key), dev->private_key);
 | 
			
		||||
		if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
 | 
			
		||||
@ -582,6 +587,7 @@ again:
 | 
			
		||||
	peers_nest = mnl_attr_nest_start(nlh, WGDEVICE_A_PEERS);
 | 
			
		||||
	for (i = 0, peer = peer ? peer : dev->first_peer; peer; peer = peer->next_peer) {
 | 
			
		||||
		uint32_t flags = 0;
 | 
			
		||||
 | 
			
		||||
		peer_nest = mnl_attr_nest_start_check(nlh, SOCKET_BUFFER_SIZE, i++);
 | 
			
		||||
		if (!peer_nest)
 | 
			
		||||
			goto toobig_peers;
 | 
			
		||||
@ -747,6 +753,7 @@ static int parse_peer(const struct nlattr *attr, void *data)
 | 
			
		||||
		break;
 | 
			
		||||
	case WGPEER_A_ENDPOINT: {
 | 
			
		||||
		struct sockaddr *addr;
 | 
			
		||||
 | 
			
		||||
		if (mnl_attr_get_payload_len(attr) < sizeof(*addr))
 | 
			
		||||
			break;
 | 
			
		||||
		addr = mnl_attr_get_payload(attr);
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
/* Copyright (C) 2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Original author: Jiri Pirko <jiri@mellanox.com> */
 | 
			
		||||
 * Original author: Jiri Pirko <jiri@mellanox.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
 | 
			
		||||
@ -113,7 +114,7 @@ int mnlg_socket_recv_run(struct mnlg_socket *nlg, mnl_cb_t data_cb, void *data)
 | 
			
		||||
		if (err <= 0)
 | 
			
		||||
			break;
 | 
			
		||||
		err = mnl_cb_run2(nlg->buf, err, nlg->seq, nlg->portid,
 | 
			
		||||
				  data_cb, data, mnlg_cb_array, sizeof(mnlg_cb_array) / sizeof(mnlg_cb_array[0]));
 | 
			
		||||
				  data_cb, data, mnlg_cb_array, MNL_ARRAY_SIZE(mnlg_cb_array));
 | 
			
		||||
	} while (err > 0);
 | 
			
		||||
 | 
			
		||||
	return err;
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
/* Copyright (C) 2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Original author: Jiri Pirko <jiri@mellanox.com> */
 | 
			
		||||
 * Original author: Jiri Pirko <jiri@mellanox.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef MNLG_H
 | 
			
		||||
#define MNLG_H
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										15
									
								
								src/show.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/show.c
									
									
									
									
									
								
							@ -23,6 +23,7 @@ static int peer_cmp(const void *first, const void *second)
 | 
			
		||||
{
 | 
			
		||||
	time_t diff;
 | 
			
		||||
	const struct wgpeer *a = *(const void **)first, *b = *(const void **)second;
 | 
			
		||||
 | 
			
		||||
	if (!a->last_handshake_time.tv_sec && !a->last_handshake_time.tv_usec && (b->last_handshake_time.tv_sec || b->last_handshake_time.tv_usec))
 | 
			
		||||
		return 1;
 | 
			
		||||
	if (!b->last_handshake_time.tv_sec && !b->last_handshake_time.tv_usec && (a->last_handshake_time.tv_sec || a->last_handshake_time.tv_usec))
 | 
			
		||||
@ -65,6 +66,7 @@ static void sort_peers(struct wgdevice *device)
 | 
			
		||||
static char *key(const uint8_t key[static WG_KEY_LEN])
 | 
			
		||||
{
 | 
			
		||||
	static char base64[WG_KEY_LEN_BASE64];
 | 
			
		||||
 | 
			
		||||
	if (key_is_zero(key))
 | 
			
		||||
		return "(none)";
 | 
			
		||||
	key_to_base64(base64, key);
 | 
			
		||||
@ -74,6 +76,7 @@ static char *key(const uint8_t key[static WG_KEY_LEN])
 | 
			
		||||
static char *masked_key(const uint8_t masked_key[static WG_KEY_LEN])
 | 
			
		||||
{
 | 
			
		||||
	const char *var = getenv("WG_HIDE_KEYS");
 | 
			
		||||
 | 
			
		||||
	if (var && !strcmp(var, "never"))
 | 
			
		||||
		return key(masked_key);
 | 
			
		||||
	return "(hidden)";
 | 
			
		||||
@ -82,6 +85,7 @@ static char *masked_key(const uint8_t masked_key[static WG_KEY_LEN])
 | 
			
		||||
static char *ip(const struct wgallowedip *ip)
 | 
			
		||||
{
 | 
			
		||||
	static char buf[INET6_ADDRSTRLEN + 1];
 | 
			
		||||
 | 
			
		||||
	memset(buf, 0, INET6_ADDRSTRLEN + 1);
 | 
			
		||||
	if (ip->family == AF_INET)
 | 
			
		||||
		inet_ntop(AF_INET, &ip->ip4, buf, INET6_ADDRSTRLEN);
 | 
			
		||||
@ -161,6 +165,7 @@ static char *ago(const struct timeval *t)
 | 
			
		||||
static char *every(uint16_t seconds)
 | 
			
		||||
{
 | 
			
		||||
	static char buf[1024] = "every ";
 | 
			
		||||
 | 
			
		||||
	pretty_time(buf + strlen("every "), sizeof(buf) - strlen("every ") - 1, seconds);
 | 
			
		||||
	return buf;
 | 
			
		||||
}
 | 
			
		||||
@ -170,7 +175,7 @@ static char *bytes(uint64_t b)
 | 
			
		||||
	static char buf[1024];
 | 
			
		||||
 | 
			
		||||
	if (b < 1024ULL)
 | 
			
		||||
		snprintf(buf, sizeof(buf) - 1, "%u " TERMINAL_FG_CYAN "B" TERMINAL_RESET, (unsigned)b);
 | 
			
		||||
		snprintf(buf, sizeof(buf) - 1, "%u " TERMINAL_FG_CYAN "B" TERMINAL_RESET, (unsigned int)b);
 | 
			
		||||
	else if (b < 1024ULL * 1024ULL)
 | 
			
		||||
		snprintf(buf, sizeof(buf) - 1, "%.2f " TERMINAL_FG_CYAN "KiB" TERMINAL_RESET, (double)b / 1024);
 | 
			
		||||
	else if (b < 1024ULL * 1024ULL * 1024ULL)
 | 
			
		||||
@ -183,7 +188,7 @@ static char *bytes(uint64_t b)
 | 
			
		||||
	return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *COMMAND_NAME = NULL;
 | 
			
		||||
static const char *COMMAND_NAME;
 | 
			
		||||
static void show_usage(void)
 | 
			
		||||
{
 | 
			
		||||
	fprintf(stderr, "Usage: %s %s { <interface> | all | interfaces } [public-key | private-key | listen-port | fwmark | peers | preshared-keys | endpoints | allowed-ips | latest-handshakes | transfer | persistent-keepalive | dump]\n", PROG_NAME, COMMAND_NAME);
 | 
			
		||||
@ -275,6 +280,7 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int
 | 
			
		||||
{
 | 
			
		||||
	struct wgpeer *peer;
 | 
			
		||||
	struct wgallowedip *allowedip;
 | 
			
		||||
 | 
			
		||||
	if (!strcmp(param, "public-key")) {
 | 
			
		||||
		if (with_interface)
 | 
			
		||||
			printf("%s\t", device->name);
 | 
			
		||||
@ -362,6 +368,7 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int
 | 
			
		||||
int show_main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
 | 
			
		||||
	COMMAND_NAME = argv[0];
 | 
			
		||||
 | 
			
		||||
	if (argc > 3) {
 | 
			
		||||
@ -371,6 +378,7 @@ int show_main(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
	if (argc == 1 || !strcmp(argv[1], "all")) {
 | 
			
		||||
		char *interfaces = ipc_list_devices(), *interface;
 | 
			
		||||
 | 
			
		||||
		if (!interfaces) {
 | 
			
		||||
			perror("Unable to get devices");
 | 
			
		||||
			return 1;
 | 
			
		||||
@ -378,6 +386,7 @@ int show_main(int argc, char *argv[])
 | 
			
		||||
		interface = interfaces;
 | 
			
		||||
		for (size_t len = 0; (len = strlen(interface)); interface += len + 1) {
 | 
			
		||||
			struct wgdevice *device = NULL;
 | 
			
		||||
 | 
			
		||||
			if (ipc_get_device(&device, interface) < 0) {
 | 
			
		||||
				perror("Unable to get device");
 | 
			
		||||
				continue;
 | 
			
		||||
@ -398,6 +407,7 @@ int show_main(int argc, char *argv[])
 | 
			
		||||
		free(interfaces);
 | 
			
		||||
	} else if (!strcmp(argv[1], "interfaces")) {
 | 
			
		||||
		char *interfaces, *interface;
 | 
			
		||||
 | 
			
		||||
		if (argc > 2) {
 | 
			
		||||
			show_usage();
 | 
			
		||||
			return 1;
 | 
			
		||||
@ -415,6 +425,7 @@ int show_main(int argc, char *argv[])
 | 
			
		||||
		show_usage();
 | 
			
		||||
	else {
 | 
			
		||||
		struct wgdevice *device = NULL;
 | 
			
		||||
 | 
			
		||||
		if (ipc_get_device(&device, argv[1]) < 0) {
 | 
			
		||||
			perror("Unable to get device");
 | 
			
		||||
			return 1;
 | 
			
		||||
 | 
			
		||||
@ -72,6 +72,7 @@ int showconf_main(int argc, char *argv[])
 | 
			
		||||
			char host[4096 + 1];
 | 
			
		||||
			char service[512 + 1];
 | 
			
		||||
			socklen_t addr_len = 0;
 | 
			
		||||
 | 
			
		||||
			if (peer->endpoint.addr.sa_family == AF_INET)
 | 
			
		||||
				addr_len = sizeof(struct sockaddr_in);
 | 
			
		||||
			else if (peer->endpoint.addr.sa_family == AF_INET6)
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,7 @@ static bool color_mode(FILE *file)
 | 
			
		||||
{
 | 
			
		||||
	static int mode = -1;
 | 
			
		||||
	const char *var;
 | 
			
		||||
 | 
			
		||||
	if (mode != -1)
 | 
			
		||||
		return mode;
 | 
			
		||||
	var = getenv("WG_COLOR_MODE");
 | 
			
		||||
@ -64,6 +65,7 @@ static void filter_ansi(FILE *file, const char *fmt, va_list args)
 | 
			
		||||
void terminal_printf(const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list args;
 | 
			
		||||
 | 
			
		||||
	va_start(args, fmt);
 | 
			
		||||
	filter_ansi(stdout, fmt, args);
 | 
			
		||||
	va_end(args);
 | 
			
		||||
@ -72,6 +74,7 @@ void terminal_printf(const char *fmt, ...)
 | 
			
		||||
void terminal_fprintf(FILE *file, const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list args;
 | 
			
		||||
 | 
			
		||||
	va_start(args, fmt);
 | 
			
		||||
	filter_ansi(file, fmt, args);
 | 
			
		||||
	va_end(args);
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user