From 61349d3d273aa23935b0c413c5885005db2669db Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 29 Nov 2013 05:33:12 +0100 Subject: Compile with -std=c99 and restructure some code to ensure there is no invalid aliasing (hopefully) --- src/CMakeLists.txt | 2 +- src/cpuid.h | 2 +- .../cipher/aes128_ctr/openssl/aes128_ctr_openssl.c | 6 +- .../cipher/blowfish_ctr/builtin/blowfish_ctr.c | 33 ++++++--- src/crypto/mac/ghash/builtin/ghash_builtin.c | 26 ++++---- .../mac/ghash/pclmulqdq/ghash_pclmulqdq_impl.c | 21 +++--- src/fastd.c | 6 +- src/fastd.h | 19 +++--- src/hkdf_sha256.c | 17 +++-- src/methods/composed_gmac/composed_gmac.c | 2 +- src/methods/generic_gcm/generic_gcm.c | 2 +- src/methods/generic_gmac/generic_gmac.c | 2 +- src/peer.c | 36 +++++----- src/peer.h | 12 ++-- src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c | 6 +- src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h | 6 +- src/protocols/ec25519_fhmqvc/handshake.c | 78 +++++++++++----------- src/protocols/ec25519_fhmqvc/state.c | 2 +- src/protocols/ec25519_fhmqvc/util.c | 10 +-- src/receive.c | 24 ++++--- src/send.c | 13 ++-- src/socket.c | 2 +- src/tuntap.c | 8 +-- 23 files changed, 183 insertions(+), 152 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4bcbb65..628465b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ set_directory_properties(PROPERTIES COMPILE_DEFINITIONS _GNU_SOURCE) -set(FASTD_CFLAGS "-Wall -pthread ${UECC_CFLAGS_OTHER} ${NACL_CFLAGS_OTHER} ${OPENSSL_CRYPTO_CFLAGS_OTHER}") +set(FASTD_CFLAGS "-pthread -std=c99 ${UECC_CFLAGS_OTHER} ${NACL_CFLAGS_OTHER} ${OPENSSL_CRYPTO_CFLAGS_OTHER} -Wall") include_directories(${FASTD_SOURCE_DIR} ${FASTD_BINARY_DIR}/src) link_directories(${UECC_LIBRARY_DIRS} ${NACL_LIBRARY_DIRS} ${OPENSSL_CRYPTO_LIBRARY_DIRS}) diff --git a/src/cpuid.h b/src/cpuid.h index 0558c09..eab9110 100644 --- a/src/cpuid.h +++ b/src/cpuid.h @@ -41,7 +41,7 @@ static inline uint64_t fastd_cpuid(void) { uint32_t edx, ecx; - asm("cpuid" : "=d"(edx), "=c"(ecx) : "a"((uint32_t)1)); + __asm__("cpuid" : "=d"(edx), "=c"(ecx) : "a"((uint32_t)1)); return ((uint64_t)ecx) << 32 | edx; } diff --git a/src/crypto/cipher/aes128_ctr/openssl/aes128_ctr_openssl.c b/src/crypto/cipher/aes128_ctr/openssl/aes128_ctr_openssl.c index 37ed95c..6917333 100644 --- a/src/crypto/cipher/aes128_ctr/openssl/aes128_ctr_openssl.c +++ b/src/crypto/cipher/aes128_ctr/openssl/aes128_ctr_openssl.c @@ -41,7 +41,7 @@ static fastd_cipher_state_t* aes128_ctr_init_state(fastd_context_t *ctx UNUSED, fastd_cipher_state_t *state = malloc(sizeof(fastd_cipher_state_t)); state->aes = EVP_CIPHER_CTX_new(); - EVP_EncryptInit(state->aes, EVP_aes_128_ctr(), (const void*)key, NULL); + EVP_EncryptInit(state->aes, EVP_aes_128_ctr(), (const unsigned char*)key, NULL); return state; } @@ -52,10 +52,10 @@ static bool aes128_ctr_crypt(fastd_context_t *ctx UNUSED, const fastd_cipher_sta if (!EVP_EncryptInit(state->aes, NULL, NULL, iv)) return false; - if (!EVP_EncryptUpdate(state->aes, (void*)out, &clen, (const void*)in, len)) + if (!EVP_EncryptUpdate(state->aes, (unsigned char*)out, &clen, (const unsigned char*)in, len)) return false; - if (!EVP_EncryptFinal(state->aes, ((void*)out) + clen, &clen2)) + if (!EVP_EncryptFinal(state->aes, ((unsigned char*)out) + clen, &clen2)) return false; if ((size_t)(clen+clen2) != len) diff --git a/src/crypto/cipher/blowfish_ctr/builtin/blowfish_ctr.c b/src/crypto/cipher/blowfish_ctr/builtin/blowfish_ctr.c index 8c18203..70c4d35 100644 --- a/src/crypto/cipher/blowfish_ctr/builtin/blowfish_ctr.c +++ b/src/crypto/cipher/blowfish_ctr/builtin/blowfish_ctr.c @@ -26,6 +26,13 @@ #include "../../../../crypto.h" + +typedef union bf_block { + fastd_block128_t b; + uint32_t u32[4]; +} bf_block_t; + + static const uint32_t Sdefault[4][256] = { { 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, @@ -240,24 +247,30 @@ static fastd_cipher_state_t* blowfish_ctr_init_state(fastd_context_t *ctx UNUSED } static bool blowfish_ctr_crypt(fastd_context_t *ctx UNUSED, const fastd_cipher_state_t *state, fastd_block128_t *out, const fastd_block128_t *in, size_t len, const uint8_t *iv) { + register bf_block_t block; register uint32_t ctr[2]; - register uint32_t block[2]; - - uint32_t *out4 = (uint32_t*)out; - uint32_t *in4 = (uint32_t*)in; ctr[0] = (iv[0] << 24)|(iv[1] << 16)|(iv[2] << 8)|(iv[3]); ctr[1] = (iv[4] << 24)|(iv[5] << 16)|(iv[6] << 8)|(iv[7]); size_t i; - for(i = 0; i < len; i += 8) { - block[0] = ctr[0]; - block[1] = ctr[1]; - BF_ENCRYPT(state, block[0], block[1]); + for(i = 0; i < len; i += 16) { + block.u32[0] = ctr[0]; + block.u32[1] = ctr[1]; + BF_ENCRYPT(state, block.u32[0], block.u32[1]); + ctr[1]++; - *(out4++) = *(in4++) ^ htonl(block[0]); - *(out4++) = *(in4++) ^ htonl(block[1]); + block.u32[2] = ctr[0]; + block.u32[3] = ctr[1]; + BF_ENCRYPT(state, block.u32[2], block.u32[3]); ctr[1]++; + + block.u32[0] = htonl(block.u32[0]); + block.u32[1] = htonl(block.u32[1]); + block.u32[2] = htonl(block.u32[2]); + block.u32[3] = htonl(block.u32[3]); + + xor(out++, *(in++), block.b); } return true; diff --git a/src/crypto/mac/ghash/builtin/ghash_builtin.c b/src/crypto/mac/ghash/builtin/ghash_builtin.c index cc81e74..511e844 100644 --- a/src/crypto/mac/ghash/builtin/ghash_builtin.c +++ b/src/crypto/mac/ghash/builtin/ghash_builtin.c @@ -35,13 +35,13 @@ struct fastd_mac_state { static const fastd_block128_t r = { .b = {0xe1} }; -static inline uint8_t shr(fastd_block128_t *out, const fastd_block128_t *in, int n) { +static inline uint8_t shr(fastd_block128_t *out, fastd_block128_t in, int n) { size_t i; uint8_t c = 0; for (i = 0; i < sizeof(fastd_block128_t); i++) { - uint8_t c2 = in->b[i] << (8-n); - out->b[i] = (in->b[i] >> n) | c; + uint8_t c2 = in.b[i] << (8-n); + out->b[i] = (in.b[i] >> n) | c; c = c2; } @@ -53,8 +53,8 @@ static inline void mulH_a(fastd_block128_t *x, const fastd_mac_state_t *cstate) int i; for (i = 0; i < 16; i++) { - xor_a(&out, &cstate->H[2*i][x->b[i]>>4]); - xor_a(&out, &cstate->H[2*i+1][x->b[i]&0xf]); + xor_a(&out, cstate->H[2*i][x->b[i]>>4]); + xor_a(&out, cstate->H[2*i+1][x->b[i]&0xf]); } *x = out; @@ -76,11 +76,11 @@ static fastd_mac_state_t* ghash_init_state(fastd_context_t *ctx UNUSED, const fa int i; for (i = 1; i < 4; i++) { - uint8_t carry = shr(&Hbase[i], &Hbase[i-1], 1); + uint8_t carry = shr(&Hbase[i], Hbase[i-1], 1); if (carry) - xor_a(&Hbase[i], &r); + xor_a(&Hbase[i], r); - shr(&Rbase[i], &Rbase[i-1], 1); + shr(&Rbase[i], Rbase[i-1], 1); } fastd_block128_t R[16]; @@ -91,8 +91,8 @@ static fastd_mac_state_t* ghash_init_state(fastd_context_t *ctx UNUSED, const fa int j; for (j = 0; j < 4; j++) { if (i & (8 >> j)) { - xor_a(&state->H[0][i], &Hbase[j]); - xor_a(&R[i], &Rbase[j]); + xor_a(&state->H[0][i], Hbase[j]); + xor_a(&R[i], Rbase[j]); } } } @@ -101,8 +101,8 @@ static fastd_mac_state_t* ghash_init_state(fastd_context_t *ctx UNUSED, const fa int j; for (j = 0; j < 16; j++) { - uint8_t carry = shr(&state->H[i][j], &state->H[i-1][j], 4); - xor_a(&state->H[i][j], &R[carry]); + uint8_t carry = shr(&state->H[i][j], state->H[i-1][j], 4); + xor_a(&state->H[i][j], R[carry]); } } @@ -114,7 +114,7 @@ static bool ghash_hash(fastd_context_t *ctx UNUSED, const fastd_mac_state_t *sta size_t i; for (i = 0; i < n_blocks; i++) { - xor_a(out, &in[i]); + xor_a(out, in[i]); mulH_a(out, state); } diff --git a/src/crypto/mac/ghash/pclmulqdq/ghash_pclmulqdq_impl.c b/src/crypto/mac/ghash/pclmulqdq/ghash_pclmulqdq_impl.c index 0abff8c..375cf91 100644 --- a/src/crypto/mac/ghash/pclmulqdq/ghash_pclmulqdq_impl.c +++ b/src/crypto/mac/ghash/pclmulqdq/ghash_pclmulqdq_impl.c @@ -30,10 +30,10 @@ #include -typedef union _vecblock { +typedef union vecblock { __m128i v; fastd_block128_t b; -} vecblock; +} vecblock_t; static inline __m128i shl(__m128i v, int a) { __m128i tmpl = _mm_slli_epi64(v, a); @@ -61,7 +61,7 @@ static inline __m128i byteswap(__m128i v) { fastd_mac_state_t* fastd_ghash_pclmulqdq_init_state(fastd_context_t *ctx UNUSED, const fastd_mac_context_t *mctx UNUSED, const uint8_t *key) { fastd_mac_state_t *state = malloc(sizeof(fastd_mac_state_t)); - vecblock h; + vecblock_t h; memcpy(&h, key, sizeof(__m128i)); h.v = byteswap(h.v); @@ -124,19 +124,18 @@ static __m128i gmul(__m128i v, __m128i h) { bool fastd_ghash_pclmulqdq_hash(fastd_context_t *ctx UNUSED, const fastd_mac_state_t *state, fastd_block128_t *out, const fastd_block128_t *in, size_t n_blocks) { - const __m128i *inv = (const __m128i*)in; - - __m128i h = ((vecblock*)&state->H)->v; - __m128i v = _mm_setzero_si128(); + vecblock_t h = {.b = state->H}; + vecblock_t v = {.v = _mm_setzero_si128()}; size_t i; for (i = 0; i < n_blocks; i++) { - __m128i b = inv[i]; - v = _mm_xor_si128(v, byteswap(b)); - v = gmul(v, h); + __m128i b = ((vecblock_t)in[i]).v; + v.v = _mm_xor_si128(v.v, byteswap(b)); + v.v = gmul(v.v, h.v); } - ((vecblock*)out)->v = byteswap(v); + v.v = byteswap(v.v); + *out = v.b; return true; } diff --git a/src/fastd.c b/src/fastd.c index 28ff207..03ffc52 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -211,7 +211,7 @@ static void close_sockets(fastd_context_t *ctx) { } static inline void handle_forward(fastd_context_t *ctx, fastd_peer_t *source_peer, fastd_buffer_t buffer) { - const fastd_eth_addr_t *dest_addr = fastd_get_dest_address(ctx, buffer); + fastd_eth_addr_t dest_addr = fastd_get_dest_address(ctx, buffer); if (fastd_eth_addr_is_unicast(dest_addr)) { fastd_peer_t *dest_peer = fastd_peer_find_by_eth_addr(ctx, dest_addr); @@ -236,7 +236,7 @@ void fastd_handle_receive(fastd_context_t *ctx, fastd_peer_t *peer, fastd_buffer return; } - const fastd_eth_addr_t *src_addr = fastd_get_source_address(ctx, buffer); + fastd_eth_addr_t src_addr = fastd_get_source_address(ctx, buffer); if (fastd_eth_addr_is_unicast(src_addr)) fastd_peer_eth_addr_add(ctx, peer, src_addr); @@ -462,7 +462,7 @@ static inline bool handle_tun_tap(fastd_context_t *ctx, fastd_buffer_t buffer) { return true; } - const fastd_eth_addr_t *dest_addr = fastd_get_dest_address(ctx, buffer); + fastd_eth_addr_t dest_addr = fastd_get_dest_address(ctx, buffer); if (!fastd_eth_addr_is_unicast(dest_addr)) return false; diff --git a/src/fastd.h b/src/fastd.h index 237af4b..8ea5027 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -380,9 +380,10 @@ static inline int fastd_rand(fastd_context_t *ctx, int min, int max) { #define exit_errno(ctx, message) exit_error(ctx, "%s: %s", message, strerror(errno)) -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) +#define container_of(ptr, type, member) ({ \ + const __typeof__(((type *)0)->member) *_mptr = (ptr); \ + (type*)((char*)_mptr - offsetof(type, member)); \ + }) #define array_size(array) (sizeof(array)/sizeof((array)[0])) @@ -506,16 +507,16 @@ static inline size_t min_size_t(size_t a, size_t b) { static inline void secure_memzero(void *s, size_t n) { memset(s, 0, n); - asm volatile("" : : "m"(s)); + __asm__ volatile("" : : "m"(s)); } -static inline void xor(fastd_block128_t *x, const fastd_block128_t *a, const fastd_block128_t *b) { - x->qw[0] = a->qw[0] ^ b->qw[0]; - x->qw[1] = a->qw[1] ^ b->qw[1]; +static inline void xor(fastd_block128_t *x, fastd_block128_t a, fastd_block128_t b) { + x->qw[0] = a.qw[0] ^ b.qw[0]; + x->qw[1] = a.qw[1] ^ b.qw[1]; } -static inline void xor_a(fastd_block128_t *x, const fastd_block128_t *a) { - xor(x, x, a); +static inline void xor_a(fastd_block128_t *x, fastd_block128_t a) { + xor(x, *x, a); } static inline bool fastd_true(void) { diff --git a/src/hkdf_sha256.c b/src/hkdf_sha256.c index 8d04ae0..26568f9 100644 --- a/src/hkdf_sha256.c +++ b/src/hkdf_sha256.c @@ -34,20 +34,19 @@ void fastd_hkdf_sha256_expand(fastd_sha256_t *out, size_t blocks, fastd_sha256_t return; size_t len = sizeof(fastd_sha256_t) + infolen + 1; + uint32_t buf[(len+3)/4]; - uint8_t buf[len] __attribute__((aligned(4))); + memset(buf, 0, FASTD_SHA256_HASH_BYTES); + memcpy(buf+FASTD_SHA256_HASH_WORDS, info, infolen); + ((uint8_t*)buf)[len-1] = 0x01; - memset(buf, 0, sizeof(fastd_sha256_t)); - memcpy(buf+sizeof(fastd_sha256_t), info, infolen); - buf[len-1] = 0x01; - - fastd_hmacsha256(out, prk->w, (uint32_t*)(buf+sizeof(fastd_sha256_t)), infolen + 1); + fastd_hmacsha256(out, prk->w, buf+FASTD_SHA256_HASH_WORDS, infolen + 1); while (--blocks) { - memcpy(buf, out, sizeof(fastd_sha256_t)); + memcpy(buf, out, FASTD_SHA256_HASH_BYTES); out++; - buf[len-1]++; + ((uint8_t*)buf)[len-1]++; - fastd_hmacsha256(out, prk->w, (uint32_t*)buf, len); + fastd_hmacsha256(out, prk->w, buf, len); } } diff --git a/src/methods/composed_gmac/composed_gmac.c b/src/methods/composed_gmac/composed_gmac.c index 75533d2..cb0d5d6 100644 --- a/src/methods/composed_gmac/composed_gmac.c +++ b/src/methods/composed_gmac/composed_gmac.c @@ -238,7 +238,7 @@ static bool method_encrypt(fastd_context_t *ctx, fastd_peer_t *peer UNUSED, fast return false; } - xor_a(&outblocks[0], &sig); + xor_a(&outblocks[0], sig); fastd_buffer_free(in); diff --git a/src/methods/generic_gcm/generic_gcm.c b/src/methods/generic_gcm/generic_gcm.c index a92ad1e..9ce8522 100644 --- a/src/methods/generic_gcm/generic_gcm.c +++ b/src/methods/generic_gcm/generic_gcm.c @@ -204,7 +204,7 @@ static bool method_encrypt(fastd_context_t *ctx, fastd_peer_t *peer UNUSED, fast return false; } - xor_a(&outblocks[0], &sig); + xor_a(&outblocks[0], sig); fastd_buffer_free(in); diff --git a/src/methods/generic_gmac/generic_gmac.c b/src/methods/generic_gmac/generic_gmac.c index 86c02f7..d42b2c4 100644 --- a/src/methods/generic_gmac/generic_gmac.c +++ b/src/methods/generic_gmac/generic_gmac.c @@ -207,7 +207,7 @@ static bool method_encrypt(fastd_context_t *ctx, fastd_peer_t *peer UNUSED, fast return false; } - xor_a(&outblocks[0], &sig); + xor_a(&outblocks[0], sig); fastd_buffer_free(in); diff --git a/src/peer.c b/src/peer.c index a84c116..5934d82 100644 --- a/src/peer.c +++ b/src/peer.c @@ -598,19 +598,24 @@ void fastd_peer_set_established(fastd_context_t *ctx, fastd_peer_t *peer) { pr_info(ctx, "connection with %P established.", peer); } -const fastd_eth_addr_t* fastd_get_source_address(const fastd_context_t *ctx, fastd_buffer_t buffer) { +fastd_eth_addr_t fastd_get_source_address(const fastd_context_t *ctx, fastd_buffer_t buffer) { + fastd_eth_addr_t ret; + switch (ctx->conf->mode) { case MODE_TAP: - return (fastd_eth_addr_t*)&((struct ethhdr*)buffer.data)->h_source; + memcpy(&ret, buffer.data+offsetof(struct ethhdr, h_source), ETH_ALEN); + return ret; default: exit_bug(ctx, "invalid mode"); } } -const fastd_eth_addr_t* fastd_get_dest_address(const fastd_context_t *ctx, fastd_buffer_t buffer) { +fastd_eth_addr_t fastd_get_dest_address(const fastd_context_t *ctx, fastd_buffer_t buffer) { + fastd_eth_addr_t ret; switch (ctx->conf->mode) { case MODE_TAP: - return (fastd_eth_addr_t*)&((struct ethhdr*)buffer.data)->h_dest; + memcpy(&ret, buffer.data+offsetof(struct ethhdr, h_dest), ETH_ALEN); + return ret; default: exit_bug(ctx, "invalid mode"); } @@ -640,21 +645,22 @@ static inline int fastd_eth_addr_cmp(const fastd_eth_addr_t *addr1, const fastd_ return memcmp(addr1->data, addr2->data, ETH_ALEN); } -static inline int fastd_peer_eth_addr_cmp(const fastd_peer_eth_addr_t *addr1, const fastd_peer_eth_addr_t *addr2) { - return fastd_eth_addr_cmp(&addr1->addr, &addr2->addr); -} +static inline fastd_peer_eth_addr_t* peer_get_by_addr(fastd_context_t *ctx, fastd_eth_addr_t addr) { + fastd_eth_addr_t *ret = bsearch(&addr, &ctx->eth_addr[0].addr, ctx->n_eth_addr, sizeof(fastd_peer_eth_addr_t), + (int (*)(const void *, const void *))fastd_eth_addr_cmp); -static inline fastd_peer_eth_addr_t* peer_get_by_addr(fastd_context_t *ctx, const fastd_eth_addr_t *addr) { - return bsearch(container_of(addr, fastd_peer_eth_addr_t, addr), ctx->eth_addr, ctx->n_eth_addr, sizeof(fastd_peer_eth_addr_t), - (int (*)(const void *, const void *))fastd_peer_eth_addr_cmp); + if (ret) + return container_of(ret, fastd_peer_eth_addr_t, addr); + else + return NULL; } -void fastd_peer_eth_addr_add(fastd_context_t *ctx, fastd_peer_t *peer, const fastd_eth_addr_t *addr) { +void fastd_peer_eth_addr_add(fastd_context_t *ctx, fastd_peer_t *peer, fastd_eth_addr_t addr) { int min = 0, max = ctx->n_eth_addr; while (max > min) { int cur = (min+max)/2; - int cmp = fastd_eth_addr_cmp(addr, &ctx->eth_addr[cur].addr); + int cmp = fastd_eth_addr_cmp(&addr, &ctx->eth_addr[cur].addr); if (cmp == 0) { ctx->eth_addr[cur].peer = peer; @@ -683,9 +689,9 @@ void fastd_peer_eth_addr_add(fastd_context_t *ctx, fastd_peer_t *peer, const fas for (i = ctx->n_eth_addr-1; i > min; i--) ctx->eth_addr[i] = ctx->eth_addr[i-1]; - ctx->eth_addr[min] = (fastd_peer_eth_addr_t){ *addr, peer, ctx->now }; + ctx->eth_addr[min] = (fastd_peer_eth_addr_t){ addr, peer, ctx->now }; - pr_debug(ctx, "learned new MAC address %E on peer %P", addr, peer); + pr_debug(ctx, "learned new MAC address %E on peer %P", &addr, peer); } void fastd_peer_eth_addr_cleanup(fastd_context_t *ctx) { @@ -705,7 +711,7 @@ void fastd_peer_eth_addr_cleanup(fastd_context_t *ctx) { ctx->n_eth_addr -= deleted; } -fastd_peer_t* fastd_peer_find_by_eth_addr(fastd_context_t *ctx, const fastd_eth_addr_t *addr) { +fastd_peer_t* fastd_peer_find_by_eth_addr(fastd_context_t *ctx, const fastd_eth_addr_t addr) { fastd_peer_eth_addr_t *peer_eth_addr = peer_get_by_addr(ctx, addr); if (peer_eth_addr) diff --git a/src/peer.h b/src/peer.h index 12f591d..fd32166 100644 --- a/src/peer.h +++ b/src/peer.h @@ -152,8 +152,8 @@ static inline bool fastd_peer_handshake_scheduled(fastd_context_t *ctx UNUSED, f return fastd_dlist_linked(&peer->handshake_entry); } -const fastd_eth_addr_t* fastd_get_source_address(const fastd_context_t *ctx, fastd_buffer_t buffer); -const fastd_eth_addr_t* fastd_get_dest_address(const fastd_context_t *ctx, fastd_buffer_t buffer); +fastd_eth_addr_t fastd_get_source_address(const fastd_context_t *ctx, fastd_buffer_t buffer); +fastd_eth_addr_t fastd_get_dest_address(const fastd_context_t *ctx, fastd_buffer_t buffer); static inline bool fastd_peer_allow_unknown(fastd_context_t *ctx) { return ctx->conf->on_verify; @@ -204,12 +204,12 @@ static inline bool fastd_peer_is_socket_dynamic(const fastd_peer_t *peer) { return (!peer->sock || !peer->sock->addr); } -static inline bool fastd_eth_addr_is_unicast(const fastd_eth_addr_t *addr) { - return ((addr->data[0] & 1) == 0); +static inline bool fastd_eth_addr_is_unicast(fastd_eth_addr_t addr) { + return ((addr.data[0] & 1) == 0); } -void fastd_peer_eth_addr_add(fastd_context_t *ctx, fastd_peer_t *peer, const fastd_eth_addr_t *addr); +void fastd_peer_eth_addr_add(fastd_context_t *ctx, fastd_peer_t *peer, fastd_eth_addr_t addr); void fastd_peer_eth_addr_cleanup(fastd_context_t *ctx); -fastd_peer_t* fastd_peer_find_by_eth_addr(fastd_context_t *ctx, const fastd_eth_addr_t *addr); +fastd_peer_t* fastd_peer_find_by_eth_addr(fastd_context_t *ctx, fastd_eth_addr_t addr); #endif /* _FASTD_PEER_H_ */ diff --git a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c index 0b3b049..82887cf 100644 --- a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c +++ b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c @@ -60,7 +60,7 @@ static fastd_protocol_config_t* protocol_init(fastd_context_t *ctx) { ecc_25519_work_t work; ecc_25519_scalarmult_base(&work, &protocol_config->key.secret); - ecc_25519_store_packed(&protocol_config->key.public, &work); + ecc_25519_store_packed(&protocol_config->key.public.int256, &work); return protocol_config; } @@ -75,7 +75,7 @@ static void protocol_peer_configure(fastd_context_t *ctx, fastd_peer_config_t *p } aligned_int256_t key; - if (!read_key(key.p, peer_conf->key)) { + if (!read_key(key.u8, peer_conf->key)) { pr_warn(ctx, "invalid key configured for `%s', disabling peer", peer_conf->name); return; } @@ -83,7 +83,7 @@ static void protocol_peer_configure(fastd_context_t *ctx, fastd_peer_config_t *p peer_conf->protocol_config = malloc(sizeof(fastd_protocol_peer_config_t)); peer_conf->protocol_config->public_key = key; - if (memcmp(peer_conf->protocol_config->public_key.p, ctx->conf->protocol_config->key.public.p, 32) == 0) + if (memcmp(&peer_conf->protocol_config->public_key, &ctx->conf->protocol_config->key.public, 32) == 0) pr_debug(ctx, "found own key as `%s', ignoring peer", peer_conf->name); } diff --git a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h index 01903c8..608276f 100644 --- a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h +++ b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h @@ -34,7 +34,11 @@ #include -typedef ecc_int256_t __attribute__((aligned(4))) aligned_int256_t; +typedef union aligned_int256 { + ecc_int256_t int256; + uint32_t u32[8]; + uint8_t u8[32]; +} aligned_int256_t; typedef struct keypair { ecc_int256_t secret; diff --git a/src/protocols/ec25519_fhmqvc/handshake.c b/src/protocols/ec25519_fhmqvc/handshake.c index 182abca..5606463 100644 --- a/src/protocols/ec25519_fhmqvc/handshake.c +++ b/src/protocols/ec25519_fhmqvc/handshake.c @@ -56,14 +56,14 @@ static void derive_key(fastd_sha256_t *out, size_t blocks, const uint32_t *salt, size_t methodlen = strlen(method_name); uint8_t info[4*PUBLICKEYBYTES + methodlen]; - memcpy(info, A->p, PUBLICKEYBYTES); - memcpy(info+PUBLICKEYBYTES, B->p, PUBLICKEYBYTES); - memcpy(info+2*PUBLICKEYBYTES, X->p, PUBLICKEYBYTES); - memcpy(info+3*PUBLICKEYBYTES, Y->p, PUBLICKEYBYTES); + memcpy(info, A, PUBLICKEYBYTES); + memcpy(info+PUBLICKEYBYTES, B, PUBLICKEYBYTES); + memcpy(info+2*PUBLICKEYBYTES, X, PUBLICKEYBYTES); + memcpy(info+3*PUBLICKEYBYTES, Y, PUBLICKEYBYTES); memcpy(info+4*PUBLICKEYBYTES, method_name, methodlen); fastd_sha256_t prk; - fastd_hkdf_sha256_extract(&prk, salt, (const uint32_t*)sigma->p, PUBLICKEYBYTES); + fastd_hkdf_sha256_extract(&prk, salt, sigma->u32, PUBLICKEYBYTES); fastd_hkdf_sha256_expand(out, blocks, &prk, info, sizeof(info)); } @@ -106,7 +106,7 @@ static inline void new_session(fastd_context_t *ctx, fastd_peer_t *peer, const c } else { fastd_sha256_t hash; - fastd_sha256_blocks(&hash, X->p, Y->p, A->p, B->p, sigma->p, NULL); + fastd_sha256_blocks(&hash, X->u32, Y->u32, A->u32, B->u32, sigma->u32, NULL); peer->protocol_state->session.method_state = method->session_init_compat(ctx, method_name, hash.b, HASHBYTES, initiator); } @@ -175,18 +175,18 @@ static bool make_shared_handshake_key(fastd_context_t *ctx, const ecc_int256_t * ecc_25519_work_t work, workXY; - if (!ecc_25519_load_packed(&workXY, initiator ? Y : X)) + if (!ecc_25519_load_packed(&workXY, initiator ? &Y->int256 : &X->int256)) return false; ecc_25519_scalarmult(&work, &ecc_25519_gf_order, &workXY); if (!ecc_25519_is_identity(&work)) return false; - if (!ecc_25519_load_packed(&work, initiator ? B : A)) + if (!ecc_25519_load_packed(&work, initiator ? &B->int256 : &A->int256)) return false; fastd_sha256_t hashbuf; - fastd_sha256_blocks(&hashbuf, Y->p, X->p, B->p, A->p, NULL); + fastd_sha256_blocks(&hashbuf, Y->u32, X->u32, B->u32, A->u32, NULL); ecc_int256_t d = {{0}}, e = {{0}}, s; @@ -217,13 +217,13 @@ static bool make_shared_handshake_key(fastd_context_t *ctx, const ecc_int256_t * if (ecc_25519_is_identity(&work)) return false; - ecc_25519_store_packed(sigma, &work); + ecc_25519_store_packed(&sigma->int256, &work); if (shared_handshake_key) derive_key(shared_handshake_key, 1, zero_salt, "", A, B, X, Y, sigma); if (shared_handshake_key_compat) - fastd_sha256_blocks(shared_handshake_key_compat, Y->p, X->p, B->p, A->p, sigma->p, NULL); + fastd_sha256_blocks(shared_handshake_key_compat, Y->u32, X->u32, B->u32, A->u32, sigma->u32, NULL); return true; } @@ -270,15 +270,15 @@ static void respond_handshake(fastd_context_t *ctx, const fastd_socket_t *sock, fastd_buffer_t buffer = fastd_handshake_new_reply(ctx, handshake, method, true, 4*(4+PUBLICKEYBYTES) + 2*(4+HASHBYTES)); - fastd_handshake_add(ctx, &buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, ctx->conf->protocol_config->key.public.p); - fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_KEY, PUBLICKEYBYTES, peer->protocol_config->public_key.p); - fastd_handshake_add(ctx, &buffer, RECORD_SENDER_HANDSHAKE_KEY, PUBLICKEYBYTES, handshake_key->key.public.p); - fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_HANDSHAKE_KEY, PUBLICKEYBYTES, peer_handshake_key->p); + fastd_handshake_add(ctx, &buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, &ctx->conf->protocol_config->key.public); + fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_KEY, PUBLICKEYBYTES, &peer->protocol_config->public_key); + fastd_handshake_add(ctx, &buffer, RECORD_SENDER_HANDSHAKE_KEY, PUBLICKEYBYTES, &handshake_key->key.public); + fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_HANDSHAKE_KEY, PUBLICKEYBYTES, peer_handshake_key); fastd_sha256_t hmacbuf; if (!ctx->conf->secure_handshakes) { - fastd_hmacsha256_blocks(&hmacbuf, peer->protocol_state->shared_handshake_key_compat.w, ctx->conf->protocol_config->key.public.p, handshake_key->key.public.p, NULL); + fastd_hmacsha256_blocks(&hmacbuf, peer->protocol_state->shared_handshake_key_compat.w, ctx->conf->protocol_config->key.public.u32, handshake_key->key.public.u32, NULL); fastd_handshake_add(ctx, &buffer, RECORD_T, HASHBYTES, hmacbuf.b); } @@ -316,7 +316,7 @@ static void finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const f valid = fastd_hmacsha256_verify(mac, shared_handshake_key.w, handshake->tlv_data, handshake->tlv_len); } else { - valid = fastd_hmacsha256_blocks_verify(handshake->records[RECORD_T].data, shared_handshake_key_compat.w, peer->protocol_config->public_key.p, peer_handshake_key->p, NULL); + valid = fastd_hmacsha256_blocks_verify(handshake->records[RECORD_T].data, shared_handshake_key_compat.w, peer->protocol_config->public_key.u32, peer_handshake_key->u32, NULL); } if (!valid) { @@ -330,10 +330,10 @@ static void finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const f fastd_buffer_t buffer = fastd_handshake_new_reply(ctx, handshake, method, false, 4*(4+PUBLICKEYBYTES) + 2*(4+HASHBYTES)); - fastd_handshake_add(ctx, &buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, ctx->conf->protocol_config->key.public.p); - fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_KEY, PUBLICKEYBYTES, peer->protocol_config->public_key.p); - fastd_handshake_add(ctx, &buffer, RECORD_SENDER_HANDSHAKE_KEY, PUBLICKEYBYTES, handshake_key->key.public.p); - fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_HANDSHAKE_KEY, PUBLICKEYBYTES, peer_handshake_key->p); + fastd_handshake_add(ctx, &buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, &ctx->conf->protocol_config->key.public); + fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_KEY, PUBLICKEYBYTES, &peer->protocol_config->public_key); + fastd_handshake_add(ctx, &buffer, RECORD_SENDER_HANDSHAKE_KEY, PUBLICKEYBYTES, &handshake_key->key.public); + fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_HANDSHAKE_KEY, PUBLICKEYBYTES, peer_handshake_key); if (!compat) { fastd_sha256_t hmacbuf; @@ -343,7 +343,7 @@ static void finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, const f } else { fastd_sha256_t hmacbuf; - fastd_hmacsha256_blocks(&hmacbuf, shared_handshake_key_compat.w, ctx->conf->protocol_config->key.public.p, handshake_key->key.public.p, NULL); + fastd_hmacsha256_blocks(&hmacbuf, shared_handshake_key_compat.w, ctx->conf->protocol_config->key.public.u32, handshake_key->key.public.u32, NULL); fastd_handshake_add(ctx, &buffer, RECORD_T, HASHBYTES, hmacbuf.b); } @@ -369,7 +369,7 @@ static void handle_finish_handshake(fastd_context_t *ctx, fastd_socket_t *sock, valid = fastd_hmacsha256_verify(mac, peer->protocol_state->shared_handshake_key.w, handshake->tlv_data, handshake->tlv_len); } else { - valid = fastd_hmacsha256_blocks_verify(handshake->records[RECORD_T].data, peer->protocol_state->shared_handshake_key_compat.w, peer->protocol_config->public_key.p, peer_handshake_key->p, NULL); + valid = fastd_hmacsha256_blocks_verify(handshake->records[RECORD_T].data, peer->protocol_state->shared_handshake_key_compat.w, peer->protocol_config->public_key.u32, peer_handshake_key->u32, NULL); } if (!valid) { @@ -389,7 +389,7 @@ static fastd_peer_t* find_sender_key(fastd_context_t *ctx, const fastd_peer_addr fastd_peer_t *ret = NULL, *peer; for (peer = peers; peer; peer = peer->next) { - if (memcmp(peer->protocol_config->public_key.p, key, PUBLICKEYBYTES) == 0) { + if (memcmp(&peer->protocol_config->public_key, key, PUBLICKEYBYTES) == 0) { if (!fastd_peer_matches_address(ctx, peer, address)) { errno = EPERM; return NULL; @@ -418,7 +418,7 @@ static fastd_peer_t* match_sender_key(fastd_context_t *ctx, const fastd_socket_t exit_bug(ctx, "packet without correct peer set on dynamic socket"); if (peer) { - if (memcmp(peer->protocol_config->public_key.p, key, PUBLICKEYBYTES) == 0) + if (memcmp(&peer->protocol_config->public_key, key, PUBLICKEYBYTES) == 0) return peer; if (fastd_peer_owns_address(ctx, peer, address)) { @@ -443,7 +443,7 @@ static size_t key_count(fastd_context_t *ctx, const unsigned char key[32]) { if (!p->protocol_config) continue; - if (memcmp(p->protocol_config->public_key.p, key, 32) == 0) + if (memcmp(&p->protocol_config->public_key, key, 32) == 0) ret++; } @@ -454,12 +454,12 @@ bool fastd_protocol_ec25519_fhmqvc_peer_check(fastd_context_t *ctx, fastd_peer_c if (!peer_conf->protocol_config) return false; - if (memcmp(peer_conf->protocol_config->public_key.p, ctx->conf->protocol_config->key.public.p, 32) == 0) + if (memcmp(&peer_conf->protocol_config->public_key, &ctx->conf->protocol_config->key.public, 32) == 0) return false; - if (key_count(ctx, peer_conf->protocol_config->public_key.p) > 1) { + if (key_count(ctx, peer_conf->protocol_config->public_key.u8) > 1) { char buf[65]; - hexdump(buf, peer_conf->protocol_config->public_key.p); + hexdump(buf, peer_conf->protocol_config->public_key.u8); pr_warn(ctx, "more than one peer is configured with key %s, disabling %s", buf, peer_conf->name); return false; } @@ -468,9 +468,9 @@ bool fastd_protocol_ec25519_fhmqvc_peer_check(fastd_context_t *ctx, fastd_peer_c } bool fastd_protocol_ec25519_fhmqvc_peer_check_temporary(fastd_context_t *ctx, fastd_peer_t *peer) { - if (key_count(ctx, peer->protocol_config->public_key.p)) { + if (key_count(ctx, peer->protocol_config->public_key.u8)) { char buf[65]; - hexdump(buf, peer->protocol_config->public_key.p); + hexdump(buf, peer->protocol_config->public_key.u8); pr_info(ctx, "key %s is configured now, deleting temporary peer.", buf); return false; } @@ -492,7 +492,7 @@ static inline fastd_peer_t* add_temporary(fastd_context_t *ctx, const fastd_peer fastd_peer_t *peer = fastd_peer_add_temporary(ctx); peer->protocol_config = malloc(sizeof(fastd_protocol_peer_config_t)); - memcpy(peer->protocol_config->public_key.p, key, PUBLICKEYBYTES); + memcpy(&peer->protocol_config->public_key, key, PUBLICKEYBYTES); /* Ugly hack */ peer->protocol_state->last_serial--; @@ -517,14 +517,14 @@ void fastd_protocol_ec25519_fhmqvc_handshake_init(fastd_context_t *ctx, const fa fastd_buffer_t buffer = fastd_handshake_new_init(ctx, 3*(4+PUBLICKEYBYTES) /* sender key, receipient key, handshake key */); - fastd_handshake_add(ctx, &buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, ctx->conf->protocol_config->key.public.p); + fastd_handshake_add(ctx, &buffer, RECORD_SENDER_KEY, PUBLICKEYBYTES, &ctx->conf->protocol_config->key.public); if (peer) - fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_KEY, PUBLICKEYBYTES, peer->protocol_config->public_key.p); + fastd_handshake_add(ctx, &buffer, RECORD_RECEIPIENT_KEY, PUBLICKEYBYTES, &peer->protocol_config->public_key); else pr_debug(ctx, "sending handshake to unknown peer %I", remote_addr); - fastd_handshake_add(ctx, &buffer, RECORD_SENDER_HANDSHAKE_KEY, PUBLICKEYBYTES, ctx->protocol_state->handshake_key.key.public.p); + fastd_handshake_add(ctx, &buffer, RECORD_SENDER_HANDSHAKE_KEY, PUBLICKEYBYTES, &ctx->protocol_state->handshake_key.key.public); fastd_send_handshake(ctx, sock, local_addr, remote_addr, peer, buffer); } @@ -578,7 +578,7 @@ void fastd_protocol_ec25519_fhmqvc_handshake_handle(fastd_context_t *ctx, fastd_ } if (has_field(handshake, RECORD_RECEIPIENT_KEY, PUBLICKEYBYTES)) { - if (memcmp(ctx->conf->protocol_config->key.public.p, handshake->records[RECORD_RECEIPIENT_KEY].data, PUBLICKEYBYTES) != 0) { + if (memcmp(&ctx->conf->protocol_config->key.public, handshake->records[RECORD_RECEIPIENT_KEY].data, PUBLICKEYBYTES) != 0) { pr_debug(ctx, "received protocol handshake with wrong receipient key from %P[%I]", peer, remote_addr); return; } @@ -590,7 +590,7 @@ void fastd_protocol_ec25519_fhmqvc_handshake_handle(fastd_context_t *ctx, fastd_ } aligned_int256_t peer_handshake_key; - memcpy(peer_handshake_key.p, handshake->records[RECORD_SENDER_HANDSHAKE_KEY].data, PUBLICKEYBYTES); + memcpy(&peer_handshake_key, handshake->records[RECORD_SENDER_HANDSHAKE_KEY].data, PUBLICKEYBYTES); if (handshake->type == 1) { if (timespec_diff(&ctx->now, &peer->last_handshake_response) < (int)ctx->conf->min_handshake_interval*1000 @@ -626,11 +626,11 @@ void fastd_protocol_ec25519_fhmqvc_handshake_handle(fastd_context_t *ctx, fastd_ handshake_key_t *handshake_key; if (is_handshake_key_valid(ctx, &ctx->protocol_state->handshake_key) && - memcmp(&ctx->protocol_state->handshake_key.key.public.p, handshake->records[RECORD_RECEIPIENT_HANDSHAKE_KEY].data, PUBLICKEYBYTES) == 0) { + memcmp(&ctx->protocol_state->handshake_key.key.public, handshake->records[RECORD_RECEIPIENT_HANDSHAKE_KEY].data, PUBLICKEYBYTES) == 0) { handshake_key = &ctx->protocol_state->handshake_key; } else if (is_handshake_key_valid(ctx, &ctx->protocol_state->prev_handshake_key) && - memcmp(&ctx->protocol_state->prev_handshake_key.key.public.p, handshake->records[RECORD_RECEIPIENT_HANDSHAKE_KEY].data, PUBLICKEYBYTES) == 0) { + memcmp(&ctx->protocol_state->prev_handshake_key.key.public, handshake->records[RECORD_RECEIPIENT_HANDSHAKE_KEY].data, PUBLICKEYBYTES) == 0) { handshake_key = &ctx->protocol_state->prev_handshake_key; } else { diff --git a/src/protocols/ec25519_fhmqvc/state.c b/src/protocols/ec25519_fhmqvc/state.c index 3affc44..727763a 100644 --- a/src/protocols/ec25519_fhmqvc/state.c +++ b/src/protocols/ec25519_fhmqvc/state.c @@ -42,7 +42,7 @@ static void new_handshake_key(fastd_context_t *ctx, keypair_t *key) { ecc_25519_work_t work; ecc_25519_scalarmult_base(&work, &key->secret); - ecc_25519_store_packed(&key->public, &work); + ecc_25519_store_packed(&key->public.int256, &work); } void fastd_protocol_ec25519_fhmqvc_maintenance(fastd_context_t *ctx) { diff --git a/src/protocols/ec25519_fhmqvc/util.c b/src/protocols/ec25519_fhmqvc/util.c index 07f4724..e653f7f 100644 --- a/src/protocols/ec25519_fhmqvc/util.c +++ b/src/protocols/ec25519_fhmqvc/util.c @@ -59,19 +59,19 @@ void fastd_protocol_ec25519_fhmqvc_generate_key(fastd_context_t *ctx) { void fastd_protocol_ec25519_fhmqvc_show_key(fastd_context_t *ctx) { if (ctx->conf->machine_readable) - print_hexdump("", ctx->conf->protocol_config->key.public.p); + print_hexdump("", ctx->conf->protocol_config->key.public.u8); else - print_hexdump("Public: ", ctx->conf->protocol_config->key.public.p); + print_hexdump("Public: ", ctx->conf->protocol_config->key.public.u8); } void fastd_protocol_ec25519_fhmqvc_set_shell_env(fastd_context_t *ctx, const fastd_peer_t *peer) { char buf[65]; - hexdump(buf, ctx->conf->protocol_config->key.public.p); + hexdump(buf, ctx->conf->protocol_config->key.public.u8); setenv("LOCAL_KEY", buf, 1); if (peer && peer->protocol_config) { - hexdump(buf, peer->protocol_config->public_key.p); + hexdump(buf, peer->protocol_config->public_key.u8); setenv("PEER_KEY", buf, 1); } else { @@ -83,7 +83,7 @@ bool fastd_protocol_ec25519_fhmqvc_describe_peer(const fastd_context_t *ctx UNUS if (peer && peer->protocol_config) { char dumpbuf[65]; - hexdump(dumpbuf, peer->protocol_config->public_key.p); + hexdump(dumpbuf, peer->protocol_config->public_key.u8); snprintf(buf, len, "%.16s", dumpbuf); return true; } diff --git a/src/receive.c b/src/receive.c index 39ede66..472b664 100644 --- a/src/receive.c +++ b/src/receive.c @@ -32,21 +32,24 @@ static inline void handle_socket_control(struct msghdr *message, const fastd_socket_t *sock, fastd_peer_address_t *local_addr) { memset(local_addr, 0, sizeof(fastd_peer_address_t)); - const char *end = (char*)message->msg_control + message->msg_controllen; + const uint8_t *end = (const uint8_t*)message->msg_control + message->msg_controllen; struct cmsghdr *cmsg; for (cmsg = CMSG_FIRSTHDR(message); cmsg; cmsg = CMSG_NXTHDR(message, cmsg)) { - if ((char*)cmsg + sizeof(*cmsg) > end) + if ((const uint8_t*)cmsg + sizeof(*cmsg) > end) return; #ifdef USE_PKTINFO if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { - struct in_pktinfo *pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg); - if ((char*)pktinfo + sizeof(*pktinfo) > end) + struct in_pktinfo pktinfo; + + if ((const uint8_t*)CMSG_DATA(cmsg) + sizeof(pktinfo) > end) return; + memcpy(&pktinfo, CMSG_DATA(cmsg), sizeof(pktinfo)); + local_addr->in.sin_family = AF_INET; - local_addr->in.sin_addr = pktinfo->ipi_addr; + local_addr->in.sin_addr = pktinfo.ipi_addr; local_addr->in.sin_port = fastd_peer_address_get_port(sock->bound_addr); return; @@ -54,16 +57,19 @@ static inline void handle_socket_control(struct msghdr *message, const fastd_soc #endif if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) { - struct in6_pktinfo *pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg); - if ((char*)pktinfo + sizeof(*pktinfo) > end) + struct in6_pktinfo pktinfo; + + if ((uint8_t*)CMSG_DATA(cmsg) + sizeof(pktinfo) > end) return; + memcpy(&pktinfo, CMSG_DATA(cmsg), sizeof(pktinfo)); + local_addr->in6.sin6_family = AF_INET6; - local_addr->in6.sin6_addr = pktinfo->ipi6_addr; + local_addr->in6.sin6_addr = pktinfo.ipi6_addr; local_addr->in6.sin6_port = fastd_peer_address_get_port(sock->bound_addr); if (IN6_IS_ADDR_LINKLOCAL(&local_addr->in6.sin6_addr)) - local_addr->in6.sin6_scope_id = pktinfo->ipi6_ifindex; + local_addr->in6.sin6_scope_id = pktinfo.ipi6_ifindex; return; } diff --git a/src/send.c b/src/send.c index caaa9f6..9f76d31 100644 --- a/src/send.c +++ b/src/send.c @@ -42,8 +42,9 @@ static inline void add_pktinfo(struct msghdr *msg, const fastd_peer_address_t *l msg->msg_controllen += cmsg->cmsg_len; - struct in_pktinfo *pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg); - pktinfo->ipi_spec_dst = local_addr->in.sin_addr; + struct in_pktinfo pktinfo = {}; + pktinfo.ipi_spec_dst = local_addr->in.sin_addr; + memcpy(CMSG_DATA(cmsg), &pktinfo, sizeof(pktinfo)); return; } #endif @@ -55,11 +56,13 @@ static inline void add_pktinfo(struct msghdr *msg, const fastd_peer_address_t *l msg->msg_controllen += cmsg->cmsg_len; - struct in6_pktinfo *pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg); - pktinfo->ipi6_addr = local_addr->in6.sin6_addr; + struct in6_pktinfo pktinfo = {}; + pktinfo.ipi6_addr = local_addr->in6.sin6_addr; if (IN6_IS_ADDR_LINKLOCAL(&local_addr->in6.sin6_addr)) - pktinfo->ipi6_ifindex = local_addr->in6.sin6_scope_id; + pktinfo.ipi6_ifindex = local_addr->in6.sin6_scope_id; + + memcpy(CMSG_DATA(cmsg), &pktinfo, sizeof(pktinfo)); } } diff --git a/src/socket.c b/src/socket.c index c5356f7..06d270d 100644 --- a/src/socket.c +++ b/src/socket.c @@ -108,7 +108,7 @@ static int bind_socket(fastd_context_t *ctx, const fastd_bind_address_t *addr, b bind_address.in.sin_port = addr->addr.in.sin_port; } - if (bind(fd, (struct sockaddr*)&bind_address, bind_address.sa.sa_family == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))) { + if (bind(fd, &bind_address.sa, bind_address.sa.sa_family == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))) { if (warn) pr_warn_errno(ctx, "bind"); goto error; diff --git a/src/tuntap.c b/src/tuntap.c index b1820f9..1204049 100644 --- a/src/tuntap.c +++ b/src/tuntap.c @@ -310,15 +310,15 @@ fastd_buffer_t fastd_tuntap_read(fastd_context_t *ctx) { void fastd_tuntap_write(fastd_context_t *ctx, fastd_buffer_t buffer) { if (multiaf_tun && ctx->conf->mode == MODE_TUN) { uint8_t version = *((uint8_t*)buffer.data) >> 4; - int af; + uint32_t af; switch (version) { case 4: - af = AF_INET; + af = htonl(AF_INET); break; case 6: - af = AF_INET6; + af = htonl(AF_INET6); break; default: @@ -327,7 +327,7 @@ void fastd_tuntap_write(fastd_context_t *ctx, fastd_buffer_t buffer) { } fastd_buffer_pull_head(ctx, &buffer, 4); - *((uint32_t*)buffer.data) = htonl(af); + memcpy(buffer.data, &af, 4); } if (write(ctx->tunfd, buffer.data, buffer.len) < 0) -- cgit v1.2.3