summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Serbinenko <phcoder@gmail.com>2013-04-18 13:22:34 +0200
committerWerner Koch <wk@gnupg.org>2013-04-18 13:25:59 +0200
commit8eab66ad6852ec985bfb1e7fec35981d5e31148a (patch)
tree2049dc255846e9c67653ef07262679d98100e392
parentcc2f85116226bf9e2b77c4949eb1e7ea2357f67d (diff)
downloadlibgcrypt-8eab66ad6852ec985bfb1e7fec35981d5e31148a.tar.gz
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 <wk@gnupg.org>
-rw-r--r--AUTHORS5
-rw-r--r--cipher/serpent.c87
2 files changed, 36 insertions, 56 deletions
diff --git a/AUTHORS b/AUTHORS
index b7c1800d..5eab32a7 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -98,6 +98,11 @@ Assigns Past and Future Changes
openpgp@brainhub.org
(cipher/ecc.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)
{