1
1
mirror of https://github.com/henrydcase/pqc.git synced 2024-11-26 09:21:28 +00:00

constant-time decapsulation/decryption failure

This commit is contained in:
Leon Botros 2019-08-21 21:27:53 +02:00
parent 7d371dd449
commit 901d53ebe4
18 changed files with 135 additions and 54 deletions

View File

@ -3,10 +3,10 @@
LIB=libledakemlt12_leaktime.a LIB=libledakemlt12_leaktime.a
HEADERS=api.h bf_decoding.h dfr_test.h gf2x_arith_mod_xPplusOne.h \ HEADERS=api.h bf_decoding.h dfr_test.h gf2x_arith_mod_xPplusOne.h \
gf2x_arith.h H_Q_matrices_generation.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 \ 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 \ CFLAGS=-O3 -Wall -Werror -Wextra -Wvla -Wpedantic -Wmissing-prototypes -std=c99 \
-I../../../common $(EXTRAFLAGS) -I../../../common $(EXTRAFLAGS)

View File

@ -2,7 +2,7 @@
# nmake /f Makefile.Microsoft_nmake # nmake /f Makefile.Microsoft_nmake
LIBRARY=libledakemlt12_leaktime.lib 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 CFLAGS=/nologo /I ..\..\..\common /W4 /WX

View File

@ -2,6 +2,7 @@
#include "niederreiter.h" #include "niederreiter.h"
#include "randombytes.h" #include "randombytes.h"
#include "rng.h" #include "rng.h"
#include "utils.h"
#include <string.h> #include <string.h>
@ -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); PQCLEAN_LEDAKEMLT12_LEAKTIME_expand_error(reconstructed_error_vector, reconstructed_errorPos);
int equal = (0 == memcmp((const uint8_t *) decoded_error_vector, int equal = PQCLEAN_LEDAKEMLT12_LEAKTIME_gf2x_verify(decoded_error_vector, reconstructed_error_vector, N0 * NUM_DIGITS_GF2X_ELEMENT);
(const uint8_t *) reconstructed_error_vector, // equal == 0, if the reconstructed error vector match !!!
N0 * NUM_DIGITS_GF2X_ELEMENT));
// equal == 1, 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, decoded_seed, TRNG_BYTE_LENGTH);
if (decryptOk == 1) {
memcpy(ss_input + sizeof(decoded_seed), tail, TRNG_BYTE_LENGTH); 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); HASH_FUNCTION(ss, ss_input, 2 * TRNG_BYTE_LENGTH);

View File

@ -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, 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); (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; return decryptOk;
} }

View File

@ -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]);
}
}

View File

@ -0,0 +1,9 @@
#ifndef UTILS_H
#define UTILS_H
#include <stdint.h>
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

View File

@ -3,10 +3,10 @@
LIB=libledakemlt32_leaktime.a LIB=libledakemlt32_leaktime.a
HEADERS=api.h bf_decoding.h dfr_test.h gf2x_arith_mod_xPplusOne.h \ HEADERS=api.h bf_decoding.h dfr_test.h gf2x_arith_mod_xPplusOne.h \
gf2x_arith.h H_Q_matrices_generation.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 \ 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 \ CFLAGS=-O3 -Wall -Werror -Wextra -Wvla -Wpedantic -Wmissing-prototypes -std=c99 \
-I../../../common $(EXTRAFLAGS) -I../../../common $(EXTRAFLAGS)

View File

@ -2,7 +2,7 @@
# nmake /f Makefile.Microsoft_nmake # nmake /f Makefile.Microsoft_nmake
LIBRARY=libledakemlt32_leaktime.lib 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 CFLAGS=/nologo /I ..\..\..\common /W4 /WX

View File

@ -2,6 +2,7 @@
#include "niederreiter.h" #include "niederreiter.h"
#include "randombytes.h" #include "randombytes.h"
#include "rng.h" #include "rng.h"
#include "utils.h"
#include <string.h> #include <string.h>
@ -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); PQCLEAN_LEDAKEMLT32_LEAKTIME_expand_error(reconstructed_error_vector, reconstructed_errorPos);
int equal = (0 == memcmp((const uint8_t *) decoded_error_vector, int equal = PQCLEAN_LEDAKEMLT32_LEAKTIME_gf2x_verify(decoded_error_vector, reconstructed_error_vector, N0 * NUM_DIGITS_GF2X_ELEMENT);
(const uint8_t *) reconstructed_error_vector, // equal == 0, if the reconstructed error vector match !!!
N0 * NUM_DIGITS_GF2X_ELEMENT));
// equal == 1, 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, decoded_seed, TRNG_BYTE_LENGTH);
if (decryptOk == 1) {
memcpy(ss_input + sizeof(decoded_seed), tail, TRNG_BYTE_LENGTH); 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); HASH_FUNCTION(ss, ss_input, 2 * TRNG_BYTE_LENGTH);

View File

@ -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, 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); (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; return decryptOk;
} }

View File

@ -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]);
}
}

View File

@ -0,0 +1,9 @@
#ifndef UTILS_H
#define UTILS_H
#include <stdint.h>
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

View File

@ -3,10 +3,10 @@
LIB=libledakemlt52_leaktime.a LIB=libledakemlt52_leaktime.a
HEADERS=api.h bf_decoding.h dfr_test.h gf2x_arith_mod_xPplusOne.h \ HEADERS=api.h bf_decoding.h dfr_test.h gf2x_arith_mod_xPplusOne.h \
gf2x_arith.h H_Q_matrices_generation.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 \ 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 \ CFLAGS=-O3 -Wall -Werror -Wextra -Wvla -Wpedantic -Wmissing-prototypes -std=c99 \
-I../../../common $(EXTRAFLAGS) -I../../../common $(EXTRAFLAGS)

View File

@ -2,7 +2,7 @@
# nmake /f Makefile.Microsoft_nmake # nmake /f Makefile.Microsoft_nmake
LIBRARY=libledakemlt52_leaktime.lib 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 CFLAGS=/nologo /I ..\..\..\common /W4 /WX

View File

@ -2,6 +2,7 @@
#include "niederreiter.h" #include "niederreiter.h"
#include "randombytes.h" #include "randombytes.h"
#include "rng.h" #include "rng.h"
#include "utils.h"
#include <string.h> #include <string.h>
@ -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); PQCLEAN_LEDAKEMLT52_LEAKTIME_expand_error(reconstructed_error_vector, reconstructed_errorPos);
int equal = (0 == memcmp((const uint8_t *) decoded_error_vector, int equal = PQCLEAN_LEDAKEMLT52_LEAKTIME_gf2x_verify(decoded_error_vector, reconstructed_error_vector, N0 * NUM_DIGITS_GF2X_ELEMENT);
(const uint8_t *) reconstructed_error_vector, // equal == 0, if the reconstructed error vector match !!!
N0 * NUM_DIGITS_GF2X_ELEMENT));
// equal == 1, 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, decoded_seed, TRNG_BYTE_LENGTH);
if (decryptOk == 1) {
memcpy(ss_input + sizeof(decoded_seed), tail, TRNG_BYTE_LENGTH); 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); HASH_FUNCTION(ss, ss_input, 2 * TRNG_BYTE_LENGTH);

View File

@ -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, 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); (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; return decryptOk;
} }

View File

@ -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]);
}
}

View File

@ -0,0 +1,9 @@
#ifndef UTILS_H
#define UTILS_H
#include <stdint.h>
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