Hi. As a first step towards fixing this, please find attached patch to add a script that re-generate mceliece6688128f.c from upstream libmceliece.
This should have been part of the first patch, but I cheated and manually modified the generated code to fix some issues. For that reason, this patch modify mceliece6688128f.c too. All of those changes should be no-ops and are to make the mceliece6688128f.sh script simpler. After applying this patch, you can reproduce the generated code: $ cd ~/src/libgcrypt/cipher $ wget -nv https://lib.mceliece.org/libmceliece-20230612.tar.gz $ tar xfa libmceliece-20230612.tar.gz $ ./mceliece6688128f.sh . > mceliece6688128f.c $ git diff Syncing the code with latest libmceliece was a bit more complicated than I thought so I think the right approach is to first get this patch in and later finish updating to latest libmceliece 20240726. That should fix the alignment issue and some other problems. The patch in this e-mail should go in first though, to have a good way to reproduce the existing code for auditing. What do you think? /Simon
From b67853bd716760f6e6ed06855454bd8387c4c0c0 Mon Sep 17 00:00:00 2001 From: Simon Josefsson <[email protected]> Date: Mon, 5 Aug 2024 08:11:02 +0200 Subject: [PATCH] cipher: Add script to re-generate mceliece6688128f.c. * cipher/mceliece6688128f.sh: Add. * cipher/mceliece6688128f.c: Regenerate from script. -- Signed-off-by: Simon Josefsson <[email protected]> --- cipher/mceliece6688128f.c | 124 ++++++++++-------- cipher/mceliece6688128f.sh | 250 +++++++++++++++++++++++++++++++++++++ 2 files changed, 324 insertions(+), 50 deletions(-) create mode 100755 cipher/mceliece6688128f.sh diff --git a/cipher/mceliece6688128f.c b/cipher/mceliece6688128f.c index 63d20a68..6ad3eecb 100644 --- a/cipher/mceliece6688128f.c +++ b/cipher/mceliece6688128f.c @@ -133,21 +133,25 @@ #include "g10lib.h" #include "mceliece6688128f.h" -#define int8 crypto_int8 -#define uint8 crypto_uint8 -#define int16 crypto_int16 -#define uint16 crypto_uint16 -#define int32 crypto_int32 -#define uint32 crypto_uint32 -#define int64 crypto_int64 -#define uint64 crypto_uint64 - static void randombytes (uint8_t *out, size_t outlen) { _gcry_randomize (out, outlen, GCRY_STRONG_RANDOM); } +static void crypto_xof_shake256(unsigned char *h,long long hlen, + const unsigned char *m,long long mlen) +{ + gcry_md_hd_t mdh; + gcry_err_code_t ec; + + ec = _gcry_md_open (&mdh, GCRY_MD_SHAKE256, 0); + if (ec) + log_fatal ("internal md_open failed: %d\n", ec); + _gcry_md_write (mdh, m, mlen); + _gcry_md_extract (mdh, GCRY_MD_SHAKE256, h, hlen); + _gcry_md_close (mdh); +} /* from libmceliece-20230612/include-build/crypto_declassify.h */ #ifndef crypto_declassify_h #define crypto_declassify_h @@ -952,7 +956,7 @@ static inline uint64_t gf_mul2(gf a, gf b0, gf b1) mask += mask; } - /**/ + /* */ t = tmp & 0x01FF000001FF0000; tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); @@ -1024,13 +1028,13 @@ static void int32_sort(int32_t *x,long long n) #define OPERATIONS_H -static void operation_enc( +static int operation_enc( unsigned char *c, unsigned char *key, const unsigned char *pk ); -static void operation_dec( +static int operation_dec( unsigned char *key, const unsigned char *c, const unsigned char *sk @@ -1310,20 +1314,6 @@ static inline uint64_t load8(const unsigned char * in) #endif -static void crypto_xof_shake256(unsigned char *h,long long hlen, - const unsigned char *m,long long mlen) -{ - gcry_md_hd_t mdh; - gcry_err_code_t ec; - - ec = _gcry_md_open (&mdh, GCRY_MD_SHAKE256, 0); - if (ec) - log_fatal ("internal md_open failed: %d\n", ec); - _gcry_md_write (mdh, m, mlen); - _gcry_md_extract (mdh, GCRY_MD_SHAKE256, h, hlen); - _gcry_md_close (mdh); -} - /* from libmceliece-20230612/crypto_kem/6688128f/vec/benes.c */ /* This file is for Benes network related functions @@ -1396,7 +1386,7 @@ static void benes(vec * r, const unsigned char * bits, int rev) uint64_t b_int_v[64]; uint64_t b_int_h[64]; - /**/ + /* */ if (rev) { bits_ptr = bits + 12288; inc = -1024; } else { bits_ptr = bits; inc = 0; } @@ -1676,7 +1666,7 @@ static void bm(vec out[][ GFBITS ], vec in[][ GFBITS ]) b = 1; L = 0; - /**/ + /* */ for (i = 0; i < GFBITS; i++) interval[0][i] = interval[1][i] = 0; @@ -1973,7 +1963,7 @@ static void scaling(vec out[][GFBITS], vec inv[][GFBITS], const unsigned char *s vec eval[128][ GFBITS ]; vec tmp[ GFBITS ]; - /**/ + /* */ irr_load(irr_int, sk); @@ -1997,7 +1987,7 @@ static void scaling(vec out[][GFBITS], vec inv[][GFBITS], const unsigned char *s vec_copy(inv[0], tmp); - /**/ + /* */ for (i = 0; i < 128; i++) for (j = 0; j < GFBITS; j++) @@ -2123,7 +2113,7 @@ static int decrypt(unsigned char *e, const unsigned char *sk, const unsigned cha check_synd = synd_cmp(s_priv, s_priv_cmp); - /**/ + /* */ benes(error, sk + IRR_BYTES, 0); @@ -2257,7 +2247,7 @@ static void syndrome(unsigned char *s, const unsigned char *pk, unsigned char *e int i, j; - /**/ + /* */ for (i = 0; i < SYND_BYTES; i++) s[i] = e[i]; @@ -2432,7 +2422,7 @@ static void butterflies(vec out[][ GFBITS ], vec in[][ GFBITS ]) const uint16_t beta[7] = {2522, 7827, 7801, 8035, 6897, 8167, 3476}; - /**/ + /* */ for (i = 0; i < 7; i++) { @@ -2588,7 +2578,7 @@ static void radix_conversions_tr(vec in[][ GFBITS ]) {0xFFFFFFFF00000000, 0x00000000FFFFFFFF} }; - /**/ + /* */ for (j = 6; j >= 0; j--) { @@ -2660,7 +2650,7 @@ static void butterflies_tr(vec out[][ GFBITS ], vec in[][ GFBITS ]) const uint16_t beta[6] = {5246, 5306, 6039, 6685, 4905, 6755}; - /**/ + /* */ for (i = 6; i >= 0; i--) { @@ -2813,7 +2803,7 @@ gf gf_mul(gf in0, gf in1) for (i = 1; i < GFBITS; i++) tmp ^= (t0 * (t1 & (1 << i))); - /**/ + /* */ t = tmp & 0x1FF0000; tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); @@ -2981,7 +2971,7 @@ static void GF_mul(gf *out, const gf *in0, const gf *in1) for (j = 0; j < 128; j++) prod[i+j] ^= gf_mul(in0[i], in1[j]); - /**/ + /* */ for (i = 254; i >= 128; i--) { @@ -3006,7 +2996,7 @@ static void GF_mul(gf *out, const gf *in0, const gf *in1) -static void operation_dec( +static int operation_dec( unsigned char *key, const unsigned char *c, const unsigned char *sk @@ -3023,7 +3013,7 @@ static void operation_dec( unsigned char *x = preimage; const unsigned char *s = sk + 40 + IRR_BYTES + COND_BYTES; - /**/ + /* */ ret_decrypt = decrypt(e, sk + 40, c); @@ -3039,6 +3029,8 @@ static void operation_dec( *x++ = c[i]; crypto_hash_32b(key, preimage, sizeof(preimage)); + + return 0; } @@ -3053,7 +3045,7 @@ static void operation_dec( -static void operation_enc( +static int operation_enc( unsigned char *c, unsigned char *key, const unsigned char *pk @@ -3062,7 +3054,7 @@ static void operation_enc( unsigned char e[ SYS_N/8 ]; unsigned char one_ec[ 1 + SYS_N/8 + SYND_BYTES ] = {1}; - /**/ + /* */ pke_encrypt(c, pk, e); @@ -3070,6 +3062,8 @@ static void operation_enc( memcpy(one_ec + 1 + SYS_N/8, c, SYND_BYTES); crypto_hash_32b(key, one_ec, sizeof(one_ec)); + + return 0; } @@ -3420,7 +3414,7 @@ static int pk_gen(unsigned char * pk, const unsigned char * irr, uint32_t * perm mat[ row ][ c ] ^= mat[ k ][ c ] & mask; } - if ( uint64_is_zero_declassify((mat[ row ][ i ] >> j) & 1) ) /* return if not systematic */ + if ( uint64_is_zero_declassify((mat[ row ][ i ] >> j) & 1) ) /* return if not systematic */ { return -1; } @@ -3459,7 +3453,7 @@ static int pk_gen(unsigned char * pk, const unsigned char * irr, uint32_t * perm pk += PK_ROW_BYTES % 8; } - /**/ + /* */ return 0; } @@ -3644,30 +3638,60 @@ static void vec_inv(vec * out, vec * in) /* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_dec.c */ +static int crypto_kem_dec( + unsigned char *key, + const unsigned char *c, + const unsigned char *sk +) +{ + return operation_dec(key,c,sk); +} + +/* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_enc.c */ + +static int crypto_kem_enc( + unsigned char *c, + unsigned char *key, + const unsigned char *pk +) +{ + return operation_enc(c,key,pk); +} + +/* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_keypair.c */ + +static void crypto_kem_keypair +( + unsigned char *pk, + unsigned char *sk +) +{ + operation_keypair(pk,sk); +} + + +/* libgcrypt wrapper */ + void mceliece6688128f_dec(uint8_t *key, const uint8_t *c, const uint8_t *sk) { - operation_dec((unsigned char*) key, + crypto_kem_dec((unsigned char*) key, (unsigned char*) c, (unsigned char*) sk); } -/* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_enc.c */ - void mceliece6688128f_enc(uint8_t *c, uint8_t *key, const uint8_t *pk) { - operation_enc((unsigned char*) c, + crypto_kem_enc((unsigned char*) c, (unsigned char*) key, (unsigned char*) pk); } -/* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_keypair.c */ - void mceliece6688128f_keypair(uint8_t *pk, uint8_t *sk) { - operation_keypair((unsigned char*) pk, (unsigned char*) sk); + crypto_kem_keypair((unsigned char*) pk, (unsigned char*) sk); } diff --git a/cipher/mceliece6688128f.sh b/cipher/mceliece6688128f.sh new file mode 100755 index 00000000..84245432 --- /dev/null +++ b/cipher/mceliece6688128f.sh @@ -0,0 +1,250 @@ +#!/bin/sh + +# mceliece6688128f.sh - Classic McEliece libmceliece->libgcrypt converter + +# Based upon the public domain mceliece6688128f.sh from my merge +# request for Classic McEliece in OpenSSH, which in turn is based on +# the public domain OpenSSH sntrup761.sh script. + +# Copyright (C) 2023-2024 Simon Josefsson <[email protected]> +# +# This file is part of Libgcrypt. +# +# Libgcrypt is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of +# the License, or (at your option) any later version. +# +# Libgcrypt is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, see <https://www.gnu.org/licenses/>. +# SPDX-License-Identifier: LGPL-2.1-or-later + +LICENSE="libmceliece-20230612/doc/license.md" +PEOPLE="libmceliece-20230612/doc/people.md" +FILES=" libmceliece-20230612/include-build/crypto_declassify.h + libmceliece-20230612/crypto_kem/6688128f/vec/params.h + libmceliece-20230612/inttypes/crypto_intN.h + libmceliece-20230612/inttypes/crypto_intN.h + libmceliece-20230612/inttypes/crypto_intN.h + libmceliece-20230612/inttypes/crypto_uintN.h + libmceliece-20230612/inttypes/crypto_uintN.h + libmceliece-20230612/inttypes/crypto_uintN.h + libmceliece-20230612/crypto_kem/6688128f/vec/vec.h + libmceliece-20230612/crypto_kem/6688128f/vec/benes.h + libmceliece-20230612/crypto_kem/6688128f/vec/bm.h + libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.h + libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.h + libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.h + libmceliece-20230612/crypto_kem/6688128f/vec/fft_consts.h + libmceliece-20230612/crypto_kem/6688128f/vec/fft.h + libmceliece-20230612/crypto_kem/6688128f/vec/fft_powers.h + libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_2x.h + libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_4x.h + libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.h + libmceliece-20230612/crypto_kem/6688128f/vec/gf.h + libmceliece-20230612/crypto_kem/6688128f/vec/hash.h + libmceliece-20230612/crypto_kem/6688128f/vec/int32_sort.h + libmceliece-20230612/crypto_kem/6688128f/vec/operations.h + libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.h + libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.h + libmceliece-20230612/crypto_kem/6688128f/vec/transpose.h + libmceliece-20230612/crypto_kem/6688128f/vec/uint16_sort.h + libmceliece-20230612/crypto_kem/6688128f/vec/uint64_sort.h + libmceliece-20230612/crypto_kem/6688128f/vec/util.h + libmceliece-20230612/crypto_kem/6688128f/vec/benes.c + libmceliece-20230612/crypto_kem/6688128f/vec/bm.c + libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.c + libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.c + libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.c + libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_consts.c + libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_powers.c + libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_2x.c + libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_4x.c + libmceliece-20230612/crypto_kem/6688128f/vec/fft.c + libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.c + libmceliece-20230612/crypto_kem/6688128f/vec/gf.c + libmceliece-20230612/crypto_kem/6688128f/vec/kem_dec.c + libmceliece-20230612/crypto_kem/6688128f/vec/kem_enc.c + libmceliece-20230612/crypto_kem/6688128f/vec/kem_keypair.c + libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.c + libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.c + libmceliece-20230612/crypto_kem/6688128f/vec/vec.c + libmceliece-20230612/crypto_kem/6688128f/vec/wrap_dec.c + libmceliece-20230612/crypto_kem/6688128f/vec/wrap_enc.c + libmceliece-20230612/crypto_kem/6688128f/vec/wrap_keypair.c" +### + +set -e +cd $1 +echo '/* mceliece6688128f.c - Classic McEliece for libgcrypt' +echo ' * Copyright (C) 2023-2024 Simon Josefsson <[email protected]>' +echo ' *' +echo ' * This file is part of Libgcrypt.' +echo ' *' +echo ' * Libgcrypt is free software; you can redistribute it and/or modify' +echo ' * it under the terms of the GNU Lesser General Public License as' +echo ' * published by the Free Software Foundation; either version 2.1 of' +echo ' * the License, or (at your option) any later version.' +echo ' *' +echo ' * Libgcrypt is distributed in the hope that it will be useful,' +echo ' * but WITHOUT ANY WARRANTY; without even the implied warranty of' +echo ' * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the' +echo ' * GNU Lesser General Public License for more details.' +echo ' *' +echo ' * You should have received a copy of the GNU Lesser General Public' +echo ' * License along with this program; if not, see <https://www.gnu.org/licenses/>.' +echo ' * SPDX-License-Identifier: LGPL-2.1-or-later' +echo ' *' +echo ' */' +echo '' +echo '/* This file is extracted from libmceliece. */' +echo +echo '/*' +sed -e 's/^/ * /' < $LICENSE | sed -e 's/ $//' +echo ' *' +sed -e 's/^/ * /' < $PEOPLE \ + | grep -v \ + -e 'The underlying `crypto_xof/shake256` software currently includes two' \ + -e 'SHAKE256 implementations. The `tweet` implementation is based on' \ + -e '\[https://twitter.com/tweetfips202\](https://twitter.com/tweetfips202)' \ + -e 'by Daniel J. Bernstein, Peter Schwabe, and Gilles Van Assche. The' \ + -e '`unrollround` implementation is from Daniel J. Bernstein.' \ + | sed -e 's/ $//' +echo ' * This file is generated by mceliece6688128f.sh from these files:' +echo ' *' +echo "$FILES" | sed -e 's/\t/ * /' +echo ' *' +echo ' */' +echo +echo '#ifdef HAVE_CONFIG_H' +echo '#include <config.h>' +echo '#endif' +echo +echo '#include "g10lib.h"' +echo '#include "mceliece6688128f.h"' +echo +cat<<EOF +static void +randombytes (uint8_t *out, size_t outlen) +{ + _gcry_randomize (out, outlen, GCRY_STRONG_RANDOM); +} + +static void crypto_xof_shake256(unsigned char *h,long long hlen, + const unsigned char *m,long long mlen) +{ + gcry_md_hd_t mdh; + gcry_err_code_t ec; + + ec = _gcry_md_open (&mdh, GCRY_MD_SHAKE256, 0); + if (ec) + log_fatal ("internal md_open failed: %d\n", ec); + _gcry_md_write (mdh, m, mlen); + _gcry_md_extract (mdh, GCRY_MD_SHAKE256, h, hlen); + _gcry_md_close (mdh); +} +EOF +N=16 +for i in $FILES; do + echo "/* from $i */" + # Changes to all files: + # - remove all includes, we inline everything required. + # - make functions not required elsewhere static. + # - rename the functions we do use. + # - remove unnecessary defines and externs. + sed -e "/#include/d" \ + -e "s/{ ; }/{\n (void) crypto_declassify_v;\n (void) crypto_declassify_vlen;\n}/" \ + -e "s/^void /static void /g" \ + -e "s/^int /static int /g" \ + -e "s/^int16 /static int16 /g" \ + -e "s/^uint16 /static uint16 /g" \ + -e "/^extern /d" \ + -e "/perm_check/d" \ + -e '/CRYPTO_NAMESPACE/d' \ + -e '/CRYPTO_SHARED_NAMESPACE/d' \ + -e 's/[ ]*$//' \ + $i | \ + case "$i" in + # Use int64_t for intermediate values in int32_MINMAX to prevent signed + # 32-bit integer overflow when called by crypto_sort_uint32. + */int32_sort.h) + sed -e "s/int32_t ab = b ^ a/int64_t ab = (int64_t)b ^ (int64_t)a/" \ + -e "s/int32_t c = b - a/int64_t c = (int64_t)b - (int64_t)a/" + ;; + # Silence false-alarm gcc warning about unitialized variable. + */kem_keypair.c) + sed -e "s/uint64_t pivots;/uint64_t pivots = 0;/" + ;; + # This file clobbers namespace for one-letter variable names, and + # overloads 'x' (of the same type!) within the same function. + */controlbits.c) + cat | sed \ + -e "s,long long x = 2\*j;,long long lx = 2*j;," \ + -e "s,int32 fj = B\[x\]\&1; /\* f\[j\] \*/,int32 fj = B[lx]\&1; /* f[j] */,g" \ + -e "s,int32 Fx = x+fj; /\* F\[x\] \*/,int32 Fx = lx+fj; /* F[x] */,g" \ + -e "s,B\[x\] = (A\[x\]<<16)|Fx;,B[lx] = (A[lx]<<16)|Fx;,g" \ + -e "s,B\[x+1\] = (A\[x+1\]<<16)|Fx1;,B[lx+1] = (A[lx+1]<<16)|Fx1;,g" + echo '#undef A' + echo '#undef B' + echo '#undef q' + ;; + # Poor-man's #include now that we removed all #include's above. + */shared-fft_*.c) + INC=$(echo $i | sed -e "s,/shared-fft_,/," -e "s,.c$,.data,") + DATA=$(echo $(cat $INC)) + sed -e "s/};/$DATA\n};/" + ;; + # Create three different versions of file depending on N. + */crypto_*intN.h) + sed -e "s/N/$N/g" + ;; + # Default: pass through. + *) + cat + ;; + esac | \ + sed -e "s/__attribute__((unused))/GCC_ATTR_UNUSED/g" \ + -e "s,^\([ \t]*\)//\(.*\)[ \t]*$,\1/*\2 */," \ + -e "s,\([ \t]\+\)//\(.*\)[ \t]*$,\1/*\2 */," + echo + if test "$N" = 16; then + N=32 + elif test "$N" = 32; then + N=64 + elif test "$N" = 64; then + N=16 + fi +done +cat<<EOF + +/* libgcrypt wrapper */ + +void mceliece6688128f_dec(uint8_t *key, + const uint8_t *c, + const uint8_t *sk) +{ + crypto_kem_dec((unsigned char*) key, + (unsigned char*) c, + (unsigned char*) sk); +} + +void mceliece6688128f_enc(uint8_t *c, + uint8_t *key, + const uint8_t *pk) +{ + crypto_kem_enc((unsigned char*) c, + (unsigned char*) key, + (unsigned char*) pk); +} + +void mceliece6688128f_keypair(uint8_t *pk, + uint8_t *sk) +{ + crypto_kem_keypair((unsigned char*) pk, (unsigned char*) sk); +} +EOF -- 2.45.2
signature.asc
Description: PGP signature
_______________________________________________ Gcrypt-devel mailing list [email protected] https://lists.gnupg.org/mailman/listinfo/gcrypt-devel
