From cf43b72fa61380937fde2aa2ad7e1275862a1020 Mon Sep 17 00:00:00 2001 From: Mikhail Labiuk Date: Sun, 5 Dec 2021 23:59:08 +0300 Subject: [PATCH 01/12] Avoid unaligned data access for grasshopper ctracpkm. Compiler can produce incorrect instructions for arch with strict memory access like ARM. Root case is compiler assuming some data type is always aligned properly. Pointer cast from unaligned pointer to this type `grasshopper_w128_t` can trigger segmentation fault. --- gost_grasshopper_cipher.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/gost_grasshopper_cipher.c b/gost_grasshopper_cipher.c index 38dd98776..8ab6d7774 100644 --- a/gost_grasshopper_cipher.c +++ b/gost_grasshopper_cipher.c @@ -510,10 +510,10 @@ static int gost_grasshopper_cipher_do_ctracpkm(EVP_CIPHER_CTX *ctx, size_t inl) { gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx); - unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); unsigned int num = EVP_CIPHER_CTX_num(ctx); size_t blocks, i, lasted = inl; - grasshopper_w128_t tmp; + grasshopper_w128_t ivb, inb, outb; + memcpy(&ivb, EVP_CIPHER_CTX_iv_noconst(ctx), sizeof(ivb)); while ((num & GRASSHOPPER_BLOCK_MASK) && lasted) { *out++ = *in++ ^ c->partial_buffer.b[num & GRASSHOPPER_BLOCK_MASK]; @@ -526,13 +526,13 @@ static int gost_grasshopper_cipher_do_ctracpkm(EVP_CIPHER_CTX *ctx, for (i = 0; i < blocks; i++) { apply_acpkm_grasshopper(c, &num); grasshopper_encrypt_block(&c->c.encrypt_round_keys, - (grasshopper_w128_t *) iv, - (grasshopper_w128_t *) & c->partial_buffer, + &ivb, + &c->partial_buffer, &c->c.buffer); - grasshopper_plus128(&tmp, &c->partial_buffer, - (grasshopper_w128_t *) in); - grasshopper_copy128((grasshopper_w128_t *) out, &tmp); - ctr128_inc(iv); + memcpy(&inb, in, GRASSHOPPER_BLOCK_SIZE); + grasshopper_plus128(&outb, &c->partial_buffer, &inb); + memcpy(out, &outb, GRASSHOPPER_BLOCK_SIZE); + ctr128_inc(ivb.b); in += GRASSHOPPER_BLOCK_SIZE; out += GRASSHOPPER_BLOCK_SIZE; num += GRASSHOPPER_BLOCK_SIZE; @@ -542,14 +542,14 @@ static int gost_grasshopper_cipher_do_ctracpkm(EVP_CIPHER_CTX *ctx, // last part if (lasted > 0) { apply_acpkm_grasshopper(c, &num); - grasshopper_encrypt_block(&c->c.encrypt_round_keys, - (grasshopper_w128_t *) iv, + grasshopper_encrypt_block(&c->c.encrypt_round_keys, &ivb, &c->partial_buffer, &c->c.buffer); for (i = 0; i < lasted; i++) out[i] = c->partial_buffer.b[i] ^ in[i]; - ctr128_inc(iv); + ctr128_inc(ivb.b); num += lasted; } + memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), &ivb, sizeof(ivb)); EVP_CIPHER_CTX_set_num(ctx, num); return inl; From 8c5ee08c5e3ca78f7b790a4e02acd73c278584fa Mon Sep 17 00:00:00 2001 From: Mikhail Labiuk Date: Sun, 12 Dec 2021 23:39:10 +0300 Subject: [PATCH 02/12] Fix align-cast for gost_grasshopper_cipher_key. --- gost_grasshopper_cipher.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/gost_grasshopper_cipher.c b/gost_grasshopper_cipher.c index 8ab6d7774..9942ae3bc 100644 --- a/gost_grasshopper_cipher.c +++ b/gost_grasshopper_cipher.c @@ -154,11 +154,7 @@ static void acpkm_next(gost_grasshopper_cipher_ctx * c) static GRASSHOPPER_INLINE void gost_grasshopper_cipher_key(gost_grasshopper_cipher_ctx * c, const uint8_t *k) { - int i; - for (i = 0; i < 2; i++) { - grasshopper_copy128(&c->key.k.k[i], - (const grasshopper_w128_t *)(k + i * 16)); - } + memcpy(&c->key, k, sizeof(c->key)); grasshopper_set_encrypt_key(&c->encrypt_round_keys, &c->key); grasshopper_set_decrypt_key(&c->decrypt_round_keys, &c->key); From 55bae427194d9d648136fa05124f400b8ae684e4 Mon Sep 17 00:00:00 2001 From: Mikhail Labiuk Date: Sun, 12 Dec 2021 23:47:57 +0300 Subject: [PATCH 03/12] Fix align-cast for gost_grasshopper_master_key. --- gost_grasshopper_cipher.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/gost_grasshopper_cipher.c b/gost_grasshopper_cipher.c index 9942ae3bc..c9a4271dd 100644 --- a/gost_grasshopper_cipher.c +++ b/gost_grasshopper_cipher.c @@ -164,11 +164,7 @@ gost_grasshopper_cipher_key(gost_grasshopper_cipher_ctx * c, const uint8_t *k) static GRASSHOPPER_INLINE void gost_grasshopper_master_key(gost_grasshopper_cipher_ctx * c, const uint8_t *k) { - int i; - for (i = 0; i < 2; i++) { - grasshopper_copy128(&c->master_key.k.k[i], - (const grasshopper_w128_t *)(k + i * 16)); - } + memcpy(&c->master_key, k, sizeof(c->master_key)); } /* Cleans up key from context */ From b86224f4b9d0effd97320bf670d2eb37b462caae Mon Sep 17 00:00:00 2001 From: Mikhail Labiuk Date: Mon, 13 Dec 2021 00:03:11 +0300 Subject: [PATCH 04/12] Fix align-cast for gost_grasshopper_cipher_do_ecb. --- gost_grasshopper_cipher.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/gost_grasshopper_cipher.c b/gost_grasshopper_cipher.c index c9a4271dd..5200ff6a1 100644 --- a/gost_grasshopper_cipher.c +++ b/gost_grasshopper_cipher.c @@ -350,17 +350,16 @@ static int gost_grasshopper_cipher_do_ecb(EVP_CIPHER_CTX *ctx, unsigned char *ou for (i = 0; i < blocks; i++, current_in += GRASSHOPPER_BLOCK_SIZE, current_out += GRASSHOPPER_BLOCK_SIZE) { + grasshopper_w128_t inb, outb; + memcpy(&inb, current_in, GRASSHOPPER_BLOCK_SIZE); if (encrypting) { grasshopper_encrypt_block(&c->encrypt_round_keys, - (grasshopper_w128_t *) current_in, - (grasshopper_w128_t *) current_out, - &c->buffer); + &inb, &outb, &c->buffer); } else { grasshopper_decrypt_block(&c->decrypt_round_keys, - (grasshopper_w128_t *) current_in, - (grasshopper_w128_t *) current_out, - &c->buffer); + &inb, &outb, &c->buffer); } + memcpy(current_out, &outb, GRASSHOPPER_BLOCK_SIZE); } return 1; From ac04583f5c18b0b79dc5a5e38a6c0163fddfd5e6 Mon Sep 17 00:00:00 2001 From: Mikhail Labiuk Date: Mon, 13 Dec 2021 00:42:19 +0300 Subject: [PATCH 05/12] Fix align-cast for gost_grasshopper_cipher_do_cbc --- gost_grasshopper_cipher.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/gost_grasshopper_cipher.c b/gost_grasshopper_cipher.c index 5200ff6a1..f8571638f 100644 --- a/gost_grasshopper_cipher.c +++ b/gost_grasshopper_cipher.c @@ -370,38 +370,40 @@ static int gost_grasshopper_cipher_do_cbc(EVP_CIPHER_CTX *ctx, unsigned char *ou { gost_grasshopper_cipher_ctx *c = (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx); - unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx); const unsigned char *current_in = in; unsigned char *current_out = out; size_t blocks = inl / GRASSHOPPER_BLOCK_SIZE; size_t i; - grasshopper_w128_t *currentBlock; + grasshopper_w128_t currentBlock; - currentBlock = (grasshopper_w128_t *) iv; + memcpy(¤tBlock, EVP_CIPHER_CTX_iv_noconst(ctx), + sizeof (currentBlock)); for (i = 0; i < blocks; - i++, current_in += GRASSHOPPER_BLOCK_SIZE, current_out += - GRASSHOPPER_BLOCK_SIZE) { - grasshopper_w128_t *currentInputBlock = (grasshopper_w128_t *) current_in; - grasshopper_w128_t *currentOutputBlock = (grasshopper_w128_t *) current_out; + i++, current_in += GRASSHOPPER_BLOCK_SIZE, + current_out += GRASSHOPPER_BLOCK_SIZE) { + grasshopper_w128_t inb, outb; + memcpy(&inb, current_in, GRASSHOPPER_BLOCK_SIZE); if (encrypting) { - grasshopper_append128(currentBlock, currentInputBlock); - grasshopper_encrypt_block(&c->encrypt_round_keys, currentBlock, - currentOutputBlock, &c->buffer); - grasshopper_copy128(currentBlock, currentOutputBlock); + grasshopper_append128(¤tBlock, &inb); + grasshopper_encrypt_block(&c->encrypt_round_keys, ¤tBlock, + &outb, &c->buffer); + grasshopper_copy128(¤tBlock, &outb); } else { grasshopper_w128_t tmp; - grasshopper_copy128(&tmp, currentInputBlock); + grasshopper_copy128(&tmp, &inb); grasshopper_decrypt_block(&c->decrypt_round_keys, - currentInputBlock, currentOutputBlock, + &inb, &outb, &c->buffer); - grasshopper_append128(currentOutputBlock, currentBlock); - grasshopper_copy128(currentBlock, &tmp); + grasshopper_append128(&outb, ¤tBlock); + grasshopper_copy128(¤tBlock, &tmp); } + memcpy(current_out, &outb, GRASSHOPPER_BLOCK_SIZE); } - + memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), ¤tBlock, + sizeof (currentBlock)); return 1; } From 28369bbb2cedb9e3d259e10721e320849ecbc7f8 Mon Sep 17 00:00:00 2001 From: Mikhail Labiuk Date: Mon, 13 Dec 2021 02:06:22 +0300 Subject: [PATCH 06/12] Fix align-cast for acpkm_next. --- gost_grasshopper_cipher.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/gost_grasshopper_cipher.c b/gost_grasshopper_cipher.c index f8571638f..0fee12d0c 100644 --- a/gost_grasshopper_cipher.c +++ b/gost_grasshopper_cipher.c @@ -124,30 +124,28 @@ GOST_cipher grasshopper_ctr_acpkm_omac_cipher = { .ctx_size = sizeof(gost_grasshopper_cipher_ctx_ctr), }; -/* first 256 bit of D from draft-irtf-cfrg-re-keying-12 */ -static const unsigned char ACPKM_D_2018[] = { - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 64 bit */ - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 128 bit */ - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 256 bit */ -}; - static void acpkm_next(gost_grasshopper_cipher_ctx * c) { - unsigned char newkey[GRASSHOPPER_KEY_SIZE]; +/* first 256 bit of D from draft-irtf-cfrg-re-keying-12 */ +static const grasshopper_w128_t D[GRASSHOPPER_KEY_SIZE / GRASSHOPPER_BLOCK_SIZE] = + { + { .b={0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 64 bit */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f} },/* 128 bit */ + { .b={0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f} },/* 256 bit */ + }; + + grasshopper_key_t newkey; const int J = GRASSHOPPER_KEY_SIZE / GRASSHOPPER_BLOCK_SIZE; int n; for (n = 0; n < J; n++) { - const unsigned char *D_n = &ACPKM_D_2018[n * GRASSHOPPER_BLOCK_SIZE]; - grasshopper_encrypt_block(&c->encrypt_round_keys, - (grasshopper_w128_t *) D_n, - (grasshopper_w128_t *) & newkey[n * - GRASSHOPPER_BLOCK_SIZE], + (grasshopper_w128_t *)&D[n], + &newkey.k.k[n], &c->buffer); } - gost_grasshopper_cipher_key(c, newkey); + gost_grasshopper_cipher_key(c, newkey.k.b); } /* Set 256 bit key into context */ From 3fb43761d1892e7a3c99b3c0516be0e08fe60e49 Mon Sep 17 00:00:00 2001 From: Mikhail Labiuk Date: Wed, 15 Dec 2021 21:45:40 +0300 Subject: [PATCH 07/12] Fix align-cast for gost_grasshopper_cipher_do_ctr. --- gost_grasshopper_cipher.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/gost_grasshopper_cipher.c b/gost_grasshopper_cipher.c index 0fee12d0c..173624eb0 100644 --- a/gost_grasshopper_cipher.c +++ b/gost_grasshopper_cipher.c @@ -431,17 +431,13 @@ static int gost_grasshopper_cipher_do_ctr(EVP_CIPHER_CTX *ctx, unsigned char *ou { gost_grasshopper_cipher_ctx_ctr *c = (gost_grasshopper_cipher_ctx_ctr *) EVP_CIPHER_CTX_get_cipher_data(ctx); - unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); const unsigned char *current_in = in; unsigned char *current_out = out; - grasshopper_w128_t *currentInputBlock; - grasshopper_w128_t *currentOutputBlock; unsigned int n = EVP_CIPHER_CTX_num(ctx); size_t lasted = inl; size_t i; size_t blocks; - grasshopper_w128_t *iv_buffer; - grasshopper_w128_t tmp; + grasshopper_w128_t iv_buffer, currentInputBlock, tmp; while (n && lasted) { *(current_out++) = *(current_in++) ^ c->partial_buffer.b[n]; @@ -451,35 +447,34 @@ static int gost_grasshopper_cipher_do_ctr(EVP_CIPHER_CTX *ctx, unsigned char *ou EVP_CIPHER_CTX_set_num(ctx, n); blocks = lasted / GRASSHOPPER_BLOCK_SIZE; - iv_buffer = (grasshopper_w128_t *) iv; + memcpy(&iv_buffer, EVP_CIPHER_CTX_iv_noconst(ctx), sizeof (iv_buffer)); // full parts for (i = 0; i < blocks; i++) { - currentInputBlock = (grasshopper_w128_t *) current_in; - currentOutputBlock = (grasshopper_w128_t *) current_out; - grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer, + memcpy(¤tInputBlock, current_in, GRASSHOPPER_BLOCK_SIZE); + grasshopper_encrypt_block(&c->c.encrypt_round_keys, &iv_buffer, &c->partial_buffer, &c->c.buffer); - grasshopper_plus128(&tmp, &c->partial_buffer, currentInputBlock); - grasshopper_copy128(currentOutputBlock, &tmp); - ctr128_inc(iv_buffer->b); + grasshopper_plus128(&tmp, &c->partial_buffer, ¤tInputBlock); + memcpy(current_out, &tmp, GRASSHOPPER_BLOCK_SIZE); + ctr128_inc(iv_buffer.b); current_in += GRASSHOPPER_BLOCK_SIZE; current_out += GRASSHOPPER_BLOCK_SIZE; lasted -= GRASSHOPPER_BLOCK_SIZE; } if (lasted > 0) { - currentInputBlock = (grasshopper_w128_t *) current_in; - currentOutputBlock = (grasshopper_w128_t *) current_out; - grasshopper_encrypt_block(&c->c.encrypt_round_keys, iv_buffer, + grasshopper_encrypt_block(&c->c.encrypt_round_keys, &iv_buffer, &c->partial_buffer, &c->c.buffer); for (i = 0; i < lasted; i++) { - currentOutputBlock->b[i] = - c->partial_buffer.b[i] ^ currentInputBlock->b[i]; + current_out[i] = + c->partial_buffer.b[i] ^ current_in[i]; } EVP_CIPHER_CTX_set_num(ctx, i); - ctr128_inc(iv_buffer->b); + ctr128_inc(iv_buffer.b); } + memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), &iv_buffer, sizeof (iv_buffer)); + return inl; } From f1a0f82fcdd8d71859f798d747c08d3e5aa00ebc Mon Sep 17 00:00:00 2001 From: Mikhail Labiuk Date: Wed, 15 Dec 2021 22:17:54 +0300 Subject: [PATCH 08/12] Fix align-cast for gost_grasshopper_cipher_do_ofb. --- gost_grasshopper_cipher.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/gost_grasshopper_cipher.c b/gost_grasshopper_cipher.c index 173624eb0..828a7a48f 100644 --- a/gost_grasshopper_cipher.c +++ b/gost_grasshopper_cipher.c @@ -589,17 +589,19 @@ static int gost_grasshopper_cipher_do_ofb(EVP_CIPHER_CTX *ctx, unsigned char *ou EVP_CIPHER_CTX_get_cipher_data(ctx); const unsigned char *in_ptr = in; unsigned char *out_ptr = out; - unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx); - unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); + grasshopper_w128_t ivb, buf; int num = EVP_CIPHER_CTX_num(ctx); size_t i = 0; size_t j; + memcpy(&buf, EVP_CIPHER_CTX_buf_noconst(ctx), sizeof (buf)); + memcpy(&ivb, EVP_CIPHER_CTX_iv_noconst(ctx), sizeof (ivb)); + /* process partial block if any */ if (num > 0) { for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl; j++, i++, in_ptr++, out_ptr++) { - *out_ptr = buf[j] ^ (*in_ptr); + *out_ptr = buf.b[j] ^ (*in_ptr); } if (j == GRASSHOPPER_BLOCK_SIZE) { EVP_CIPHER_CTX_set_num(ctx, 0); @@ -617,8 +619,7 @@ static int gost_grasshopper_cipher_do_ofb(EVP_CIPHER_CTX *ctx, unsigned char *ou * block cipher current iv */ /* Encrypt */ - gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv, - (grasshopper_w128_t *) buf); + gost_grasshopper_cnt_next(c, &ivb, &buf); /* * xor next block of input text with it and output it @@ -627,22 +628,23 @@ static int gost_grasshopper_cipher_do_ofb(EVP_CIPHER_CTX *ctx, unsigned char *ou * output this block */ for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) { - out_ptr[j] = buf[j] ^ in_ptr[j]; + out_ptr[j] = buf.b[j] ^ in_ptr[j]; } } /* Process rest of buffer */ if (i < inl) { - gost_grasshopper_cnt_next(c, (grasshopper_w128_t *) iv, - (grasshopper_w128_t *) buf); + gost_grasshopper_cnt_next(c, &ivb, &buf); for (j = 0; i < inl; j++, i++) { - out_ptr[j] = buf[j] ^ in_ptr[j]; + out_ptr[j] = buf.b[j] ^ in_ptr[j]; } EVP_CIPHER_CTX_set_num(ctx, (int)j); } else { EVP_CIPHER_CTX_set_num(ctx, 0); } + memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), &ivb, sizeof (ivb)); + memcpy(EVP_CIPHER_CTX_buf_noconst(ctx), &buf, sizeof (buf)); return 1; } From 03e3cdf67c7bffb564d6e361436b6ace5611a14c Mon Sep 17 00:00:00 2001 From: Mikhail Labiuk Date: Thu, 16 Dec 2021 00:43:37 +0300 Subject: [PATCH 09/12] Fix align-cast for gost_grasshopper_cipher_do_cfb. --- gost_grasshopper_cipher.c | 45 +++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/gost_grasshopper_cipher.c b/gost_grasshopper_cipher.c index 828a7a48f..eb4e04e1c 100644 --- a/gost_grasshopper_cipher.c +++ b/gost_grasshopper_cipher.c @@ -655,29 +655,36 @@ static int gost_grasshopper_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *ou (gost_grasshopper_cipher_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx); const unsigned char *in_ptr = in; unsigned char *out_ptr = out; - unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx); - unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); + grasshopper_w128_t new_iv, bufb, ivb; bool encrypting = (bool) EVP_CIPHER_CTX_encrypting(ctx); int num = EVP_CIPHER_CTX_num(ctx); size_t i = 0; size_t j = 0; + memcpy(&bufb, EVP_CIPHER_CTX_buf_noconst(ctx), sizeof (bufb)); + memcpy(&ivb, EVP_CIPHER_CTX_iv_noconst(ctx), sizeof (ivb)); + /* process partial block if any */ if (num > 0) { + memcpy(&new_iv, + EVP_CIPHER_CTX_buf_noconst(ctx) + GRASSHOPPER_BLOCK_SIZE, num); + for (j = (size_t)num, i = 0; j < GRASSHOPPER_BLOCK_SIZE && i < inl; j++, i++, in_ptr++, out_ptr++) { if (!encrypting) { - buf[j + GRASSHOPPER_BLOCK_SIZE] = *in_ptr; + new_iv.b[j] = *in_ptr; } - *out_ptr = buf[j] ^ (*in_ptr); + *out_ptr = bufb.b[j] ^ (*in_ptr); if (encrypting) { - buf[j + GRASSHOPPER_BLOCK_SIZE] = *out_ptr; + new_iv.b[j] = *out_ptr; } } if (j == GRASSHOPPER_BLOCK_SIZE) { - memcpy(iv, buf + GRASSHOPPER_BLOCK_SIZE, GRASSHOPPER_BLOCK_SIZE); + ivb = new_iv; EVP_CIPHER_CTX_set_num(ctx, 0); } else { + memcpy(EVP_CIPHER_CTX_buf_noconst(ctx) + GRASSHOPPER_BLOCK_SIZE, + &new_iv, j); EVP_CIPHER_CTX_set_num(ctx, (int)j); return 1; } @@ -690,9 +697,7 @@ static int gost_grasshopper_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *ou /* * block cipher current iv */ - grasshopper_encrypt_block(&c->encrypt_round_keys, - (grasshopper_w128_t *) iv, - (grasshopper_w128_t *) buf, &c->buffer); + grasshopper_encrypt_block(&c->encrypt_round_keys, &ivb, &bufb, &c->buffer); /* * xor next block of input text with it and output it */ @@ -700,37 +705,41 @@ static int gost_grasshopper_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *ou * output this block */ if (!encrypting) { - memcpy(iv, in_ptr, GRASSHOPPER_BLOCK_SIZE); + memcpy(&ivb, in_ptr, GRASSHOPPER_BLOCK_SIZE); } for (j = 0; j < GRASSHOPPER_BLOCK_SIZE; j++) { - out_ptr[j] = buf[j] ^ in_ptr[j]; + out_ptr[j] = bufb.b[j] ^ in_ptr[j]; } /* Encrypt */ /* Next iv is next block of cipher text */ if (encrypting) { - memcpy(iv, out_ptr, GRASSHOPPER_BLOCK_SIZE); + memcpy(&ivb, out_ptr, GRASSHOPPER_BLOCK_SIZE); } } /* Process rest of buffer */ if (i < inl) { - grasshopper_encrypt_block(&c->encrypt_round_keys, - (grasshopper_w128_t *) iv, - (grasshopper_w128_t *) buf, &c->buffer); + grasshopper_encrypt_block(&c->encrypt_round_keys, &ivb, &bufb, &c->buffer); if (!encrypting) { - memcpy(buf + GRASSHOPPER_BLOCK_SIZE, in_ptr, inl - i); + memcpy(EVP_CIPHER_CTX_buf_noconst(ctx) + GRASSHOPPER_BLOCK_SIZE, + in_ptr, inl - i); } for (j = 0; i < inl; j++, i++) { - out_ptr[j] = buf[j] ^ in_ptr[j]; + out_ptr[j] = bufb.b[j] ^ in_ptr[j]; } EVP_CIPHER_CTX_set_num(ctx, (int)j); if (encrypting) { - memcpy(buf + GRASSHOPPER_BLOCK_SIZE, out_ptr, j); + memcpy(EVP_CIPHER_CTX_buf_noconst(ctx) + GRASSHOPPER_BLOCK_SIZE, + out_ptr, j); } + } else { EVP_CIPHER_CTX_set_num(ctx, 0); } + memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), &ivb, sizeof (ivb)); + memcpy(EVP_CIPHER_CTX_buf_noconst(ctx), &bufb, sizeof (bufb)); + return 1; } From 49d62ca638a3e58bde273a43c41ddb4f5288385a Mon Sep 17 00:00:00 2001 From: Mikhail Labiuk Date: Thu, 16 Dec 2021 13:54:17 +0300 Subject: [PATCH 10/12] Ensure data alignment for uint512_u. --- gosthash2012.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gosthash2012.h b/gosthash2012.h index 99c9e3d69..7f89d862f 100644 --- a/gosthash2012.h +++ b/gosthash2012.h @@ -55,8 +55,8 @@ ALIGN(16) typedef union uint512_u { - unsigned long long QWORD[8]; - unsigned char B[64]; + ALIGN(16) unsigned long long QWORD[8]; + unsigned char B[64]; } uint512_u; #include "gosthash2012_const.h" From 7499536071b10b715cab7e3955b300043f88dab8 Mon Sep 17 00:00:00 2001 From: Mikhail Labiuk Date: Thu, 16 Dec 2021 15:10:38 +0300 Subject: [PATCH 11/12] Fix align-cast for test_derive.c --- test_derive.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test_derive.c b/test_derive.c index c99ccef5a..6429e6fdd 100644 --- a/test_derive.c +++ b/test_derive.c @@ -118,6 +118,15 @@ struct test_derive { }, }; +static unsigned int +charbuf_to_uint(const char *b) +{ + return (b[3] << 24) + + (b[2] << 16) + + (b[1] << 8) + + b[0]; +} + static EVP_PKEY *load_private_key(int key_nid, int param_nid, const char *pk, const char *pub) { @@ -183,7 +192,7 @@ static EVP_PKEY *load_private_key(int key_nid, int param_nid, const char *pk, BN_free(y); if (EC_POINT_cmp(group, pkey, xy, bc) == 0) printf("Public key %08x matches private key %08x\n", - *(int *)pub, *(int *)pk); + charbuf_to_uint(pub), charbuf_to_uint(pk)); else { printf(cRED "Public key mismatch!" cNORM "\n"); exit(1); From 600af30d1fc7ec30faa1fdfe6d6af01307ca98ca Mon Sep 17 00:00:00 2001 From: Mikhail Labiuk Date: Thu, 16 Dec 2021 00:57:33 +0300 Subject: [PATCH 12/12] Add compilation option to emit warning about invalid cast-align. --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f46fca351..c4a30f67c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,12 +24,12 @@ if (CMAKE_C_COMPILER_ID MATCHES "Clang") set(CMAKE_C_FLAGS_RELEASE -O2) set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb") set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -ggdb") - add_compile_options(-Werror -Wall -Wno-unused-parameter -Wno-unused-function -Wno-missing-braces -Qunused-arguments -Wno-deprecated-declarations) + add_compile_options(-Werror -Wall -Wcast-align -Wno-unused-parameter -Wno-unused-function -Wno-missing-braces -Qunused-arguments -Wno-deprecated-declarations) elseif(CMAKE_C_COMPILER_ID MATCHES "GNU") set(CMAKE_C_FLAGS_RELEASE -O2) set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb") set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -ggdb") - add_compile_options(-Werror -Wall -Wno-unused-parameter -Wno-unused-function -Wno-missing-braces -Wno-error=unknown-pragmas -Wno-error=pragmas -Wno-deprecated-declarations) + add_compile_options(-Werror -Wall -Wcast-align -Wno-unused-parameter -Wno-unused-function -Wno-missing-braces -Wno-error=unknown-pragmas -Wno-error=pragmas -Wno-deprecated-declarations) elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC") add_definitions(-D_CRT_SECURE_NO_WARNINGS) add_definitions(-D_CRT_DEPRECATED_NO_WARNINGS)