diff --git a/src/config.c b/src/config.c index 8fe3e1c..5b25b46 100644 --- a/src/config.c +++ b/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; diff --git a/src/curve25519.c b/src/curve25519.c index 29a4531..71bd095 100644 --- a/src/curve25519.c +++ b/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); } diff --git a/src/encoding.c b/src/encoding.c index c407b57..da5ccef 100644 --- a/src/encoding.c +++ b/src/encoding.c @@ -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)); diff --git a/src/ipc.c b/src/ipc.c index 66a5720..d67ada2 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -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); diff --git a/src/mnlg.c b/src/mnlg.c index ff70bdc..9135651 100644 --- a/src/mnlg.c +++ b/src/mnlg.c @@ -1,6 +1,7 @@ /* Copyright (C) 2017 Jason A. Donenfeld . All Rights Reserved. * - * Original author: Jiri Pirko */ + * Original author: Jiri Pirko + */ #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; diff --git a/src/mnlg.h b/src/mnlg.h index 46c53ba..b27a18c 100644 --- a/src/mnlg.h +++ b/src/mnlg.h @@ -1,6 +1,7 @@ /* Copyright (C) 2017 Jason A. Donenfeld . All Rights Reserved. * - * Original author: Jiri Pirko */ + * Original author: Jiri Pirko + */ #ifndef MNLG_H #define MNLG_H diff --git a/src/show.c b/src/show.c index d315ee8..05777b1 100644 --- a/src/show.c +++ b/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 { | 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; diff --git a/src/showconf.c b/src/showconf.c index adc3789..2843910 100644 --- a/src/showconf.c +++ b/src/showconf.c @@ -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) diff --git a/src/terminal.c b/src/terminal.c index e5b5edb..703c75f 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -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); diff --git a/src/wg.c b/src/wg.c index c340d66..9834271 100644 --- a/src/wg.c +++ b/src/wg.c @@ -35,6 +35,7 @@ static void show_usage(FILE *file) int main(int argc, char *argv[]) { char *tmp = NULL; + PROG_NAME = argv[0]; if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "help"))) {