summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/method_aes128_gcm.c65
1 files changed, 34 insertions, 31 deletions
diff --git a/src/method_aes128_gcm.c b/src/method_aes128_gcm.c
index ad4a5d2..b0c3232 100644
--- a/src/method_aes128_gcm.c
+++ b/src/method_aes128_gcm.c
@@ -25,7 +25,6 @@
#include "fastd.h"
-#include <asm/byteorder.h>
#include <crypto_stream_aes128ctr.h>
@@ -34,12 +33,17 @@
#define BLOCKQWORDS (BLOCKBYTES/8)
+typedef union _block_t {
+ uint8_t b[BLOCKBYTES];
+ uint64_t qw[BLOCKQWORDS];
+} block_t;
+
struct _fastd_method_session_state {
struct timespec valid_till;
struct timespec refresh_after;
uint8_t d[crypto_stream_aes128ctr_BEFORENMBYTES];
- uint64_t H[32*16*BLOCKQWORDS];
+ block_t H[32][16];
uint8_t send_nonce[NONCEBYTES];
uint8_t receive_nonce[NONCEBYTES];
@@ -91,21 +95,19 @@ static size_t method_min_decrypt_head_space(fastd_context *ctx) {
return 0;
}
-static const uint64_t r[BLOCKQWORDS] = {
- __constant_cpu_to_le64(0x87), 0,
-};
+static const block_t r = { .b = {0xe1} };
-static inline uint8_t shl(uint8_t out[BLOCKBYTES], const uint8_t in[BLOCKBYTES], int n) {
+static inline uint8_t shr(block_t *out, const block_t *in, int n) {
int i;
uint8_t c = 0;
for (i = 0; i < BLOCKBYTES; i++) {
- uint8_t c2 = in[i] >> (8-n);
- out[i] = (in[i] << n) | c;
+ uint8_t c2 = in->b[i] << (8-n);
+ out->b[i] = (in->b[i] >> n) | c;
c = c2;
}
- return c;
+ return (c >> (8-n));
}
static inline void xor(uint8_t *x, const uint8_t *a, const uint8_t *b, unsigned int l) {
@@ -114,9 +116,9 @@ static inline void xor(uint8_t *x, const uint8_t *a, const uint8_t *b, unsigned
x[i] = a[i] ^ b[i];
}
-static inline void xor_block(uint64_t x[BLOCKQWORDS], const uint64_t a[BLOCKQWORDS]) {
- x[0] ^= a[0];
- x[1] ^= a[1];
+static inline void xor_block(block_t *x, const block_t *a) {
+ x->qw[0] ^= a->qw[0];
+ x->qw[1] ^= a->qw[1];
}
static fastd_method_session_state* method_session_init(fastd_context *ctx, uint8_t *secret, size_t length, bool initiator) {
@@ -137,30 +139,31 @@ static fastd_method_session_state* method_session_init(fastd_context *ctx, uint8
uint8_t zerononce[crypto_stream_aes128ctr_NONCEBYTES];
memset(zerononce, 0, crypto_stream_aes128ctr_NONCEBYTES);
- uint64_t Hbase[4*BLOCKQWORDS];
- uint64_t Rbase[4*BLOCKQWORDS];
- crypto_stream_aes128ctr_afternm((uint8_t*)Hbase, BLOCKBYTES, zerononce, session->d);
- memcpy(Rbase, r, BLOCKBYTES);
+ block_t Hbase[4];
+ crypto_stream_aes128ctr_afternm(Hbase[0].b, BLOCKBYTES, zerononce, session->d);
+
+ block_t Rbase[4];
+ Rbase[0] = r;
for (i = 1; i < 4; i++) {
- uint8_t carry = shl((uint8_t*)(Hbase + i*BLOCKQWORDS), (uint8_t*)(Hbase + (i-1)*BLOCKQWORDS), 1);
+ uint8_t carry = shr(&Hbase[i], &Hbase[i-1], 1);
if (carry)
- xor_block(Hbase + i*BLOCKQWORDS, r);
+ xor_block(&Hbase[i], &r);
- shl((uint8_t*)(Rbase + i*BLOCKQWORDS), (uint8_t*)(Rbase + (i-1)*BLOCKQWORDS), 1);
+ shr(&Rbase[i], &Rbase[i-1], 1);
}
- uint64_t R[16*BLOCKQWORDS];
+ block_t R[16];
memset(session->H, 0, sizeof(session->H));
memset(R, 0, sizeof(R));
for (i = 0; i < 16; i++) {
int j;
for (j = 0; j < 4; j++) {
- if (i & (1 << j)) {
- xor_block(session->H + i*BLOCKQWORDS, Hbase + j*BLOCKQWORDS);
- xor_block(R + i*BLOCKQWORDS, Rbase + j*BLOCKQWORDS);
+ if (i & (8 >> j)) {
+ xor_block(&session->H[0][i], &Hbase[j]);
+ xor_block(&R[i], &Rbase[j]);
}
}
}
@@ -169,8 +172,8 @@ static fastd_method_session_state* method_session_init(fastd_context *ctx, uint8
int j;
for (j = 0; j < 16; j++) {
- uint8_t carry = shl((uint8_t*)(session->H + (16*i + j)*BLOCKQWORDS), (uint8_t*)(session->H + (16*(i-1) + j)*BLOCKQWORDS), 4);
- xor_block(session->H + (16*i + j)*BLOCKQWORDS, R + carry*BLOCKQWORDS);
+ uint8_t carry = shr(&session->H[i][j], &session->H[i-1][j], 4);
+ xor_block(&session->H[i][j], &R[carry]);
}
}
@@ -205,19 +208,19 @@ static void method_session_free(fastd_context *ctx, fastd_method_session_state *
}
static void mulH(uint8_t out[BLOCKBYTES], const uint8_t in[BLOCKBYTES], fastd_method_session_state *session) {
- uint64_t out2[BLOCKQWORDS];
- memset(out2, 0, BLOCKBYTES);
+ block_t out2;
+ memset(&out2, 0, BLOCKBYTES);
int i;
for (i = 0; i < 16; i++) {
- xor_block(out2, session->H + (32*i + (in[i]&0xf))*BLOCKQWORDS);
- xor_block(out2, session->H + (32*i+16 + (in[i]>>4))*BLOCKQWORDS);
+ xor_block(&out2, &session->H[2*i][in[i]>>4]);
+ xor_block(&out2, &session->H[2*i+1][in[i]&0xf]);
}
- memcpy(out, out2, BLOCKBYTES);
+ memcpy(out, &out2, BLOCKBYTES);
}
-#define BLOCKPTR(buf, i) (((uint8_t*)(buf))+i*BLOCKBYTES)
+#define BLOCKPTR(buf, i) (((uint8_t*)(buf))+(i)*BLOCKBYTES)
static bool method_encrypt(fastd_context *ctx, fastd_peer *peer, fastd_method_session_state *session, fastd_buffer *out, fastd_buffer in) {
*out = fastd_buffer_alloc(in.len, NONCEBYTES+BLOCKBYTES, 0);