Hello,

The Classic McEliece implementation assumes that unaligned access for
64-bit and 32-bit are OK.  It is not the case for some architectures.

Here is a patch to point out the issue.  Better patch is welcome.

-- 

diff --git a/cipher/mceliece6688128f.c b/cipher/mceliece6688128f.c
index 63d20a68..fc8f921c 100644
--- a/cipher/mceliece6688128f.c
+++ b/cipher/mceliece6688128f.c
@@ -841,7 +841,7 @@ static int decrypt(unsigned char *, const unsigned char *, 
const unsigned char *
 #ifndef ENCRYPT_H
 #define ENCRYPT_H
 
-static void pke_encrypt(unsigned char *, const unsigned char *, unsigned char 
*);
+static void pke_encrypt(unsigned char *, const unsigned char *, uint64_t *);
 
 #endif
 
@@ -2248,12 +2248,12 @@ static void gen_e(unsigned char *e)
 
 /* input: public key pk, error vector e */
 /* output: syndrome s */
-static void syndrome(unsigned char *s, const unsigned char *pk, unsigned char 
*e)
+static void syndrome(unsigned char *s, const unsigned char *pk, const uint64_t 
*e_aligned)
 {
+       const unsigned char *e = (const unsigned char *)e_aligned;
        uint64_t b;
 
-       const uint64_t *pk_ptr;
-       const uint64_t *e_ptr = ((uint64_t *) (e + SYND_BYTES));
+       const uint64_t *e_ptr = (e_aligned + SYND_BYTES/8);
 
        int i, j;
 
@@ -2264,13 +2264,19 @@ static void syndrome(unsigned char *s, const unsigned 
char *pk, unsigned char *e
 
        for (i = 0; i < PK_NROWS; i++)
        {
-               pk_ptr = ((uint64_t *) (pk + PK_ROW_BYTES * i));
+               const unsigned char *pk_ptr = pk + PK_ROW_BYTES * i;
+               uint64_t v64;
+               uint32_t v32;
 
                b = 0;
                for (j = 0; j < PK_NCOLS/64; j++)
-                       b ^= pk_ptr[j] & e_ptr[j];
+               {
+                       v64 = buf_get_he64 (pk_ptr + j * 8);
+                       b ^= v64 & e_ptr[j];
+                }
 
-               b ^= ((uint32_t *) &pk_ptr[j])[0] & ((uint32_t *) &e_ptr[j])[0];
+               v32 = buf_get_he32 (pk_ptr + j * 8);
+               b ^= v32 & ((uint32_t *) &e_ptr[j])[0];
 
                b ^= b >> 32;
                b ^= b >> 16;
@@ -2286,8 +2292,10 @@ static void syndrome(unsigned char *s, const unsigned 
char *pk, unsigned char *e
 
 /* input: public key pk */
 /* output: error vector e, syndrome s */
-static void pke_encrypt(unsigned char *s, const unsigned char *pk, unsigned 
char *e)
+static void pke_encrypt(unsigned char *s, const unsigned char *pk, uint64_t 
*e_aligned)
 {
+       unsigned char *e = (unsigned char *)e_aligned;
+
        gen_e(e);
 
 #ifdef KAT
@@ -2301,7 +2309,7 @@ static void pke_encrypt(unsigned char *s, const unsigned 
char *pk, unsigned char
   }
 #endif
 
-       syndrome(s, pk, e);
+       syndrome(s, pk, e_aligned);
 }
 
 
@@ -3059,12 +3067,13 @@ static void operation_enc(
        const unsigned char *pk
 )
 {
-       unsigned char e[ SYS_N/8 ];
+       uint64_t e_aligned[ (SYS_N+63)/64 ];
+       unsigned char *e = (unsigned char *)e_aligned;
        unsigned char one_ec[ 1 + SYS_N/8 + SYND_BYTES ] = {1};
 
        /**/
 
-       pke_encrypt(c, pk, e);
+       pke_encrypt(c, pk, e_aligned);
 
        memcpy(one_ec + 1, e, SYS_N/8);
        memcpy(one_ec + 1 + SYS_N/8, c, SYND_BYTES);
diff --git a/cipher/mceliece6688128f.h b/cipher/mceliece6688128f.h
index eb9f23a0..05ecac32 100644
--- a/cipher/mceliece6688128f.h
+++ b/cipher/mceliece6688128f.h
@@ -29,6 +29,7 @@
 /**** Start of the glue code to libgcrypt ****/
 #include "g10lib.h"             /* for GCC_ATTR_UNUSED */
 #include "gcrypt-int.h"
+#include "bufhelp.h"
 
 #define mceliece6688128f_keypair _gcry_mceliece6688128f_keypair
 #define mceliece6688128f_enc     _gcry_mceliece6688128f_enc
@@ -41,6 +42,8 @@
 #define GCC_ATTR_UNUSED
 #endif
 
+/* Please implement Host-endian get macros: buf_get_he32 and buf_get_he64 */
+
 #define MCELIECE6688128F_SECRETKEY_SIZE 13932
 #define MCELIECE6688128F_PUBLICKEY_SIZE 1044992
 #define MCELIECE6688128F_CIPHERTEXT_SIZE 208

_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel@gnupg.org
https://lists.gnupg.org/mailman/listinfo/gcrypt-devel

Reply via email to