diff --git a/crypto_kem/ledakemlt12/leaktime/Makefile b/crypto_kem/ledakemlt12/leaktime/Makefile index 32e38b8e..8948dfcf 100644 --- a/crypto_kem/ledakemlt12/leaktime/Makefile +++ b/crypto_kem/ledakemlt12/leaktime/Makefile @@ -3,10 +3,10 @@ LIB=libledakemlt12_leaktime.a HEADERS=api.h bf_decoding.h dfr_test.h gf2x_arith_mod_xPplusOne.h \ gf2x_arith.h H_Q_matrices_generation.h \ - niederreiter.h qc_ldpc_parameters.h rng.h sort.h + niederreiter.h qc_ldpc_parameters.h rng.h sort.h utils.h OBJECTS=bf_decoding.o dfr_test.o gf2x_arith_mod_xPplusOne.o \ - gf2x_arith.o H_Q_matrices_generation.o kem.o niederreiter.o rng.o sort.o + gf2x_arith.o H_Q_matrices_generation.o kem.o niederreiter.o rng.o sort.o utils.o CFLAGS=-O3 -Wall -Werror -Wextra -Wvla -Wpedantic -Wmissing-prototypes -std=c99 \ -I../../../common $(EXTRAFLAGS) diff --git a/crypto_kem/ledakemlt12/leaktime/Makefile.Microsoft_nmake b/crypto_kem/ledakemlt12/leaktime/Makefile.Microsoft_nmake index 5915e0b5..abcc7815 100644 --- a/crypto_kem/ledakemlt12/leaktime/Makefile.Microsoft_nmake +++ b/crypto_kem/ledakemlt12/leaktime/Makefile.Microsoft_nmake @@ -2,7 +2,7 @@ # nmake /f Makefile.Microsoft_nmake LIBRARY=libledakemlt12_leaktime.lib -OBJECTS=bf_decoding.obj dfr_test.obj gf2x_arith_mod_xPplusOne.obj gf2x_arith.obj H_Q_matrices_generation.obj kem.obj niederreiter.obj rng.obj sort.obj +OBJECTS=bf_decoding.obj dfr_test.obj gf2x_arith_mod_xPplusOne.obj gf2x_arith.obj H_Q_matrices_generation.obj kem.obj niederreiter.obj rng.obj sort.obj utils.obj CFLAGS=/nologo /I ..\..\..\common /W4 /WX diff --git a/crypto_kem/ledakemlt12/leaktime/kem.c b/crypto_kem/ledakemlt12/leaktime/kem.c index 85958986..f7dfa58f 100644 --- a/crypto_kem/ledakemlt12/leaktime/kem.c +++ b/crypto_kem/ledakemlt12/leaktime/kem.c @@ -2,6 +2,7 @@ #include "niederreiter.h" #include "randombytes.h" #include "rng.h" +#include "utils.h" #include @@ -128,20 +129,19 @@ int PQCLEAN_LEDAKEMLT12_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, PQCLEAN_LEDAKEMLT12_LEAKTIME_expand_error(reconstructed_error_vector, reconstructed_errorPos); - int equal = (0 == memcmp((const uint8_t *) decoded_error_vector, - (const uint8_t *) reconstructed_error_vector, - N0 * NUM_DIGITS_GF2X_ELEMENT)); - // equal == 1, if the reconstructed error vector match !!! + int equal = PQCLEAN_LEDAKEMLT12_LEAKTIME_gf2x_verify(decoded_error_vector, reconstructed_error_vector, N0 * NUM_DIGITS_GF2X_ELEMENT); + // equal == 0, if the reconstructed error vector match !!! - int decryptOk = (decode_ok == 1 && equal == 1); + int decryptOk = (decode_ok == 1 && equal == 0); memcpy(ss_input, decoded_seed, TRNG_BYTE_LENGTH); + memcpy(ss_input + sizeof(decoded_seed), tail, TRNG_BYTE_LENGTH); - if (decryptOk == 1) { - memcpy(ss_input + sizeof(decoded_seed), tail, TRNG_BYTE_LENGTH); - } else { // decryption failure - memcpy(ss_input + sizeof(decoded_seed), ((const privateKeyNiederreiter_t *)sk)->decryption_failure_secret, TRNG_BYTE_LENGTH); - } + // Overwrite on failure + PQCLEAN_LEDAKEMLT12_LEAKTIME_cmov(ss_input + sizeof(decoded_seed), + ((const privateKeyNiederreiter_t *) sk)->decryption_failure_secret, + TRNG_BYTE_LENGTH, + !decryptOk); HASH_FUNCTION(ss, ss_input, 2 * TRNG_BYTE_LENGTH); diff --git a/crypto_kem/ledakemlt12/leaktime/niederreiter.c b/crypto_kem/ledakemlt12/leaktime/niederreiter.c index 2eb712c7..0e7173f6 100644 --- a/crypto_kem/ledakemlt12/leaktime/niederreiter.c +++ b/crypto_kem/ledakemlt12/leaktime/niederreiter.c @@ -182,11 +182,9 @@ int PQCLEAN_LEDAKEMLT12_LEAKTIME_niederreiter_decrypt(DIGIT *err, const privateK memset(((unsigned char *) err_mockup) + (NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B) + TRNG_BYTE_LENGTH, 0x00, (N0 - 1)*NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B - TRNG_BYTE_LENGTH); - if (!decryptOk) { - memcpy(err, err_mockup, N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); - } else { - memcpy(err, err_computed, N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); - } + memcpy(err, err_computed, N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); + // Overwrite on decryption failure + PQCLEAN_LEDAKEMLT12_LEAKTIME_gf2x_cmov(err, err_mockup, N0 * NUM_DIGITS_GF2X_ELEMENT, !decryptOk); return decryptOk; } diff --git a/crypto_kem/ledakemlt12/leaktime/utils.c b/crypto_kem/ledakemlt12/leaktime/utils.c new file mode 100644 index 00000000..bd657b5c --- /dev/null +++ b/crypto_kem/ledakemlt12/leaktime/utils.c @@ -0,0 +1,20 @@ +#include "gf2x_arith.h" +#include "utils.h" + +/* compares DIGIT sequences, returns 0 if they are equal */ +int PQCLEAN_LEDAKEMLT12_LEAKTIME_gf2x_verify(const DIGIT *a, const DIGIT *b, size_t len) { + DIGIT x = 0; + for (size_t i = 0; i < len; i++) { + x |= a[i] ^ b[i]; + } + x = (-x) >> (DIGIT_SIZE_b - 1); + return (int)x; +} + +/* conditionally move a into r if cond */ +void PQCLEAN_LEDAKEMLT12_LEAKTIME_cmov(uint8_t *r, const uint8_t *a, size_t len, int cond) { + uint8_t mask = -cond; + for (size_t i = 0; i < len; i++) { + r[i] ^= mask & (r[i] ^ a[i]); + } +} diff --git a/crypto_kem/ledakemlt12/leaktime/utils.h b/crypto_kem/ledakemlt12/leaktime/utils.h new file mode 100644 index 00000000..9d60d763 --- /dev/null +++ b/crypto_kem/ledakemlt12/leaktime/utils.h @@ -0,0 +1,9 @@ +#ifndef UTILS_H +#define UTILS_H + +#include + +int PQCLEAN_LEDAKEMLT12_LEAKTIME_gf2x_verify(const DIGIT *a, const DIGIT *b, size_t len); +void PQCLEAN_LEDAKEMLT12_LEAKTIME_cmov(uint8_t *r, const uint8_t *a, size_t len, int cond); + +#endif diff --git a/crypto_kem/ledakemlt32/leaktime/Makefile b/crypto_kem/ledakemlt32/leaktime/Makefile index 75c23bdd..9fae5312 100644 --- a/crypto_kem/ledakemlt32/leaktime/Makefile +++ b/crypto_kem/ledakemlt32/leaktime/Makefile @@ -3,10 +3,10 @@ LIB=libledakemlt32_leaktime.a HEADERS=api.h bf_decoding.h dfr_test.h gf2x_arith_mod_xPplusOne.h \ gf2x_arith.h H_Q_matrices_generation.h \ - niederreiter.h qc_ldpc_parameters.h rng.h sort.h + niederreiter.h qc_ldpc_parameters.h rng.h sort.h utils.h OBJECTS=bf_decoding.o dfr_test.o gf2x_arith_mod_xPplusOne.o \ - gf2x_arith.o H_Q_matrices_generation.o kem.o niederreiter.o rng.o sort.o + gf2x_arith.o H_Q_matrices_generation.o kem.o niederreiter.o rng.o sort.o utils.o CFLAGS=-O3 -Wall -Werror -Wextra -Wvla -Wpedantic -Wmissing-prototypes -std=c99 \ -I../../../common $(EXTRAFLAGS) diff --git a/crypto_kem/ledakemlt32/leaktime/Makefile.Microsoft_nmake b/crypto_kem/ledakemlt32/leaktime/Makefile.Microsoft_nmake index 548f166c..e4da0bf7 100644 --- a/crypto_kem/ledakemlt32/leaktime/Makefile.Microsoft_nmake +++ b/crypto_kem/ledakemlt32/leaktime/Makefile.Microsoft_nmake @@ -2,7 +2,7 @@ # nmake /f Makefile.Microsoft_nmake LIBRARY=libledakemlt32_leaktime.lib -OBJECTS=bf_decoding.obj dfr_test.obj gf2x_arith_mod_xPplusOne.obj gf2x_arith.obj H_Q_matrices_generation.obj kem.obj niederreiter.obj rng.obj sort.obj +OBJECTS=bf_decoding.obj dfr_test.obj gf2x_arith_mod_xPplusOne.obj gf2x_arith.obj H_Q_matrices_generation.obj kem.obj niederreiter.obj rng.obj sort.obj utils.obj CFLAGS=/nologo /I ..\..\..\common /W4 /WX diff --git a/crypto_kem/ledakemlt32/leaktime/kem.c b/crypto_kem/ledakemlt32/leaktime/kem.c index 2d126c92..882ff1df 100644 --- a/crypto_kem/ledakemlt32/leaktime/kem.c +++ b/crypto_kem/ledakemlt32/leaktime/kem.c @@ -2,6 +2,7 @@ #include "niederreiter.h" #include "randombytes.h" #include "rng.h" +#include "utils.h" #include @@ -128,20 +129,19 @@ int PQCLEAN_LEDAKEMLT32_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, PQCLEAN_LEDAKEMLT32_LEAKTIME_expand_error(reconstructed_error_vector, reconstructed_errorPos); - int equal = (0 == memcmp((const uint8_t *) decoded_error_vector, - (const uint8_t *) reconstructed_error_vector, - N0 * NUM_DIGITS_GF2X_ELEMENT)); - // equal == 1, if the reconstructed error vector match !!! + int equal = PQCLEAN_LEDAKEMLT32_LEAKTIME_gf2x_verify(decoded_error_vector, reconstructed_error_vector, N0 * NUM_DIGITS_GF2X_ELEMENT); + // equal == 0, if the reconstructed error vector match !!! - int decryptOk = (decode_ok == 1 && equal == 1); + int decryptOk = (decode_ok == 1 && equal == 0); memcpy(ss_input, decoded_seed, TRNG_BYTE_LENGTH); + memcpy(ss_input + sizeof(decoded_seed), tail, TRNG_BYTE_LENGTH); - if (decryptOk == 1) { - memcpy(ss_input + sizeof(decoded_seed), tail, TRNG_BYTE_LENGTH); - } else { // decryption failure - memcpy(ss_input + sizeof(decoded_seed), ((const privateKeyNiederreiter_t *)sk)->decryption_failure_secret, TRNG_BYTE_LENGTH); - } + // Overwrite on failure + PQCLEAN_LEDAKEMLT32_LEAKTIME_cmov(ss_input + sizeof(decoded_seed), + ((const privateKeyNiederreiter_t *) sk)->decryption_failure_secret, + TRNG_BYTE_LENGTH, + !decryptOk); HASH_FUNCTION(ss, ss_input, 2 * TRNG_BYTE_LENGTH); diff --git a/crypto_kem/ledakemlt32/leaktime/niederreiter.c b/crypto_kem/ledakemlt32/leaktime/niederreiter.c index 33397ae6..c7181d7f 100644 --- a/crypto_kem/ledakemlt32/leaktime/niederreiter.c +++ b/crypto_kem/ledakemlt32/leaktime/niederreiter.c @@ -182,11 +182,9 @@ int PQCLEAN_LEDAKEMLT32_LEAKTIME_niederreiter_decrypt(DIGIT *err, const privateK memset(((unsigned char *) err_mockup) + (NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B) + TRNG_BYTE_LENGTH, 0x00, (N0 - 1)*NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B - TRNG_BYTE_LENGTH); - if (!decryptOk) { - memcpy(err, err_mockup, N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); - } else { - memcpy(err, err_computed, N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); - } + memcpy(err, err_computed, N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); + // Overwrite on decryption failure + PQCLEAN_LEDAKEMLT32_LEAKTIME_gf2x_cmov(err, err_mockup, N0 * NUM_DIGITS_GF2X_ELEMENT, !decryptOk); return decryptOk; } diff --git a/crypto_kem/ledakemlt32/leaktime/utils.c b/crypto_kem/ledakemlt32/leaktime/utils.c new file mode 100644 index 00000000..86d9353c --- /dev/null +++ b/crypto_kem/ledakemlt32/leaktime/utils.c @@ -0,0 +1,20 @@ +#include "gf2x_arith.h" +#include "utils.h" + +/* compares DIGIT sequences, returns 0 if they are equal */ +int PQCLEAN_LEDAKEMLT32_LEAKTIME_gf2x_verify(const DIGIT *a, const DIGIT *b, size_t len) { + DIGIT x = 0; + for (size_t i = 0; i < len; i++) { + x |= a[i] ^ b[i]; + } + x = (-x) >> (DIGIT_SIZE_b - 1); + return (int)x; +} + +/* conditionally move a into r if cond */ +void PQCLEAN_LEDAKEMLT32_LEAKTIME_cmov(uint8_t *r, const uint8_t *a, size_t len, int cond) { + uint8_t mask = -cond; + for (size_t i = 0; i < len; i++) { + r[i] ^= mask & (r[i] ^ a[i]); + } +} diff --git a/crypto_kem/ledakemlt32/leaktime/utils.h b/crypto_kem/ledakemlt32/leaktime/utils.h new file mode 100644 index 00000000..df31a8b8 --- /dev/null +++ b/crypto_kem/ledakemlt32/leaktime/utils.h @@ -0,0 +1,9 @@ +#ifndef UTILS_H +#define UTILS_H + +#include + +int PQCLEAN_LEDAKEMLT32_LEAKTIME_gf2x_verify(const DIGIT *a, const DIGIT *b, size_t len); +void PQCLEAN_LEDAKEMLT32_LEAKTIME_cmov(uint8_t *r, const uint8_t *a, size_t len, int cond); + +#endif diff --git a/crypto_kem/ledakemlt52/leaktime/Makefile b/crypto_kem/ledakemlt52/leaktime/Makefile index 981ce732..7ef80889 100644 --- a/crypto_kem/ledakemlt52/leaktime/Makefile +++ b/crypto_kem/ledakemlt52/leaktime/Makefile @@ -3,10 +3,10 @@ LIB=libledakemlt52_leaktime.a HEADERS=api.h bf_decoding.h dfr_test.h gf2x_arith_mod_xPplusOne.h \ gf2x_arith.h H_Q_matrices_generation.h \ - niederreiter.h qc_ldpc_parameters.h rng.h sort.h + niederreiter.h qc_ldpc_parameters.h rng.h sort.h utils.h OBJECTS=bf_decoding.o dfr_test.o gf2x_arith_mod_xPplusOne.o \ - gf2x_arith.o H_Q_matrices_generation.o kem.o niederreiter.o rng.o sort.o + gf2x_arith.o H_Q_matrices_generation.o kem.o niederreiter.o rng.o sort.o utils.o CFLAGS=-O3 -Wall -Werror -Wextra -Wvla -Wpedantic -Wmissing-prototypes -std=c99 \ -I../../../common $(EXTRAFLAGS) diff --git a/crypto_kem/ledakemlt52/leaktime/Makefile.Microsoft_nmake b/crypto_kem/ledakemlt52/leaktime/Makefile.Microsoft_nmake index a346d3b1..a1bdaf09 100644 --- a/crypto_kem/ledakemlt52/leaktime/Makefile.Microsoft_nmake +++ b/crypto_kem/ledakemlt52/leaktime/Makefile.Microsoft_nmake @@ -2,7 +2,7 @@ # nmake /f Makefile.Microsoft_nmake LIBRARY=libledakemlt52_leaktime.lib -OBJECTS=bf_decoding.obj dfr_test.obj gf2x_arith_mod_xPplusOne.obj gf2x_arith.obj H_Q_matrices_generation.obj kem.obj niederreiter.obj rng.obj sort.obj +OBJECTS=bf_decoding.obj dfr_test.obj gf2x_arith_mod_xPplusOne.obj gf2x_arith.obj H_Q_matrices_generation.obj kem.obj niederreiter.obj rng.obj sort.obj utils.obj CFLAGS=/nologo /I ..\..\..\common /W4 /WX diff --git a/crypto_kem/ledakemlt52/leaktime/kem.c b/crypto_kem/ledakemlt52/leaktime/kem.c index 1d48e3e1..2b3d3514 100644 --- a/crypto_kem/ledakemlt52/leaktime/kem.c +++ b/crypto_kem/ledakemlt52/leaktime/kem.c @@ -2,6 +2,7 @@ #include "niederreiter.h" #include "randombytes.h" #include "rng.h" +#include "utils.h" #include @@ -128,20 +129,19 @@ int PQCLEAN_LEDAKEMLT52_LEAKTIME_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, PQCLEAN_LEDAKEMLT52_LEAKTIME_expand_error(reconstructed_error_vector, reconstructed_errorPos); - int equal = (0 == memcmp((const uint8_t *) decoded_error_vector, - (const uint8_t *) reconstructed_error_vector, - N0 * NUM_DIGITS_GF2X_ELEMENT)); - // equal == 1, if the reconstructed error vector match !!! + int equal = PQCLEAN_LEDAKEMLT52_LEAKTIME_gf2x_verify(decoded_error_vector, reconstructed_error_vector, N0 * NUM_DIGITS_GF2X_ELEMENT); + // equal == 0, if the reconstructed error vector match !!! - int decryptOk = (decode_ok == 1 && equal == 1); + int decryptOk = (decode_ok == 1 && equal == 0); memcpy(ss_input, decoded_seed, TRNG_BYTE_LENGTH); + memcpy(ss_input + sizeof(decoded_seed), tail, TRNG_BYTE_LENGTH); - if (decryptOk == 1) { - memcpy(ss_input + sizeof(decoded_seed), tail, TRNG_BYTE_LENGTH); - } else { // decryption failure - memcpy(ss_input + sizeof(decoded_seed), ((const privateKeyNiederreiter_t *)sk)->decryption_failure_secret, TRNG_BYTE_LENGTH); - } + // Overwrite on failure + PQCLEAN_LEDAKEMLT52_LEAKTIME_cmov(ss_input + sizeof(decoded_seed), + ((const privateKeyNiederreiter_t *) sk)->decryption_failure_secret, + TRNG_BYTE_LENGTH, + !decryptOk); HASH_FUNCTION(ss, ss_input, 2 * TRNG_BYTE_LENGTH); diff --git a/crypto_kem/ledakemlt52/leaktime/niederreiter.c b/crypto_kem/ledakemlt52/leaktime/niederreiter.c index 648132d7..e5d2f602 100644 --- a/crypto_kem/ledakemlt52/leaktime/niederreiter.c +++ b/crypto_kem/ledakemlt52/leaktime/niederreiter.c @@ -182,11 +182,9 @@ int PQCLEAN_LEDAKEMLT52_LEAKTIME_niederreiter_decrypt(DIGIT *err, const privateK memset(((unsigned char *) err_mockup) + (NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B) + TRNG_BYTE_LENGTH, 0x00, (N0 - 1)*NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B - TRNG_BYTE_LENGTH); - if (!decryptOk) { - memcpy(err, err_mockup, N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); - } else { - memcpy(err, err_computed, N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); - } + memcpy(err, err_computed, N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); + // Overwrite on decryption failure + PQCLEAN_LEDAKEMLT52_LEAKTIME_gf2x_cmov(err, err_mockup, N0 * NUM_DIGITS_GF2X_ELEMENT, !decryptOk); return decryptOk; } diff --git a/crypto_kem/ledakemlt52/leaktime/utils.c b/crypto_kem/ledakemlt52/leaktime/utils.c new file mode 100644 index 00000000..f50734dc --- /dev/null +++ b/crypto_kem/ledakemlt52/leaktime/utils.c @@ -0,0 +1,20 @@ +#include "gf2x_arith.h" +#include "utils.h" + +/* compares DIGIT sequences, returns 0 if they are equal */ +int PQCLEAN_LEDAKEMLT52_LEAKTIME_gf2x_verify(const DIGIT *a, const DIGIT *b, size_t len) { + DIGIT x = 0; + for (size_t i = 0; i < len; i++) { + x |= a[i] ^ b[i]; + } + x = (-x) >> (DIGIT_SIZE_b - 1); + return (int)x; +} + +/* conditionally move a into r if cond */ +void PQCLEAN_LEDAKEMLT52_LEAKTIME_cmov(uint8_t *r, const uint8_t *a, size_t len, int cond) { + uint8_t mask = -cond; + for (size_t i = 0; i < len; i++) { + r[i] ^= mask & (r[i] ^ a[i]); + } +} diff --git a/crypto_kem/ledakemlt52/leaktime/utils.h b/crypto_kem/ledakemlt52/leaktime/utils.h new file mode 100644 index 00000000..da09a7d8 --- /dev/null +++ b/crypto_kem/ledakemlt52/leaktime/utils.h @@ -0,0 +1,9 @@ +#ifndef UTILS_H +#define UTILS_H + +#include + +int PQCLEAN_LEDAKEMLT52_LEAKTIME_gf2x_verify(const DIGIT *a, const DIGIT *b, size_t len); +void PQCLEAN_LEDAKEMLT52_LEAKTIME_cmov(uint8_t *r, const uint8_t *a, size_t len, int cond); + +#endif