Cleanup, optimization, multicast stuff, and it now compiles again.

This commit is contained in:
Adam Ierymenko 2019-09-11 15:34:55 -07:00
parent bccb86a401
commit d8dae365f6
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
13 changed files with 144 additions and 219 deletions

View file

@ -58,8 +58,8 @@ public:
} }
private: private:
inline AtomicCounter(const AtomicCounter &) {} ZT_ALWAYS_INLINE AtomicCounter(const AtomicCounter &) {}
inline const AtomicCounter &operator=(const AtomicCounter &) { return *this; } ZT_ALWAYS_INLINE const AtomicCounter &operator=(const AtomicCounter &) { return *this; }
#ifdef __GNUC__ #ifdef __GNUC__
int _v; int _v;

View file

@ -41,7 +41,7 @@ typedef uint8_t u8;
typedef int32_t s32; typedef int32_t s32;
typedef int64_t limb; typedef int64_t limb;
static inline void fsum(limb *output, const limb *in) { static ZT_ALWAYS_INLINE void fsum(limb *output, const limb *in) {
unsigned i; unsigned i;
for (i = 0; i < 10; i += 2) { for (i = 0; i < 10; i += 2) {
output[0+i] = output[0+i] + in[0+i]; output[0+i] = output[0+i] + in[0+i];
@ -49,21 +49,21 @@ static inline void fsum(limb *output, const limb *in) {
} }
} }
static inline void fdifference(limb *output, const limb *in) { static ZT_ALWAYS_INLINE void fdifference(limb *output, const limb *in) {
unsigned i; unsigned i;
for (i = 0; i < 10; ++i) { for (i = 0; i < 10; ++i) {
output[i] = in[i] - output[i]; output[i] = in[i] - output[i];
} }
} }
static inline void fscalar_product(limb *output, const limb *in, const limb scalar) { static ZT_ALWAYS_INLINE void fscalar_product(limb *output, const limb *in, const limb scalar) {
unsigned i; unsigned i;
for (i = 0; i < 10; ++i) { for (i = 0; i < 10; ++i) {
output[i] = in[i] * scalar; output[i] = in[i] * scalar;
} }
} }
static inline void fproduct(limb *output, const limb *in2, const limb *in) { static ZT_ALWAYS_INLINE void fproduct(limb *output, const limb *in2, const limb *in) {
output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]); output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]);
output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) + output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) +
((limb) ((s32) in2[1])) * ((s32) in[0]); ((limb) ((s32) in2[1])) * ((s32) in[0]);
@ -166,7 +166,7 @@ static inline void fproduct(limb *output, const limb *in2, const limb *in) {
output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]); output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]);
} }
static inline void freduce_degree(limb *output) { static ZT_ALWAYS_INLINE void freduce_degree(limb *output) {
output[8] += output[18] << 4; output[8] += output[18] << 4;
output[8] += output[18] << 1; output[8] += output[18] << 1;
output[8] += output[18]; output[8] += output[18];
@ -200,7 +200,7 @@ static inline void freduce_degree(limb *output) {
#error "This code only works on a two's complement system" #error "This code only works on a two's complement system"
#endif #endif
static inline limb div_by_2_26(const limb v) static ZT_ALWAYS_INLINE limb div_by_2_26(const limb v)
{ {
/* High word of v; no shift needed. */ /* High word of v; no shift needed. */
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
@ -212,7 +212,7 @@ static inline limb div_by_2_26(const limb v)
return (v + roundoff) >> 26; return (v + roundoff) >> 26;
} }
static inline limb div_by_2_25(const limb v) static ZT_ALWAYS_INLINE limb div_by_2_25(const limb v)
{ {
/* High word of v; no shift needed*/ /* High word of v; no shift needed*/
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
@ -224,7 +224,7 @@ static inline limb div_by_2_25(const limb v)
return (v + roundoff) >> 25; return (v + roundoff) >> 25;
} }
static inline void freduce_coefficients(limb *output) { static ZT_ALWAYS_INLINE void freduce_coefficients(limb *output) {
unsigned i; unsigned i;
output[10] = 0; output[10] = 0;
@ -277,7 +277,7 @@ static inline void fmul(limb *output, const limb *in, const limb *in2) {
memcpy(output, t, sizeof(limb) * 10); memcpy(output, t, sizeof(limb) * 10);
} }
static inline void fsquare_inner(limb *output, const limb *in) { static ZT_ALWAYS_INLINE void fsquare_inner(limb *output, const limb *in) {
output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]); output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]);
output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]); output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]);
output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) + output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) +
@ -335,7 +335,7 @@ static inline void fsquare_inner(limb *output, const limb *in) {
output[18] = 2 * ((limb) ((s32) in[9])) * ((s32) in[9]); output[18] = 2 * ((limb) ((s32) in[9])) * ((s32) in[9]);
} }
static void fsquare(limb *output, const limb *in) { static inline void fsquare(limb *output, const limb *in) {
limb t[19]; limb t[19];
fsquare_inner(t, in); fsquare_inner(t, in);
/* |t[i]| < 14*2^54 because the largest product of two limbs will be < /* |t[i]| < 14*2^54 because the largest product of two limbs will be <
@ -347,7 +347,7 @@ static void fsquare(limb *output, const limb *in) {
memcpy(output, t, sizeof(limb) * 10); memcpy(output, t, sizeof(limb) * 10);
} }
static inline void fexpand(limb *output, const u8 *input) { static ZT_ALWAYS_INLINE void fexpand(limb *output, const u8 *input) {
#define F(n,start,shift,mask) \ #define F(n,start,shift,mask) \
output[n] = ((((limb) input[start + 0]) | \ output[n] = ((((limb) input[start + 0]) | \
((limb) input[start + 1]) << 8 | \ ((limb) input[start + 1]) << 8 | \
@ -370,7 +370,7 @@ static inline void fexpand(limb *output, const u8 *input) {
#error "This code only works when >> does sign-extension on negative numbers" #error "This code only works when >> does sign-extension on negative numbers"
#endif #endif
static inline s32 s32_eq(s32 a, s32 b) { static ZT_ALWAYS_INLINE s32 s32_eq(s32 a, s32 b) {
a = ~(a ^ b); a = ~(a ^ b);
a &= a << 16; a &= a << 16;
a &= a << 8; a &= a << 8;
@ -380,7 +380,7 @@ static inline s32 s32_eq(s32 a, s32 b) {
return a >> 31; return a >> 31;
} }
static inline s32 s32_gte(s32 a, s32 b) { static ZT_ALWAYS_INLINE s32 s32_gte(s32 a, s32 b) {
a -= b; a -= b;
/* a >= 0 iff a >= b. */ /* a >= 0 iff a >= b. */
return ~(a >> 31); return ~(a >> 31);
@ -560,7 +560,7 @@ static inline void fmonty(limb *x2, limb *z2, /* output 2Q */
/* |z2|i| < 2^26 */ /* |z2|i| < 2^26 */
} }
static inline void swap_conditional(limb a[19], limb b[19], limb iswap) { static ZT_ALWAYS_INLINE void swap_conditional(limb a[19], limb b[19], limb iswap) {
unsigned i; unsigned i;
const s32 swap = (s32) -iswap; const s32 swap = (s32) -iswap;
@ -683,7 +683,7 @@ static inline void crecip(limb *out, const limb *z) {
/* 2^255 - 21 */ fmul(out,t1,z11); /* 2^255 - 21 */ fmul(out,t1,z11);
} }
static void crypto_scalarmult(u8 *mypublic, const u8 *secret, const u8 *basepoint) { static inline void crypto_scalarmult(u8 *mypublic, const u8 *secret, const u8 *basepoint) {
limb bp[10], x[10], z[11], zmone[10]; limb bp[10], x[10], z[11], zmone[10];
uint8_t e[32]; uint8_t e[32];
int i; int i;
@ -701,10 +701,7 @@ static void crypto_scalarmult(u8 *mypublic, const u8 *secret, const u8 *basepoin
} }
static const unsigned char base[32] = {9}; static const unsigned char base[32] = {9};
static inline void crypto_scalarmult_base(unsigned char *q,const unsigned char *n) static ZT_ALWAYS_INLINE void crypto_scalarmult_base(unsigned char *q,const unsigned char *n) { crypto_scalarmult(q,n,base); }
{
crypto_scalarmult(q,n,base);
}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -762,7 +759,7 @@ typedef struct
static inline void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y); static inline void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y);
static inline crypto_uint32 equal(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */ static ZT_ALWAYS_INLINE crypto_uint32 equal(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
{ {
crypto_uint32 x = a ^ b; /* 0: yes; 1..65535: no */ crypto_uint32 x = a ^ b; /* 0: yes; 1..65535: no */
x -= 1; /* 4294967295: yes; 0..65534: no */ x -= 1; /* 4294967295: yes; 0..65534: no */
@ -770,7 +767,7 @@ static inline crypto_uint32 equal(crypto_uint32 a,crypto_uint32 b) /* 16-bit inp
return x; return x;
} }
static inline crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */ static ZT_ALWAYS_INLINE crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
{ {
unsigned int x = a; unsigned int x = a;
x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */ x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */
@ -779,17 +776,10 @@ static inline crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs
return x; return x;
} }
static inline crypto_uint32 times19(crypto_uint32 a) static ZT_ALWAYS_INLINE crypto_uint32 times19(crypto_uint32 a) { return (a << 4) + (a << 1) + a; }
{ static ZT_ALWAYS_INLINE crypto_uint32 times38(crypto_uint32 a) { return (a << 5) + (a << 2) + (a << 1); }
return (a << 4) + (a << 1) + a;
}
static inline crypto_uint32 times38(crypto_uint32 a) static ZT_ALWAYS_INLINE void reduce_add_sub(fe25519 *r)
{
return (a << 5) + (a << 2) + (a << 1);
}
static inline void reduce_add_sub(fe25519 *r)
{ {
int i,rep; int i,rep;
for(rep=0;rep<4;rep++) for(rep=0;rep<4;rep++)
@ -807,7 +797,7 @@ static inline void reduce_add_sub(fe25519 *r)
} }
} }
static inline void reduce_mul(fe25519 *r) static ZT_ALWAYS_INLINE void reduce_mul(fe25519 *r)
{ {
int i,rep; int i,rep;
for(rep=0;rep<2;rep++) for(rep=0;rep<2;rep++)
@ -825,8 +815,7 @@ static inline void reduce_mul(fe25519 *r)
} }
} }
/* reduction modulo 2^255-19 */ static ZT_ALWAYS_INLINE void fe25519_freeze(fe25519 *r)
static inline void fe25519_freeze(fe25519 *r)
{ {
int i; int i;
crypto_uint32 mm = equal(r->v[31],127); crypto_uint32 mm = equal(r->v[31],127);
@ -842,15 +831,14 @@ static inline void fe25519_freeze(fe25519 *r)
r->v[0] -= mm&237; r->v[0] -= mm&237;
} }
static inline void fe25519_unpack(fe25519 *r, const unsigned char x[32]) static ZT_ALWAYS_INLINE void fe25519_unpack(fe25519 *r, const unsigned char x[32])
{ {
int i; int i;
for(i=0;i<32;i++) r->v[i] = x[i]; for(i=0;i<32;i++) r->v[i] = x[i];
r->v[31] &= 127; r->v[31] &= 127;
} }
/* Assumes input x being reduced below 2^255 */ static ZT_ALWAYS_INLINE void fe25519_pack(unsigned char r[32], const fe25519 *x)
static inline void fe25519_pack(unsigned char r[32], const fe25519 *x)
{ {
int i; int i;
fe25519 y = *x; fe25519 y = *x;
@ -871,7 +859,7 @@ static inline int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y)
return 1; return 1;
} }
static inline void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b) static ZT_ALWAYS_INLINE void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
{ {
int i; int i;
crypto_uint32 mask = b; crypto_uint32 mask = b;
@ -879,27 +867,27 @@ static inline void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
for(i=0;i<32;i++) r->v[i] ^= mask & (x->v[i] ^ r->v[i]); for(i=0;i<32;i++) r->v[i] ^= mask & (x->v[i] ^ r->v[i]);
} }
static inline unsigned char fe25519_getparity(const fe25519 *x) static ZT_ALWAYS_INLINE unsigned char fe25519_getparity(const fe25519 *x)
{ {
fe25519 t = *x; fe25519 t = *x;
fe25519_freeze(&t); fe25519_freeze(&t);
return t.v[0] & 1; return t.v[0] & 1;
} }
static inline void fe25519_setone(fe25519 *r) static ZT_ALWAYS_INLINE void fe25519_setone(fe25519 *r)
{ {
int i; int i;
r->v[0] = 1; r->v[0] = 1;
for(i=1;i<32;i++) r->v[i]=0; for(i=1;i<32;i++) r->v[i]=0;
} }
static inline void fe25519_setzero(fe25519 *r) static ZT_ALWAYS_INLINE void fe25519_setzero(fe25519 *r)
{ {
int i; int i;
for(i=0;i<32;i++) r->v[i]=0; for(i=0;i<32;i++) r->v[i]=0;
} }
static inline void fe25519_neg(fe25519 *r, const fe25519 *x) static ZT_ALWAYS_INLINE void fe25519_neg(fe25519 *r, const fe25519 *x)
{ {
fe25519 t; fe25519 t;
int i; int i;
@ -908,14 +896,14 @@ static inline void fe25519_neg(fe25519 *r, const fe25519 *x)
fe25519_sub(r, r, &t); fe25519_sub(r, r, &t);
} }
static inline void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y) static ZT_ALWAYS_INLINE void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y)
{ {
int i; int i;
for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i]; for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
reduce_add_sub(r); reduce_add_sub(r);
} }
static inline void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y) static ZT_ALWAYS_INLINE void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
{ {
int i; int i;
crypto_uint32 t[32]; crypto_uint32 t[32];
@ -926,7 +914,7 @@ static inline void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
reduce_add_sub(r); reduce_add_sub(r);
} }
static inline void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y) static ZT_ALWAYS_INLINE void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)
{ {
int i,j; int i,j;
crypto_uint32 t[63]; crypto_uint32 t[63];
@ -943,10 +931,7 @@ static inline void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)
reduce_mul(r); reduce_mul(r);
} }
static inline void fe25519_square(fe25519 *r, const fe25519 *x) static ZT_ALWAYS_INLINE void fe25519_square(fe25519 *r, const fe25519 *x) { fe25519_mul(r, x, x); }
{
fe25519_mul(r, x, x);
}
static inline void fe25519_invert(fe25519 *r, const fe25519 *x) static inline void fe25519_invert(fe25519 *r, const fe25519 *x)
{ {
@ -1072,7 +1057,7 @@ static inline void fe25519_pow2523(fe25519 *r, const fe25519 *x)
static const crypto_uint32 m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; static const crypto_uint32 m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
static const crypto_uint32 mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F}; static const crypto_uint32 mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F};
static inline crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */ static ZT_ALWAYS_INLINE crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
{ {
unsigned int x = a; unsigned int x = a;
x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */ x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */
@ -1080,8 +1065,7 @@ static inline crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs
return x; return x;
} }
/* Reduce coefficients of r before calling reduce_add_sub */ static ZT_ALWAYS_INLINE void reduce_add_sub(sc25519 *r)
static inline void reduce_add_sub(sc25519 *r)
{ {
crypto_uint32 pb = 0; crypto_uint32 pb = 0;
crypto_uint32 b; crypto_uint32 b;
@ -1101,7 +1085,6 @@ static inline void reduce_add_sub(sc25519 *r)
r->v[i] ^= mask & (r->v[i] ^ t[i]); r->v[i] ^= mask & (r->v[i] ^ t[i]);
} }
/* Reduce coefficients of x before calling barrett_reduce */
static inline void barrett_reduce(sc25519 *r, const crypto_uint32 x[64]) static inline void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
{ {
/* See HAC, Alg. 14.42 */ /* See HAC, Alg. 14.42 */
@ -1140,10 +1123,6 @@ static inline void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
pb = b; pb = b;
} }
/* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3
* If so: Handle it here!
*/
reduce_add_sub(r); reduce_add_sub(r);
reduce_add_sub(r); reduce_add_sub(r);
} }
@ -1165,7 +1144,7 @@ static inline void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
barrett_reduce(r, t); barrett_reduce(r, t);
} }
static inline void sc25519_to32bytes(unsigned char r[32], const sc25519 *x) static ZT_ALWAYS_INLINE void sc25519_to32bytes(unsigned char r[32], const sc25519 *x)
{ {
int i; int i;
for(i=0;i<32;i++) r[i] = x->v[i]; for(i=0;i<32;i++) r[i] = x->v[i];
@ -1202,7 +1181,7 @@ static inline void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
barrett_reduce(r, t); barrett_reduce(r, t);
} }
static inline void sc25519_window3(signed char r[85], const sc25519 *s) static ZT_ALWAYS_INLINE void sc25519_window3(signed char r[85], const sc25519 *s)
{ {
char carry; char carry;
int i; int i;
@ -1239,7 +1218,7 @@ static inline void sc25519_window3(signed char r[85], const sc25519 *s)
r[84] += carry; r[84] += carry;
} }
static inline void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2) static ZT_ALWAYS_INLINE void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2)
{ {
int i; int i;
for(i=0;i<31;i++) for(i=0;i<31;i++)
@ -2128,21 +2107,21 @@ static const ge25519_aff ge25519_base_multiples_affine[425] = {
{{0x69, 0x3e, 0x47, 0x97, 0x2c, 0xaf, 0x52, 0x7c, 0x78, 0x83, 0xad, 0x1b, 0x39, 0x82, 0x2f, 0x02, 0x6f, 0x47, 0xdb, 0x2a, 0xb0, 0xe1, 0x91, 0x99, 0x55, 0xb8, 0x99, 0x3a, 0xa0, 0x44, 0x11, 0x51}}} {{0x69, 0x3e, 0x47, 0x97, 0x2c, 0xaf, 0x52, 0x7c, 0x78, 0x83, 0xad, 0x1b, 0x39, 0x82, 0x2f, 0x02, 0x6f, 0x47, 0xdb, 0x2a, 0xb0, 0xe1, 0x91, 0x99, 0x55, 0xb8, 0x99, 0x3a, 0xa0, 0x44, 0x11, 0x51}}}
}; };
static inline void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p) static ZT_ALWAYS_INLINE void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p)
{ {
fe25519_mul(&r->x, &p->x, &p->t); fe25519_mul(&r->x, &p->x, &p->t);
fe25519_mul(&r->y, &p->y, &p->z); fe25519_mul(&r->y, &p->y, &p->z);
fe25519_mul(&r->z, &p->z, &p->t); fe25519_mul(&r->z, &p->z, &p->t);
} }
static inline void p1p1_to_p2_2(ge25519_p3 *r, const ge25519_p1p1 *p) static ZT_ALWAYS_INLINE void p1p1_to_p2_2(ge25519_p3 *r, const ge25519_p1p1 *p)
{ {
fe25519_mul(&r->x, &p->x, &p->t); fe25519_mul(&r->x, &p->x, &p->t);
fe25519_mul(&r->y, &p->y, &p->z); fe25519_mul(&r->y, &p->y, &p->z);
fe25519_mul(&r->z, &p->z, &p->t); fe25519_mul(&r->z, &p->z, &p->t);
} }
static inline void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p) static ZT_ALWAYS_INLINE void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p)
{ {
p1p1_to_p2_2(r, p); p1p1_to_p2_2(r, p);
fe25519_mul(&r->t, &p->x, &p->y); fe25519_mul(&r->t, &p->x, &p->y);
@ -2211,13 +2190,13 @@ static inline void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p)
} }
/* Constant-time version of: if(b) r = p */ /* Constant-time version of: if(b) r = p */
static inline void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b) static ZT_ALWAYS_INLINE void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b)
{ {
fe25519_cmov(&r->x, &p->x, b); fe25519_cmov(&r->x, &p->x, b);
fe25519_cmov(&r->y, &p->y, b); fe25519_cmov(&r->y, &p->y, b);
} }
static inline unsigned char equal(signed char b,signed char c) static ZT_ALWAYS_INLINE unsigned char equal(signed char b,signed char c)
{ {
unsigned char ub = b; unsigned char ub = b;
unsigned char uc = c; unsigned char uc = c;
@ -2228,7 +2207,7 @@ static inline unsigned char equal(signed char b,signed char c)
return (unsigned char)y; return (unsigned char)y;
} }
static inline unsigned char negative(signed char b) static ZT_ALWAYS_INLINE unsigned char negative(signed char b)
{ {
unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
x >>= 63; /* 1: yes; 0: no */ x >>= 63; /* 1: yes; 0: no */
@ -2377,7 +2356,7 @@ static inline void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s)
} }
} }
static inline void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen) static ZT_ALWAYS_INLINE void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen)
{ {
unsigned long long i; unsigned long long i;

View file

@ -32,7 +32,7 @@ public:
/** /**
* Generate a C25519 elliptic curve key pair * Generate a C25519 elliptic curve key pair
*/ */
static inline void generate(uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN]) static ZT_ALWAYS_INLINE void generate(uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN])
{ {
Utils::getSecureRandom(priv,ZT_C25519_PRIVATE_KEY_LEN); Utils::getSecureRandom(priv,ZT_C25519_PRIVATE_KEY_LEN);
_calcPubDH(pub,priv); _calcPubDH(pub,priv);
@ -53,7 +53,7 @@ public:
* @tparam F Type of 'cond' * @tparam F Type of 'cond'
*/ */
template<typename F> template<typename F>
static inline void generateSatisfying(F cond,uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN]) static ZT_ALWAYS_INLINE void generateSatisfying(F cond,uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN],uint8_t priv[ZT_C25519_PRIVATE_KEY_LEN])
{ {
Utils::getSecureRandom(priv,ZT_C25519_PRIVATE_KEY_LEN); Utils::getSecureRandom(priv,ZT_C25519_PRIVATE_KEY_LEN);
_calcPubED(pub,priv); // do Ed25519 key -- bytes 32-63 of pub and priv _calcPubED(pub,priv); // do Ed25519 key -- bytes 32-63 of pub and priv

View file

@ -61,7 +61,7 @@ class Capability : public Credential
public: public:
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_CAPABILITY; } static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_CAPABILITY; }
inline Capability() : ZT_ALWAYS_INLINE Capability() :
_nwid(0), _nwid(0),
_ts(0), _ts(0),
_id(0), _id(0),
@ -80,7 +80,7 @@ public:
* @param rules Network flow rules for this capability * @param rules Network flow rules for this capability
* @param ruleCount Number of flow rules * @param ruleCount Number of flow rules
*/ */
inline Capability(uint32_t id,uint64_t nwid,int64_t ts,unsigned int mccl,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount) : ZT_ALWAYS_INLINE Capability(uint32_t id,uint64_t nwid,int64_t ts,unsigned int mccl,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount) :
_nwid(nwid), _nwid(nwid),
_ts(ts), _ts(ts),
_id(id), _id(id),
@ -119,7 +119,7 @@ public:
/** /**
* @return Last 'to' address in chain of custody * @return Last 'to' address in chain of custody
*/ */
inline Address issuedTo() const ZT_ALWAYS_INLINE Address issuedTo() const
{ {
Address i2; Address i2;
for(unsigned int i=0;i<ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH;++i) { for(unsigned int i=0;i<ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH;++i) {
@ -165,7 +165,7 @@ public:
* *
* @param RR Runtime environment to provide for peer lookup, etc. * @param RR Runtime environment to provide for peer lookup, etc.
*/ */
inline Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); } ZT_ALWAYS_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); }
template<unsigned int C> template<unsigned int C>
static inline void serializeRules(Buffer<C> &b,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount) static inline void serializeRules(Buffer<C> &b,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount)

View file

@ -69,7 +69,7 @@ class CertificateOfMembership : public Credential
friend class Credential; friend class Credential;
public: public:
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COM; } static ZT_ALWAYS_INLINE Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COM; }
/** /**
* Reserved qualifier IDs * Reserved qualifier IDs
@ -101,7 +101,7 @@ public:
/** /**
* Create an empty certificate of membership * Create an empty certificate of membership
*/ */
inline CertificateOfMembership() : ZT_ALWAYS_INLINE CertificateOfMembership() :
_qualifierCount(0), _qualifierCount(0),
_signatureLength(0) {} _signatureLength(0) {}
@ -113,7 +113,7 @@ public:
* @param nwid Network ID * @param nwid Network ID
* @param issuedTo Certificate recipient * @param issuedTo Certificate recipient
*/ */
inline CertificateOfMembership(uint64_t timestamp,uint64_t timestampMaxDelta,uint64_t nwid,const Address &issuedTo) ZT_ALWAYS_INLINE CertificateOfMembership(uint64_t timestamp,uint64_t timestampMaxDelta,uint64_t nwid,const Address &issuedTo)
{ {
_qualifiers[0].id = COM_RESERVED_ID_TIMESTAMP; _qualifiers[0].id = COM_RESERVED_ID_TIMESTAMP;
_qualifiers[0].value = timestamp; _qualifiers[0].value = timestamp;
@ -135,10 +135,7 @@ public:
* @param startAt Position to start in buffer * @param startAt Position to start in buffer
*/ */
template<unsigned int C> template<unsigned int C>
inline CertificateOfMembership(const Buffer<C> &b,unsigned int startAt = 0) ZT_ALWAYS_INLINE CertificateOfMembership(const Buffer<C> &b,unsigned int startAt = 0) { deserialize(b,startAt); }
{
deserialize(b,startAt);
}
/** /**
* @return True if there's something here * @return True if there's something here
@ -214,7 +211,7 @@ public:
} }
} }
inline void setQualifier(ReservedId id,uint64_t value,uint64_t maxDelta) { setQualifier((uint64_t)id,value,maxDelta); } ZT_ALWAYS_INLINE void setQualifier(ReservedId id,uint64_t value,uint64_t maxDelta) { setQualifier((uint64_t)id,value,maxDelta); }
/** /**
* Compare two certificates for parameter agreement * Compare two certificates for parameter agreement
@ -297,17 +294,17 @@ public:
* @param RR Runtime environment for looking up peers * @param RR Runtime environment for looking up peers
* @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
*/ */
inline Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); } ZT_ALWAYS_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); }
/** /**
* @return True if signed * @return True if signed
*/ */
inline bool isSigned() const { return (_signedBy); } ZT_ALWAYS_INLINE bool isSigned() const { return (_signedBy); }
/** /**
* @return Address that signed this certificate or null address if none * @return Address that signed this certificate or null address if none
*/ */
inline const Address &signedBy() const { return _signedBy; } ZT_ALWAYS_INLINE const Address &signedBy() const { return _signedBy; }
template<unsigned int C> template<unsigned int C>
inline void serialize(Buffer<C> &b) const inline void serialize(Buffer<C> &b) const

View file

@ -46,7 +46,7 @@ class CertificateOfOwnership : public Credential
friend class Credential; friend class Credential;
public: public:
static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COO; } static ZT_ALWAYS_INLINE Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_COO; }
enum Thing enum Thing
{ {
@ -56,12 +56,12 @@ public:
THING_IPV6_ADDRESS = 3 THING_IPV6_ADDRESS = 3
}; };
inline CertificateOfOwnership() ZT_ALWAYS_INLINE CertificateOfOwnership()
{ {
memset(reinterpret_cast<void *>(this),0,sizeof(CertificateOfOwnership)); memset(reinterpret_cast<void *>(this),0,sizeof(CertificateOfOwnership));
} }
inline CertificateOfOwnership(const uint64_t nwid,const int64_t ts,const Address &issuedTo,const uint32_t id) ZT_ALWAYS_INLINE CertificateOfOwnership(const uint64_t nwid,const int64_t ts,const Address &issuedTo,const uint32_t id)
{ {
memset(reinterpret_cast<void *>(this),0,sizeof(CertificateOfOwnership)); memset(reinterpret_cast<void *>(this),0,sizeof(CertificateOfOwnership));
_networkId = nwid; _networkId = nwid;
@ -82,7 +82,7 @@ public:
ZT_ALWAYS_INLINE Thing thingType(const unsigned int i) const { return (Thing)_thingTypes[i]; } ZT_ALWAYS_INLINE Thing thingType(const unsigned int i) const { return (Thing)_thingTypes[i]; }
ZT_ALWAYS_INLINE const uint8_t *thingValue(const unsigned int i) const { return _thingValues[i]; } ZT_ALWAYS_INLINE const uint8_t *thingValue(const unsigned int i) const { return _thingValues[i]; }
inline bool owns(const InetAddress &ip) const ZT_ALWAYS_INLINE bool owns(const InetAddress &ip) const
{ {
if (ip.ss_family == AF_INET) if (ip.ss_family == AF_INET)
return this->_owns(THING_IPV4_ADDRESS,&(reinterpret_cast<const struct sockaddr_in *>(&ip)->sin_addr.s_addr),4); return this->_owns(THING_IPV4_ADDRESS,&(reinterpret_cast<const struct sockaddr_in *>(&ip)->sin_addr.s_addr),4);
@ -91,7 +91,7 @@ public:
return false; return false;
} }
inline bool owns(const MAC &mac) const ZT_ALWAYS_INLINE bool owns(const MAC &mac) const
{ {
uint8_t tmp[6]; uint8_t tmp[6];
mac.copyTo(tmp,6); mac.copyTo(tmp,6);

View file

@ -26,7 +26,7 @@
namespace ZeroTier { namespace ZeroTier {
template<typename CRED> template<typename CRED>
static inline Credential::VerifyResult _credVerify(const RuntimeEnvironment *const RR,void *tPtr,CRED credential) static ZT_ALWAYS_INLINE Credential::VerifyResult _credVerify(const RuntimeEnvironment *const RR,void *tPtr,CRED credential)
{ {
const Address signedBy(credential.signer()); const Address signedBy(credential.signer());
const uint64_t networkId = credential.networkId(); const uint64_t networkId = credential.networkId();

View file

@ -217,7 +217,7 @@ public:
* @tparam BC Buffer capacity (usually inferred) * @tparam BC Buffer capacity (usually inferred)
*/ */
template<unsigned int BC> template<unsigned int BC>
inline bool get(const char *key,Buffer<BC> &dest) const ZT_ALWAYS_INLINE bool get(const char *key,Buffer<BC> &dest) const
{ {
const int r = this->get(key,const_cast<char *>(reinterpret_cast<const char *>(dest.data())),BC); const int r = this->get(key,const_cast<char *>(reinterpret_cast<const char *>(dest.data())),BC);
if (r >= 0) { if (r >= 0) {
@ -236,7 +236,7 @@ public:
* @param dfl Default value if not found in dictionary * @param dfl Default value if not found in dictionary
* @return Boolean value of key or 'dfl' if not found * @return Boolean value of key or 'dfl' if not found
*/ */
bool getB(const char *key,bool dfl = false) const ZT_ALWAYS_INLINE bool getB(const char *key,bool dfl = false) const
{ {
char tmp[4]; char tmp[4];
if (this->get(key,tmp,sizeof(tmp)) >= 0) if (this->get(key,tmp,sizeof(tmp)) >= 0)
@ -251,7 +251,7 @@ public:
* @param dfl Default value or 0 if unspecified * @param dfl Default value or 0 if unspecified
* @return Decoded hex UInt value or 'dfl' if not found * @return Decoded hex UInt value or 'dfl' if not found
*/ */
inline uint64_t getUI(const char *key,uint64_t dfl = 0) const ZT_ALWAYS_INLINE uint64_t getUI(const char *key,uint64_t dfl = 0) const
{ {
char tmp[128]; char tmp[128];
if (this->get(key,tmp,sizeof(tmp)) >= 1) if (this->get(key,tmp,sizeof(tmp)) >= 1)
@ -266,7 +266,7 @@ public:
* @param dfl Default value or 0 if unspecified * @param dfl Default value or 0 if unspecified
* @return Decoded hex UInt value or 'dfl' if not found * @return Decoded hex UInt value or 'dfl' if not found
*/ */
inline int64_t getI(const char *key,int64_t dfl = 0) const ZT_ALWAYS_INLINE int64_t getI(const char *key,int64_t dfl = 0) const
{ {
char tmp[128]; char tmp[128];
if (this->get(key,tmp,sizeof(tmp)) >= 1) if (this->get(key,tmp,sizeof(tmp)) >= 1)
@ -366,7 +366,7 @@ public:
/** /**
* Add a boolean as a '1' or a '0' * Add a boolean as a '1' or a '0'
*/ */
inline bool add(const char *key,bool value) ZT_ALWAYS_INLINE bool add(const char *key,bool value)
{ {
return this->add(key,(value) ? "1" : "0",1); return this->add(key,(value) ? "1" : "0",1);
} }
@ -374,7 +374,7 @@ public:
/** /**
* Add a 64-bit integer (unsigned) as a hex value * Add a 64-bit integer (unsigned) as a hex value
*/ */
inline bool add(const char *key,uint64_t value) ZT_ALWAYS_INLINE bool add(const char *key,uint64_t value)
{ {
char tmp[32]; char tmp[32];
return this->add(key,Utils::hex(value,tmp),-1); return this->add(key,Utils::hex(value,tmp),-1);
@ -383,7 +383,7 @@ public:
/** /**
* Add a 64-bit integer (unsigned) as a hex value * Add a 64-bit integer (unsigned) as a hex value
*/ */
inline bool add(const char *key,int64_t value) ZT_ALWAYS_INLINE bool add(const char *key,int64_t value)
{ {
char tmp[32]; char tmp[32];
if (value >= 0) { if (value >= 0) {
@ -397,7 +397,7 @@ public:
/** /**
* Add a 64-bit integer (unsigned) as a hex value * Add a 64-bit integer (unsigned) as a hex value
*/ */
inline bool add(const char *key,const Address &a) ZT_ALWAYS_INLINE bool add(const char *key,const Address &a)
{ {
char tmp[32]; char tmp[32];
return this->add(key,Utils::hex(a.toInt(),tmp),-1); return this->add(key,Utils::hex(a.toInt(),tmp),-1);
@ -409,7 +409,7 @@ public:
* @tparam BC Buffer capacity (usually inferred) * @tparam BC Buffer capacity (usually inferred)
*/ */
template<unsigned int BC> template<unsigned int BC>
inline bool add(const char *key,const Buffer<BC> &value) ZT_ALWAYS_INLINE bool add(const char *key,const Buffer<BC> &value)
{ {
return this->add(key,(const char *)value.data(),(int)value.size()); return this->add(key,(const char *)value.data(),(int)value.size());
} }
@ -418,7 +418,7 @@ public:
* @param key Key to check * @param key Key to check
* @return True if key is present * @return True if key is present
*/ */
inline bool contains(const char *key) const ZT_ALWAYS_INLINE bool contains(const char *key) const
{ {
char tmp[2]; char tmp[2];
return (this->get(key,tmp,2) >= 0); return (this->get(key,tmp,2) >= 0);

View file

@ -45,7 +45,7 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,void *tPtr)
// Check for trusted paths or unencrypted HELLOs (HELLO is the only packet sent in the clear) // Check for trusted paths or unencrypted HELLOs (HELLO is the only packet sent in the clear)
const unsigned int c = cipher(); const unsigned int c = cipher();
bool trusted = false; bool trusted = false;
if (c == ZT_PROTO_CIPHER_SUITE__NO_CRYPTO_TRUSTED_PATH) { if (c == ZT_PROTO_CIPHER_SUITE__NONE) {
// If this is marked as a packet via a trusted path, check source address and path ID. // If this is marked as a packet via a trusted path, check source address and path ID.
// Obviously if no trusted paths are configured this always returns false and such // Obviously if no trusted paths are configured this always returns false and such
// packets are dropped on the floor. // packets are dropped on the floor.
@ -174,15 +174,11 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,void *tPtr,const Shar
network->setAccessDenied(); network->setAccessDenied();
} break; } break;
case Packet::ERROR_UNWANTED_MULTICAST: { case Packet::ERROR_MULTICAST_STFU: {
// Members of networks can use this error to indicate that they no longer // Members of networks can use this error to indicate that they no longer
// want to receive multicasts on a given channel. // want to receive multicasts on a given channel.
networkId = at<uint64_t>(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD); const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 8,6),6),at<uint32_t>(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 14));
const SharedPtr<Network> network(RR->node->network(networkId)); RR->mc->remove(at<uint64_t>(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD),mg,peer->address());
if ((network)&&(network->gate(tPtr,peer))) {
const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 8,6),6),at<uint32_t>(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 14));
RR->mc->remove(network->id(),mg,peer->address());
}
} break; } break;
default: break; default: break;
@ -431,6 +427,8 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedP
} break; } break;
case Packet::VERB_MULTICAST_GATHER: { case Packet::VERB_MULTICAST_GATHER: {
// TODO
/*
networkId = at<uint64_t>(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_NETWORK_ID); networkId = at<uint64_t>(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_NETWORK_ID);
const SharedPtr<Network> network(RR->node->network(networkId)); const SharedPtr<Network> network(RR->node->network(networkId));
if (network) { if (network) {
@ -439,32 +437,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,void *tPtr,const SharedP
if (((ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS + 6) + (count * 5)) <= size()) if (((ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS + 6) + (count * 5)) <= size())
RR->mc->addMultiple(tPtr,RR->node->now(),networkId,mg,field(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS + 6,count * 5),count,at<uint32_t>(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS)); RR->mc->addMultiple(tPtr,RR->node->now(),networkId,mg,field(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS + 6,count * 5),count,at<uint32_t>(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS));
} }
} break; */
case Packet::VERB_MULTICAST_FRAME: {
const unsigned int flags = (*this)[ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_FLAGS];
networkId = at<uint64_t>(ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_NETWORK_ID);
const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_MAC,6),6),at<uint32_t>(ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_ADI));
const SharedPtr<Network> network(RR->node->network(networkId));
if (network) {
unsigned int offset = 0;
if ((flags & 0x01) != 0) { // deprecated but still used by older peers
CertificateOfMembership com;
offset += com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_COM_AND_GATHER_RESULTS);
if (com)
network->addCredential(tPtr,com);
}
if ((flags & 0x02) != 0) {
// OK(MULTICAST_FRAME) includes implicit gather results
offset += ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_COM_AND_GATHER_RESULTS;
unsigned int totalKnown = at<uint32_t>(offset); offset += 4;
unsigned int count = at<uint16_t>(offset); offset += 2;
RR->mc->addMultiple(tPtr,RR->node->now(),networkId,mg,field(offset,count * 5),count,totalKnown);
}
}
} break; } break;
default: break; default: break;
@ -660,6 +633,8 @@ bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,void *tPtr,c
// Packet contains a series of 18-byte network,MAC,ADI tuples // Packet contains a series of 18-byte network,MAC,ADI tuples
for(unsigned int ptr=ZT_PACKET_IDX_PAYLOAD;(ptr+18)<=size();ptr+=18) { for(unsigned int ptr=ZT_PACKET_IDX_PAYLOAD;(ptr+18)<=size();ptr+=18) {
// TODO
/*
const uint64_t nwid = at<uint64_t>(ptr); const uint64_t nwid = at<uint64_t>(ptr);
if (nwid != lastNwid) { if (nwid != lastNwid) {
lastNwid = nwid; lastNwid = nwid;
@ -671,6 +646,7 @@ bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,void *tPtr,c
} }
if (authorized) if (authorized)
RR->mc->add(tPtr,now,nwid,MulticastGroup(MAC(field(ptr + 8,6),6),at<uint32_t>(ptr + 14)),peer->address()); RR->mc->add(tPtr,now,nwid,MulticastGroup(MAC(field(ptr + 8,6),6),at<uint32_t>(ptr + 14)),peer->address());
*/
} }
peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP,0); peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP,0);
@ -831,6 +807,8 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,void *tPtr
const int64_t now = RR->node->now(); const int64_t now = RR->node->now();
if (gatherLimit) { if (gatherLimit) {
// TODO
/*
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK); Packet outp(peer->address(),RR->identity.address(),Packet::VERB_OK);
outp.append((unsigned char)Packet::VERB_MULTICAST_GATHER); outp.append((unsigned char)Packet::VERB_MULTICAST_GATHER);
outp.append(packetId()); outp.append(packetId());
@ -842,6 +820,7 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment *RR,void *tPtr
outp.armor(peer->key(),true); outp.armor(peer->key(),true);
_path->send(RR,tPtr,outp.data(),outp.size(),now); _path->send(RR,tPtr,outp.data(),outp.size(),now);
} }
*/
} }
peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP,nwid); peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_MULTICAST_GATHER,0,Packet::VERB_NOP,nwid);
@ -956,6 +935,7 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr,
} }
if (gatherLimit) { // DEPRECATED but still supported if (gatherLimit) { // DEPRECATED but still supported
/*
Packet outp(source(),RR->identity.address(),Packet::VERB_OK); Packet outp(source(),RR->identity.address(),Packet::VERB_OK);
outp.append((unsigned char)Packet::VERB_MULTICAST_FRAME); outp.append((unsigned char)Packet::VERB_MULTICAST_FRAME);
outp.append(packetId()); outp.append(packetId());
@ -967,6 +947,7 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,void *tPtr,
outp.armor(peer->key(),true); outp.armor(peer->key(),true);
_path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now()); _path->send(RR,tPtr,outp.data(),outp.size(),RR->node->now());
} }
*/
} }
peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,nwid); peer->received(tPtr,_path,hops(),packetId(),payloadLength(),Packet::VERB_MULTICAST_FRAME,0,Packet::VERB_NOP,nwid);

View file

@ -49,7 +49,7 @@ class Network;
class IncomingPacket : public Packet class IncomingPacket : public Packet
{ {
public: public:
inline IncomingPacket() : ZT_ALWAYS_INLINE IncomingPacket() :
Packet(), Packet(),
_receiveTime(0) _receiveTime(0)
{ {
@ -64,7 +64,7 @@ public:
* @param now Current time * @param now Current time
* @throws std::out_of_range Range error processing packet * @throws std::out_of_range Range error processing packet
*/ */
inline IncomingPacket(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now) : ZT_ALWAYS_INLINE IncomingPacket(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now) :
Packet(data,len), Packet(data,len),
_receiveTime(now), _receiveTime(now),
_path(path) _path(path)
@ -80,7 +80,7 @@ public:
* @param now Current time * @param now Current time
* @throws std::out_of_range Range error processing packet * @throws std::out_of_range Range error processing packet
*/ */
inline void init(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now) ZT_ALWAYS_INLINE void init(const void *data,unsigned int len,const SharedPtr<Path> &path,int64_t now)
{ {
copyFrom(data,len); copyFrom(data,len);
_receiveTime = now; _receiveTime = now;
@ -105,7 +105,7 @@ public:
/** /**
* @return Time of packet receipt / start of decode * @return Time of packet receipt / start of decode
*/ */
inline uint64_t receiveTime() const { return _receiveTime; } ZT_ALWAYS_INLINE uint64_t receiveTime() const { return _receiveTime; }
private: private:
// These are called internally to handle packet contents once it has // These are called internally to handle packet contents once it has

View file

@ -49,28 +49,7 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre
const SharedPtr<Path> path(RR->topology->getPath(localSocket,fromAddr)); const SharedPtr<Path> path(RR->topology->getPath(localSocket,fromAddr));
path->received(now); path->received(now);
if (len == 13) { if (len > ZT_PROTO_MIN_FRAGMENT_LENGTH) { // SECURITY: min length check is important since we do some C-style stuff below!
/* LEGACY: before VERB_PUSH_DIRECT_PATHS, peers used broadcast
* announcements on the LAN to solve the 'same network problem.' We
* no longer send these, but we'll listen for them for a while to
* locate peers with versions <1.0.4. */
const Address beaconAddr(reinterpret_cast<const char *>(data) + 8,5);
if (beaconAddr == RR->identity.address())
return;
if (!RR->node->shouldUsePathForZeroTierTraffic(tPtr,beaconAddr,localSocket,fromAddr))
return;
const SharedPtr<Peer> peer(RR->topology->get(beaconAddr));
if (peer) { // we'll only respond to beacons from known peers
if ((now - _lastBeaconResponse) >= 2500) { // limit rate of responses
_lastBeaconResponse = now;
Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NOP);
outp.armor(peer->key(),true);
path->send(RR,tPtr,outp.data(),outp.size(),now);
}
}
} else if (len > ZT_PROTO_MIN_FRAGMENT_LENGTH) { // SECURITY: min length check is important since we do some C-style stuff below!
if (reinterpret_cast<const uint8_t *>(data)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] == ZT_PACKET_FRAGMENT_INDICATOR) { if (reinterpret_cast<const uint8_t *>(data)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] == ZT_PACKET_FRAGMENT_INDICATOR) {
// Handle fragment ---------------------------------------------------- // Handle fragment ----------------------------------------------------
@ -372,6 +351,8 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
return; return;
} }
// TODO
/*
RR->mc->send( RR->mc->send(
tPtr, tPtr,
RR->node->now(), RR->node->now(),
@ -382,6 +363,7 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
etherType, etherType,
data, data,
len); len);
*/
} else if (to == network->mac()) { } else if (to == network->mac()) {
// Destination is this node, so just reinject it // Destination is this node, so just reinject it
RR->node->putFrame(tPtr,network->id(),network->userPtr(),from,to,etherType,vlanId,data,len); RR->node->putFrame(tPtr,network->id(),network->userPtr(),from,to,etherType,vlanId,data,len);
@ -434,7 +416,11 @@ void Switch::onLocalEthernet(void *tPtr,const SharedPtr<Network> &network,const
/* Create an array of up to ZT_MAX_BRIDGE_SPAM recipients for this bridged frame. */ /* Create an array of up to ZT_MAX_BRIDGE_SPAM recipients for this bridged frame. */
bridges[0] = network->findBridgeTo(to); bridges[0] = network->findBridgeTo(to);
std::vector<Address> activeBridges(network->config().activeBridges()); std::vector<Address> activeBridges;
for(unsigned int i=0;i<network->config().specialistCount;++i) {
if ((network->config().specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE) != 0)
activeBridges.push_back(network->config().specialists[i]);
}
if ((bridges[0])&&(bridges[0] != RR->identity.address())&&(network->config().permitsBridging(bridges[0]))) { if ((bridges[0])&&(bridges[0] != RR->identity.address())&&(network->config().permitsBridging(bridges[0]))) {
/* We have a known bridge route for this MAC, send it there. */ /* We have a known bridge route for this MAC, send it there. */
++numBridges; ++numBridges;

View file

@ -193,13 +193,13 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
} }
uint8_t h[48]; uint8_t h[48];
for(unsigned int k=0;k<4;++k) { for(unsigned int k=0;k<4;++k) { // treat random state like a 256-bit counter; endian-ness is irrelevant since we just want random
if (++randomState[k] != 0) if (++randomState[k] != 0)
break; break;
} }
HMACSHA384((const uint8_t *)randomState,randomBuf,sizeof(randomBuf),h); HMACSHA384((const uint8_t *)randomState,randomBuf,sizeof(randomBuf),h); // compute HMAC on random buffer using state as secret key
AES c(h); AES c(h);
c.ctr(h + 32,randomBuf,sizeof(randomBuf),randomBuf); c.ctr(h + 32,randomBuf,sizeof(randomBuf),randomBuf); // encrypt random buffer with AES-CTR using HMAC result as key
} }
((uint8_t *)buf)[i] = randomBuf[randomPtr++]; ((uint8_t *)buf)[i] = randomBuf[randomPtr++];

View file

@ -68,29 +68,35 @@ public:
*/ */
static char *decimal(unsigned long n,char s[24]); static char *decimal(unsigned long n,char s[24]);
static inline char *hex(uint64_t i,char s[17]) /**
* Convert an unsigned integer into hex
*
* @param i Any unsigned integer
* @param s Buffer to receive hex, must be at least (2*sizeof(i))+1 in size or overflow will occur.
* @return Pointer to s containing hex string with trailing zero byte
*/
template<typename I>
static ZT_ALWAYS_INLINE char *hex(I i,char *s)
{ {
s[0] = HEXCHARS[(i >> 60) & 0xf]; char *const r = s;
s[1] = HEXCHARS[(i >> 56) & 0xf]; for(unsigned int i=0,b=(sizeof(i)*8);i<sizeof(i);++i) {
s[2] = HEXCHARS[(i >> 52) & 0xf]; b -= 4;
s[3] = HEXCHARS[(i >> 48) & 0xf]; *(s++) = HEXCHARS[(i >> b) & 0xf];
s[4] = HEXCHARS[(i >> 44) & 0xf]; b -= 4;
s[5] = HEXCHARS[(i >> 40) & 0xf]; *(s++) = HEXCHARS[(i >> b) & 0xf];
s[6] = HEXCHARS[(i >> 36) & 0xf]; }
s[7] = HEXCHARS[(i >> 32) & 0xf]; *s = (char)0;
s[8] = HEXCHARS[(i >> 28) & 0xf]; return r;
s[9] = HEXCHARS[(i >> 24) & 0xf];
s[10] = HEXCHARS[(i >> 20) & 0xf];
s[11] = HEXCHARS[(i >> 16) & 0xf];
s[12] = HEXCHARS[(i >> 12) & 0xf];
s[13] = HEXCHARS[(i >> 8) & 0xf];
s[14] = HEXCHARS[(i >> 4) & 0xf];
s[15] = HEXCHARS[i & 0xf];
s[16] = (char)0;
return s;
} }
static inline char *hex10(uint64_t i,char s[11]) /**
* Convert the least significant 40 bits of a uint64_t to hex
*
* @param i Unsigned 64-bit int
* @param s Buffer of size [11] to receive 10 hex characters
* @return Pointer to buffer
*/
static ZT_ALWAYS_INLINE char *hex10(uint64_t i,char s[11])
{ {
s[0] = HEXCHARS[(i >> 36) & 0xf]; s[0] = HEXCHARS[(i >> 36) & 0xf];
s[1] = HEXCHARS[(i >> 32) & 0xf]; s[1] = HEXCHARS[(i >> 32) & 0xf];
@ -106,39 +112,15 @@ public:
return s; return s;
} }
static inline char *hex(uint32_t i,char s[9]) /**
{ * Convert a byte array into hex
s[0] = HEXCHARS[(i >> 28) & 0xf]; *
s[1] = HEXCHARS[(i >> 24) & 0xf]; * @param d Bytes
s[2] = HEXCHARS[(i >> 20) & 0xf]; * @param l Length of bytes
s[3] = HEXCHARS[(i >> 16) & 0xf]; * @param s String buffer, must be at least (l*2)+1 in size or overflow will occur
s[4] = HEXCHARS[(i >> 12) & 0xf]; * @return Pointer to filled string buffer
s[5] = HEXCHARS[(i >> 8) & 0xf]; */
s[6] = HEXCHARS[(i >> 4) & 0xf]; static ZT_ALWAYS_INLINE char *hex(const void *d,unsigned int l,char *s)
s[7] = HEXCHARS[i & 0xf];
s[8] = (char)0;
return s;
}
static inline char *hex(uint16_t i,char s[5])
{
s[0] = HEXCHARS[(i >> 12) & 0xf];
s[1] = HEXCHARS[(i >> 8) & 0xf];
s[2] = HEXCHARS[(i >> 4) & 0xf];
s[3] = HEXCHARS[i & 0xf];
s[4] = (char)0;
return s;
}
static inline char *hex(uint8_t i,char s[3])
{
s[0] = HEXCHARS[(i >> 4) & 0xf];
s[1] = HEXCHARS[i & 0xf];
s[2] = (char)0;
return s;
}
static inline char *hex(const void *d,unsigned int l,char *s)
{ {
char *const save = s; char *const save = s;
for(unsigned int i=0;i<l;++i) { for(unsigned int i=0;i<l;++i) {