From 86e72b490a5790a9c23341067c7e4d3e38be1634 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Thu, 18 Apr 2013 13:22:34 +0200 Subject: Fix alignment problem in serpent.c. * cipher/serpent.c (serpent_key_prepare): Fix misaligned access. (serpent_setkey): Likewise. (serpent_encrypt_internal): Likewise. (serpent_decrypt_internal): Likewise. (serpent_encrypt): Don't put an alignment-increasing cast. (serpent_decrypt): Likewise. (serpent_test): Likewise. -- This is a port of the fix for the Libgcrypt code in GRUB: http://bzr.savannah.gnu.org/lh/grub/trunk/grub/revision/3685 GRUB is FSF copyrighted and thus we can use this code without a DCO. Note that the above fix was not correct and failed the selftests, thus I fixed this fix. GnuPG-bug-id: 1384 Signed-off-by: Werner Koch (cherry picked from commit 8eab66ad6852ec985bfb1e7fec35981d5e31148a) --- AUTHORS | 5 ++++ cipher/serpent.c | 87 ++++++++++++++++++++------------------------------------ 2 files changed, 36 insertions(+), 56 deletions(-) diff --git a/AUTHORS b/AUTHORS index 5c75b3c2..a7a8f3f2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -103,6 +103,11 @@ Assigns Past and Future Changes ulm@gentoo.org (Changes to cipher/idea.c and related files) +LIBGCRYPT Vladimir Serbinenko 2012-04-26 +Assigns Past and Future Changes +phcoder@gmail.com +(cipher/serpent.c) + Authors with a DCO ================== diff --git a/cipher/serpent.c b/cipher/serpent.c index a78e018a..ea14c7ec 100644 --- a/cipher/serpent.c +++ b/cipher/serpent.c @@ -585,15 +585,14 @@ serpent_key_prepare (const byte *key, unsigned int key_length, int i; /* Copy key. */ - for (i = 0; i < key_length / 4; i++) - { + memcpy (key_prepared, key, key_length); + key_length /= 4; #ifdef WORDS_BIGENDIAN - key_prepared[i] = byte_swap_32 (((u32 *) key)[i]); + for (i = 0; i < key_length; i++) + key_prepared[i] = byte_swap_32 (key_prepared[i]); #else - key_prepared[i] = ((u32 *) key)[i]; + i = key_length; #endif - } - if (i < 8) { /* Key must be padded according to the Serpent @@ -707,21 +706,17 @@ serpent_setkey (void *ctx, static void serpent_encrypt_internal (serpent_context_t *context, - const serpent_block_t input, serpent_block_t output) + const byte *input, byte *output) { serpent_block_t b, b_next; int round = 0; + memcpy (b, input, sizeof (b)); #ifdef WORDS_BIGENDIAN - b[0] = byte_swap_32 (input[0]); - b[1] = byte_swap_32 (input[1]); - b[2] = byte_swap_32 (input[2]); - b[3] = byte_swap_32 (input[3]); -#else - b[0] = input[0]; - b[1] = input[1]; - b[2] = input[2]; - b[3] = input[3]; + b[0] = byte_swap_32 (b[0]); + b[1] = byte_swap_32 (b[1]); + b[2] = byte_swap_32 (b[2]); + b[3] = byte_swap_32 (b[3]); #endif ROUND (0, context->keys, b, b_next); @@ -759,35 +754,27 @@ serpent_encrypt_internal (serpent_context_t *context, ROUND_LAST (7, context->keys, b, b_next); #ifdef WORDS_BIGENDIAN - output[0] = byte_swap_32 (b_next[0]); - output[1] = byte_swap_32 (b_next[1]); - output[2] = byte_swap_32 (b_next[2]); - output[3] = byte_swap_32 (b_next[3]); -#else - output[0] = b_next[0]; - output[1] = b_next[1]; - output[2] = b_next[2]; - output[3] = b_next[3]; + b_next[0] = byte_swap_32 (b_next[0]); + b_next[1] = byte_swap_32 (b_next[1]); + b_next[2] = byte_swap_32 (b_next[2]); + b_next[3] = byte_swap_32 (b_next[3]); #endif + memcpy (output, b_next, sizeof (b_next)); } static void serpent_decrypt_internal (serpent_context_t *context, - const serpent_block_t input, serpent_block_t output) + const byte *input, byte *output) { serpent_block_t b, b_next; int round = ROUNDS; + memcpy (b_next, input, sizeof (b)); #ifdef WORDS_BIGENDIAN - b_next[0] = byte_swap_32 (input[0]); - b_next[1] = byte_swap_32 (input[1]); - b_next[2] = byte_swap_32 (input[2]); - b_next[3] = byte_swap_32 (input[3]); -#else - b_next[0] = input[0]; - b_next[1] = input[1]; - b_next[2] = input[2]; - b_next[3] = input[3]; + b_next[0] = byte_swap_32 (b_next[0]); + b_next[1] = byte_swap_32 (b_next[1]); + b_next[2] = byte_swap_32 (b_next[2]); + b_next[3] = byte_swap_32 (b_next[3]); #endif ROUND_FIRST_INVERSE (7, context->keys, b_next, b); @@ -824,18 +811,13 @@ serpent_decrypt_internal (serpent_context_t *context, ROUND_INVERSE (1, context->keys, b, b_next); ROUND_INVERSE (0, context->keys, b, b_next); - #ifdef WORDS_BIGENDIAN - output[0] = byte_swap_32 (b_next[0]); - output[1] = byte_swap_32 (b_next[1]); - output[2] = byte_swap_32 (b_next[2]); - output[3] = byte_swap_32 (b_next[3]); -#else - output[0] = b_next[0]; - output[1] = b_next[1]; - output[2] = b_next[2]; - output[3] = b_next[3]; + b_next[0] = byte_swap_32 (b_next[0]); + b_next[1] = byte_swap_32 (b_next[1]); + b_next[2] = byte_swap_32 (b_next[2]); + b_next[3] = byte_swap_32 (b_next[3]); #endif + memcpy (output, b_next, sizeof (b_next)); } static void @@ -843,8 +825,7 @@ serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in) { serpent_context_t *context = ctx; - serpent_encrypt_internal (context, - (const u32 *) buffer_in, (u32 *) buffer_out); + serpent_encrypt_internal (context, buffer_in, buffer_out); _gcry_burn_stack (2 * sizeof (serpent_block_t)); } @@ -853,9 +834,7 @@ serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in) { serpent_context_t *context = ctx; - serpent_decrypt_internal (context, - (const u32 *) buffer_in, - (u32 *) buffer_out); + serpent_decrypt_internal (context, buffer_in, buffer_out); _gcry_burn_stack (2 * sizeof (serpent_block_t)); } @@ -914,9 +893,7 @@ serpent_test (void) { serpent_setkey_internal (&context, test_data[i].key, test_data[i].key_length); - serpent_encrypt_internal (&context, - (const u32 *) test_data[i].text_plain, - (u32 *) scratch); + serpent_encrypt_internal (&context, test_data[i].text_plain, scratch); if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t))) switch (test_data[i].key_length) @@ -929,9 +906,7 @@ serpent_test (void) return "Serpent-256 test encryption failed."; } - serpent_decrypt_internal (&context, - (const u32 *) test_data[i].text_cipher, - (u32 *) scratch); + serpent_decrypt_internal (&context, test_data[i].text_cipher, scratch); if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t))) switch (test_data[i].key_length) { -- cgit v1.2.1