Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fault #7

Open
wants to merge 48 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
8c3d4d9
Added description of this branch
sfluhrer Apr 3, 2019
c982ade
Started on fault changes
sfluhrer Apr 3, 2019
86505bc
Started on fault changes
sfluhrer Apr 3, 2019
dce438c
Started on fault changes
sfluhrer Apr 3, 2019
9a31d98
Fault detection changes
sfluhrer Apr 3, 2019
893f67e
Fault detection changes
sfluhrer Apr 3, 2019
f04460f
Fault detection changes
sfluhrer Apr 3, 2019
d81da3e
Fault detection changes
sfluhrer Apr 3, 2019
7629601
Fault detection changes
sfluhrer Apr 3, 2019
886e371
Fault detection logic
sfluhrer Apr 3, 2019
dfc4392
Fault detection logic
sfluhrer Apr 3, 2019
8f63015
Fault detection logic
sfluhrer Apr 3, 2019
1913ab6
Bugfix: Replace '48' with HSS_MAX_PRIVATE_KEY_LEN
sfluhrer Apr 3, 2019
7a6a382
Bugfix: modify how we work with private keys
sfluhrer Apr 3, 2019
aa3edd3
Bugfix: fix private key handling
sfluhrer Apr 3, 2019
a81472d
Bugfix: mismatch int/unsigned
sfluhrer Apr 3, 2019
d4a9c9a
Fault detection changes
sfluhrer Apr 3, 2019
ed32a79
Fault detection changes
sfluhrer Apr 3, 2019
1ac1f07
Fault detection changes
sfluhrer Apr 3, 2019
b6a6d2b
Fault detection logic
sfluhrer Apr 3, 2019
c2e2ebc
Fault detection logic
sfluhrer Apr 3, 2019
5322f16
Fault detection logic
sfluhrer Apr 3, 2019
4026af0
Fault detection logic
sfluhrer Apr 3, 2019
bf8a1dc
Fault detection changes
sfluhrer Apr 3, 2019
a9e7610
Fault detection logic
sfluhrer Apr 3, 2019
bfc8144
Configuration file
sfluhrer Apr 7, 2019
09a92dd
Moved ALLOW_VERBOSE flag to config.h
sfluhrer Apr 7, 2019
bf474fe
Allocate redundant trees (if configured)
sfluhrer Apr 7, 2019
18b874d
Adjust for changed merkle_tree data structures
sfluhrer Apr 7, 2019
982aa1a
Move SECRET_METHOD, SECRET_FLAGS to config.h
sfluhrer Apr 7, 2019
1575812
Perform double-checking logic
sfluhrer Apr 7, 2019
0175555
Add redundant data structures
sfluhrer Apr 7, 2019
6aaa8c2
Redundancy changes
sfluhrer Apr 7, 2019
86cd38d
Perform redundant checks
sfluhrer Apr 7, 2019
3aa5e19
Data structure changes
sfluhrer Apr 7, 2019
f17fa31
Moved MAX_THREAD, DEFAULT_THREAD to config.h
sfluhrer Apr 7, 2019
ec2b3e3
Add lm_ots_doublecheck_signature prototype
sfluhrer Apr 7, 2019
d10bdbf
Add lm_ots_doublecheck_signature function
sfluhrer Apr 7, 2019
83558c1
Updated status
sfluhrer Apr 7, 2019
981cc00
Moved USE_OPENSSL flag to config.h
sfluhrer Apr 7, 2019
da331ea
Added fault testing code
sfluhrer Apr 11, 2019
dc20e54
Added fault testing code
sfluhrer Apr 11, 2019
e383c8c
Updated status
sfluhrer Apr 11, 2019
390614e
Added version flag to private key format
sfluhrer May 21, 2019
69038bd
Add another option for fault tolerance
sfluhrer May 28, 2019
3f35287
Added memory leak checking
sfluhrer Jun 27, 2019
496d06c
Merge branch 'master' into fault
sfluhrer Oct 4, 2019
ed83af1
Fix build errors due to merge
sfluhrer Oct 6, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 30 additions & 26 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
AR = /usr/bin/ar
CC = /usr/bin/gcc
CFLAGS = -Wall -O3
# CFLAGS = -Wall -g

all: hss_lib.a \
hss_lib_thread.a \
Expand All @@ -12,7 +13,7 @@ hss_lib.a: hss.o hss_alloc.o hss_aux.o hss_common.o \
hss_compute.o hss_generate.o hss_keygen.o hss_param.o hss_reserve.o \
hss_sign.o hss_sign_inc.o hss_thread_single.o \
hss_verify.o hss_verify_inc.o hss_derive.o \
hss_derive.o hss_zeroize.o lm_common.o \
hss_derive.o hss_zeroize.o hss_malloc.o lm_common.o \
lm_ots_common.o lm_ots_sign.o lm_ots_verify.o lm_verify.o endian.o \
hash.o sha256.o
$(AR) rcs $@ $^
Expand All @@ -21,7 +22,7 @@ hss_lib_thread.a: hss.o hss_alloc.o hss_aux.o hss_common.o \
hss_compute.o hss_generate.o hss_keygen.o hss_param.o hss_reserve.o \
hss_sign.o hss_sign_inc.o hss_thread_pthread.o \
hss_verify.o hss_verify_inc.o \
hss_derive.o hss_zeroize.o lm_common.o \
hss_derive.o hss_zeroize.o hss_malloc.o lm_common.o \
lm_ots_common.o lm_ots_sign.o lm_ots_verify.o lm_verify.o endian.o \
hash.o sha256.o
$(AR) rcs $@ $^
Expand All @@ -37,79 +38,82 @@ demo: demo.c hss_lib_thread.a
test_1: test_1.c lm_ots_common.o lm_ots_sign.o lm_ots_verify.o endian.o hash.o sha256.o hss_zeroize.o
$(CC) $(CFLAGS) -o test_1 test_1.c lm_ots_common.o lm_ots_sign.o lm_ots_verify.o endian.o hash.o sha256.o hss_zeroize.o -lcrypto

test_hss: test_hss.c test_hss.h test_testvector.c test_stat.c test_keygen.c test_load.c test_sign.c test_sign_inc.c test_verify.c test_verify_inc.c test_keyload.c test_reserve.c test_thread.c test_h25.c hss.h hss_lib_thread.a
$(CC) $(CFLAGS) test_hss.c test_testvector.c test_stat.c test_keygen.c test_sign.c test_sign_inc.c test_load.c test_verify.c test_verify_inc.c test_keyload.c test_reserve.c test_thread.c test_h25.c hss_lib_thread.a -lcrypto -lpthread -o test_hss
test_hss: test_hss.c test_hss.h test_testvector.c test_stat.c test_keygen.c test_load.c test_sign.c test_sign_inc.c test_verify.c test_verify_inc.c test_keyload.c test_reserve.c test_thread.c test_h25.c test_fault.c test_update.c hss.h hss_lib_thread.a
$(CC) $(CFLAGS) test_hss.c test_testvector.c test_stat.c test_keygen.c test_sign.c test_sign_inc.c test_load.c test_verify.c test_verify_inc.c test_keyload.c test_reserve.c test_thread.c test_h25.c test_fault.c test_update.c hss_lib_thread.a -lcrypto -lpthread -o test_hss

hss.o: hss.c hss.h common_defs.h hash.h endian.h hss_internal.h hss_aux.h hss_derive.h
hss.o: hss.c hss.h common_defs.h hash.h endian.h hss_internal.h hss_aux.h hss_derive.h config.h
$(CC) $(CFLAGS) -c hss.c -o $@

hss_alloc.o: hss_alloc.c hss.h hss_internal.h lm_common.h
hss_alloc.o: hss_alloc.c hss.h hss_internal.h lm_common.h config.h hss_malloc.h
$(CC) $(CFLAGS) -c hss_alloc.c -o $@

hss_aux.o: hss_aux.c hss_aux.h hss_internal.h common_defs.h lm_common.h endian.h hash.h
hss_aux.o: hss_aux.c hss_aux.h hss_internal.h common_defs.h lm_common.h endian.h hash.h config.h
$(CC) $(CFLAGS) -c hss_aux.c -o $@

hss_common.o: hss_common.c common_defs.h hss_common.h lm_common.h
hss_common.o: hss_common.c common_defs.h hss_common.h lm_common.h config.h
$(CC) $(CFLAGS) -c hss_common.c -o $@

hss_compute.o: hss_compute.c hss_internal.h hash.h hss_thread.h lm_ots_common.h lm_ots.h endian.h hss_derive.h
hss_compute.o: hss_compute.c hss_internal.h hash.h hss_thread.h lm_ots_common.h lm_ots.h endian.h hss_derive.h config.h
$(CC) $(CFLAGS) -c hss_compute.c -o $@

hss_derive.o: hss_derive.c hss_derive.h hss_internal.h hash.h endian.h
hss_derive.o: hss_derive.c hss_derive.h hss_internal.h hash.h endian.h config.h
$(CC) $(CFLAGS) -c hss_derive.c -o $@

hss_generate.o: hss_generate.c hss.h hss_internal.h hss_aux.h hash.h hss_thread.h hss_reserve.h lm_ots_common.h endian.h
hss_generate.o: hss_generate.c hss.h hss_internal.h hss_aux.h hash.h hss_thread.h hss_reserve.h lm_ots_common.h endian.h config.h
$(CC) $(CFLAGS) -c hss_generate.c -o $@

hss_keygen.o: hss_keygen.c hss.h common_defs.h hss_internal.h hss_aux.h endian.h hash.h hss_thread.h lm_common.h lm_ots_common.h
hss_keygen.o: hss_keygen.c hss.h common_defs.h hss_internal.h hss_aux.h endian.h hash.h hss_thread.h lm_common.h lm_ots_common.h config.h
$(CC) $(CFLAGS) -c hss_keygen.c -o $@

hss_param.o: hss_param.c hss.h hss_internal.h endian.h hss_zeroize.h
hss_malloc.o: hss_malloc.c hss.h config.h common_defs.h hss_malloc.h
$(CC) $(CFLAGS) -c hss_malloc.c -o $@

hss_param.o: hss_param.c hss.h hss_internal.h endian.h hss_zeroize.h config.h
$(CC) $(CFLAGS) -c hss_param.c -o $@

hss_reserve.o: hss_reserve.c common_defs.h hss_internal.h hss_reserve.h endian.h
hss_reserve.o: hss_reserve.c hss.h common_defs.h hss_internal.h hss_reserve.h endian.h config.h
$(CC) $(CFLAGS) -c hss_reserve.c -o $@

hss_sign.o: hss_sign.c common_defs.h hss.h hash.h endian.h hss_internal.h hss_aux.h hss_thread.h hss_reserve.h lm_ots.h lm_ots_common.h hss_derive.h
hss_sign.o: hss_sign.c common_defs.h hss.h hash.h endian.h hss_internal.h hss_aux.h hss_thread.h hss_reserve.h lm_ots.h lm_ots_common.h hss_derive.h config.h
$(CC) $(CFLAGS) -c hss_sign.c -o $@

hss_sign_inc.o: hss_sign_inc.c hss.h common_defs.h hss.h hash.h endian.h hss_internal.h hss_aux.h hss_reserve.h hss_derive.h lm_ots.h lm_ots_common.h hss_sign_inc.h
hss_sign_inc.o: hss_sign_inc.c hss.h common_defs.h hss.h hash.h endian.h hss_internal.h hss_aux.h hss_reserve.h hss_derive.h lm_ots.h lm_ots_common.h hss_sign_inc.h config.h
$(CC) $(CFLAGS) -c hss_sign_inc.c -o $@

hss_thread_single.o: hss_thread_single.c hss_thread.h
hss_thread_single.o: hss_thread_single.c hss_thread.h config.h
$(CC) $(CFLAGS) -c hss_thread_single.c -o $@

hss_thread_pthread.o: hss_thread_pthread.c hss_thread.h
hss_thread_pthread.o: hss_thread_pthread.c hss_thread.h config.h
$(CC) $(CFLAGS) -c hss_thread_pthread.c -o $@

hss_verify.o: hss_verify.c hss_verify.h common_defs.h lm_verify.h lm_common.h lm_ots_verify.h hash.h endian.h hss_thread.h
hss_verify.o: hss_verify.c hss.h hss_verify.h common_defs.h lm_verify.h lm_common.h lm_ots_verify.h hash.h endian.h hss_thread.h config.h
$(CC) $(CFLAGS) -c hss_verify.c -o $@

hss_verify_inc.o: hss_verify_inc.c hss_verify_inc.h common_defs.h lm_verify.h lm_common.h lm_ots_verify.h hash.h endian.h hss_thread.h
hss_verify_inc.o: hss_verify_inc.c hss.h hss_verify_inc.h common_defs.h lm_verify.h lm_common.h lm_ots_verify.h hash.h endian.h hss_thread.h config.h
$(CC) $(CFLAGS) -c hss_verify_inc.c -o $@

hss_zeroize.o: hss_zeroize.c hss_zeroize.h
$(CC) $(CFLAGS) -c hss_zeroize.c -o $@

lm_common.o: lm_common.c lm_common.h hash.h common_defs.h lm_ots_common.h
lm_common.o: lm_common.c lm_common.h hash.h common_defs.h lm_ots_common.h config.h
$(CC) $(CFLAGS) -c lm_common.c -o $@

lm_ots_common.o: lm_ots_common.c common_defs.h hash.h
lm_ots_common.o: lm_ots_common.c common_defs.h hash.h config.h
$(CC) $(CFLAGS) -c lm_ots_common.c -o $@

lm_ots_sign.o: lm_ots_sign.c common_defs.h lm_ots.h lm_ots_common.h hash.h endian.h hss_zeroize.h hss_derive.h
lm_ots_sign.o: lm_ots_sign.c common_defs.h lm_ots.h lm_ots_common.h hash.h endian.h hss_zeroize.h hss_derive.h config.h
$(CC) $(CFLAGS) -c lm_ots_sign.c -o $@

lm_ots_verify.o: lm_ots_verify.c lm_ots_verify.h lm_ots_common.h hash.h endian.h common_defs.h
lm_ots_verify.o: lm_ots_verify.c lm_ots_verify.h lm_ots_common.h hash.h endian.h common_defs.h config.h
$(CC) $(CFLAGS) -c lm_ots_verify.c -o $@

lm_verify.o: lm_verify.c lm_verify.h lm_common.h lm_ots_common.h lm_ots_verify.h hash.h endian.h common_defs.h
lm_verify.o: lm_verify.c lm_verify.h lm_common.h lm_ots_common.h lm_ots_verify.h hash.h endian.h common_defs.h config.h
$(CC) $(CFLAGS) -c lm_verify.c -o $@

endian.o: endian.c endian.h
$(CC) $(CFLAGS) -c endian.c -o $@

hash.o: hash.c hash.h sha256.h hss_zeroize.h
hash.o: hash.c hash.h sha256.h hss_zeroize.h config.h
$(CC) $(CFLAGS) -c hash.c -o $@

sha256.o: sha256.c sha256.h endian.h
Expand Down
17 changes: 14 additions & 3 deletions README
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
This code attempts to be a usable implementation of the LMS Hash Based
Signature Scheme from RFC 8554.

See read.me for documentation how to use it.
This specific branch attempts to implement optional fault tolerance;
that is, no secret keying data is leaked on a miscompute.

This appears to be complete and tested.

Changes:
- Expanded the size of the private key to 64 bytes (both to add a
checksum to detect NVRAM errors, and to include a 'max count' value
which may be useful in key sharing
- Added a FAULT_TOLERANCE flag that, when exabled, adds checking logic
to the public key computations; this is at some cost to both time
and memory
- Added a fault regression test, which tests out the above protection
- Also added a test that looks for memory leaks

This is the ACVP branch - designed to be (optionally) compatible with the
public ACVP server
90 changes: 89 additions & 1 deletion config.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,63 @@
* the operating environment needs
*/

/*
* These control how we do threading; these apply only if we have the
* threading library installed
*
* This is the maximum number of threads we'll try to create; we won't
* exceed this number no matter what the application tells us
*/
#define MAX_THREAD 16 /* Never try to create more than 16 threads */

/*
* This is the number of threads we'll try to create if the application
* doesn't specify otherwise (i.e. passes in 0)
*/
#define DEFAULT_THREAD 16 /* Go with 16 threads by default */

/*
* We provide two different methods to be resiliant against fault attacks.
* Both these methods have costs (but very different costs); if fault attacks
* are a concern for your implementation, you should enable one (or both of
* them if you're feeling especially paranoid, they are mutually compatible)
*/

/*
* Method 1 for fault tolerance: when we initially compute the signature for
* an internal root node, we store it (actually, the hash of the signed
* public key) in the private key. Then, if we ever need to compute that
* signature again, we compare hashes; if they're different, then a fault
* that could have leaked the private key has occurred
* 0 -> We don't.
* 1 -> We do. This has the cost of expanding the size of the private key
* by 7*FAULT_CACHE_LEN bytes; it also can cause us to update the private
* key more often than expected (if you use reservations)
*/
#define FAULT_CACHE_SIG 1

/*
* If we cache hashes of signatures (FAULT_CACHE_SIG), then this determines
* the length of the hash we use; if FAULT_CACHE_LEN < 32, we truncate the
* hash. This is here because we generally don't need to store the entire
* hash (unless we assume that the attacker can generate a precise fault at a
* specific spot in the computation, and he has enough computational resources
* to do a second preimage attack on a truncated hash), and shortening the
* hash reduces the space used by a private key.
*/
#define FAULT_CACHE_LEN 8

/*
* Method 2 for fault tolerance: compute hashes twice, and compare the results
* Note that the goal of this is to prevent errors that would cause us
* to leak information that would allow forgeries; errors that only cause us
* to produce invalid signatures are not of concern.
* 0 -> We don't.
* 1 -> We do. This has the extra cost of increassing load and signature
* generation times, and increased memory consumption
*/
#define FAULT_RECOMPUTE 0

/*
* This modifies which seed generation logic we use
* Note that changing these parameters will change the mapping
Expand All @@ -20,7 +77,7 @@
* seed in more than a defined number of distinct hashes
* 2 -> We generate seeds and secrets in a way which is compatible with ACVP
*/
#define SECRET_METHOD 2
#define SECRET_METHOD 0

/*
* If we're using the side channel resistant method, this defines the max
Expand All @@ -31,4 +88,35 @@
*/
#define SECRET_MAX 4 /* Never use a seed more than 16 times */

/*
* This determines whether we use the OpenSSL implementation of SHA-256
* or we use our own
* 1 -> We use the OpenSSL implementation; it's faster (and can use the
* Intel SHA256 instructions for even more speed)
* 0 -> We use a portable C implementation; it's slower, but it does
* allow for some of the below instrumentation logic
*/
#define USE_OPENSSL 1 /* We use the OpenSSL implementation for SHA-256 */

/*
* This determines whether we will print out the internal hash inputs and
* outputs if the global hss_verbose is set. Obvously, this is not great
* for security; however it can be useful to track down those truly hard
* bugs. It is also quite chatty, and if you do use this, you probably
* want to shut off multithreading
* This works only if USE_OPENSSL == 0
* 0 -> Omit debugging code
* 1 -> Include debugging code
*/
#define ALLOW_VERBOSE 0 /* Don't do instrumentation */

/*
* This determines whether we'll including some test instrumenetation into
* the code. This is never appropriate for a real application; this does
* allow the testing code to run some additional tests
* 0 -> Omit instrumentation
* 1 -> Include instrumentation
*/
#define TEST_INSTRUMENTATION 0 /* Test mode off */

#endif /* CONFIG_H_ */
14 changes: 5 additions & 9 deletions demo.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,8 @@ static int sign(const char *keyname, char **files) {
printf( "Loading private key\n" );
fflush(stdout);
struct hss_working_key *w = hss_load_private_key(
read_private_key, private_key_filename, /* How to load the */
/* private key */
read_private_key, update_private_key, /* How to load and */
private_key_filename, /* update the private key */
0, /* Use minimal memory */
aux_data, len_aux_data, /* The auxiliary data */
0); /* Use the defaults for extra info */
Expand Down Expand Up @@ -517,8 +517,6 @@ static int sign(const char *keyname, char **files) {
(void)hss_sign_init(
&ctx, /* Incremental signing context */
w, /* Working key */
update_private_key, /* Routine to update the */
private_key_filename, /* private key */
sig, sig_len, /* Where to place the signature */
0); /* Use the defaults for extra info */

Expand Down Expand Up @@ -712,8 +710,8 @@ static int advance(const char *keyname, const char *text_advance) {
printf( "Loading private key\n" );
fflush(stdout);
struct hss_working_key *w = hss_load_private_key(
read_private_key, private_key_filename, /* How to load the */
/* private key */
read_private_key, update_private_key, /* How to load and */
private_key_filename, /* update the private key */
0, /* Use minimal memory */
aux_data, len_aux_data, /* The auxiliary data */
0); /* Use the defaults for extra info */
Expand All @@ -729,9 +727,7 @@ static int advance(const char *keyname, const char *text_advance) {
/* Now that we've loaded the private key, we fast-forward it */
/* We do this by reserving N signatures (which updates the private */
/* key to reflect that we've generated those signatures) */
bool success = hss_reserve_signature( w,
update_private_key, private_key_filename,
advance, 0 );
bool success = hss_reserve_signature( w, advance, 0 );
if (!success) {
printf( "Error advancing\n" );
}
Expand Down
Loading