diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9f9df9be7..68f444e28 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -34,24 +34,24 @@ jobs: cc: [ gcc, clang ] os: [ ubuntu-20.04, ubuntu-22.04 ] config: - - { BUILDNAME: 'META_BUILDS', BUILDOPTIONS: '-DGMP_DESC', BUILDSCRIPT: '.ci/meta_builds.sh' } - - { BUILDNAME: 'VALGRIND', BUILDOPTIONS: '', BUILDSCRIPT: '.ci/valgrind.sh' } - - { BUILDNAME: 'STOCK', BUILDOPTIONS: '', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'STOCK-MPI', BUILDOPTIONS: '-ULTM_DESC -UTFM_DESC -UUSE_LTM -UUSE_TFM', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'STOCK+AESNI', BUILDOPTIONS: '-msse4.1 -maes', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'EASY', BUILDOPTIONS: '-DLTC_EASY', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'SMALL', BUILDOPTIONS: '-DLTC_SMALL_CODE', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'NOTABLES', BUILDOPTIONS: '-DLTC_NO_TABLES', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'SMALL+NOTABLES', BUILDOPTIONS: '-DLTC_SMALL_CODE -DLTC_NO_TABLES', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'NO_FAST', BUILDOPTIONS: '-DLTC_NO_FAST', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'NO_FAST+NOTABLES', BUILDOPTIONS: '-DLTC_NO_FAST -DLTC_NO_TABLES', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'NO_ASM', BUILDOPTIONS: '-DLTC_NO_ASM', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'NO_TIMING_RESISTANCE', BUILDOPTIONS: '-DLTC_NO_ECC_TIMING_RESISTANT -DLTC_NO_RSA_BLINDING', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'PTHREAD', BUILDOPTIONS: '-DLTC_PTHREAD', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'STOCK+ARGTYPE=1', BUILDOPTIONS: '-DARGTYPE=1', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'STOCK+ARGTYPE=2', BUILDOPTIONS: '-DARGTYPE=2', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'STOCK+ARGTYPE=3', BUILDOPTIONS: '-DARGTYPE=3', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'STOCK+ARGTYPE=4', BUILDOPTIONS: '-DARGTYPE=4', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'META_BUILDS', BUILDOPTIONS: '-DGMP_DESC', BUILDSCRIPT: '.ci/meta_builds.sh' } + - { BUILDNAME: 'VALGRIND', BUILDOPTIONS: '', BUILDSCRIPT: '.ci/valgrind.sh' } + - { BUILDNAME: 'STOCK', BUILDOPTIONS: '', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'STOCK-MPI', BUILDOPTIONS: '-ULTM_DESC -UTFM_DESC -UUSE_LTM -UUSE_TFM', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'STOCK+AESNI', BUILDOPTIONS: '-msse4.1 -maes', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'EASY', BUILDOPTIONS: '-DLTC_EASY', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'SMALL', BUILDOPTIONS: '-DLTC_SMALL_CODE', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'NO_TABLES', BUILDOPTIONS: '-DLTC_NO_TABLES', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'NO_FAST', BUILDOPTIONS: '-DLTC_NO_FAST', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'NO_FAST+SMALL+NO_TABLES', BUILDOPTIONS: '-DLTC_NO_FAST -DLTC_SMALL_CODE -DLTC_NO_TABLES', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'NO_ASM', BUILDOPTIONS: '-DLTC_NO_ASM', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'NO_TIMING_RESISTANCE', BUILDOPTIONS: '-DLTC_NO_ECC_TIMING_RESISTANT -DLTC_NO_RSA_BLINDING', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'FORTUNA_CUSTOM_OPTIONS', BUILDOPTIONS: '-DLTC_FORTUNA_USE_ENCRYPT_ONLY -DLTC_FORTUNA_RESEED_RATELIMIT_STATIC', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'PTHREAD', BUILDOPTIONS: '-DLTC_PTHREAD', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'STOCK+ARGTYPE=1', BUILDOPTIONS: '-DARGTYPE=1', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'STOCK+ARGTYPE=2', BUILDOPTIONS: '-DARGTYPE=2', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'STOCK+ARGTYPE=3', BUILDOPTIONS: '-DARGTYPE=3', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'STOCK+ARGTYPE=4', BUILDOPTIONS: '-DARGTYPE=4', BUILDSCRIPT: '.ci/run.sh' } steps: - uses: actions/checkout@v2 - name: install dependencies diff --git a/src/ciphers/aes/aes_desc.c b/src/ciphers/aes/aes_desc.c index 5b42d92bc..4b930a5e9 100644 --- a/src/ciphers/aes/aes_desc.c +++ b/src/ciphers/aes/aes_desc.c @@ -34,6 +34,7 @@ const struct ltc_cipher_descriptor aes_desc = #define AES_SETUP aes_enc_setup #define AES_ENC aes_enc_ecb_encrypt #define AES_DONE aes_enc_done +#define AES_TEST aes_enc_test #define AES_KS aes_enc_keysize const struct ltc_cipher_descriptor aes_enc_desc = @@ -119,6 +120,7 @@ int AES_ENC(const unsigned char *pt, unsigned char *ct, const symmetric_key *ske } +#ifndef ENCRYPT_ONLY /** Decrypts a block of text with AES @param ct The input ciphertext (16 bytes) @@ -135,6 +137,7 @@ int AES_DEC(const unsigned char *ct, unsigned char *pt, const symmetric_key *ske #endif return rijndael_ecb_decrypt(ct, pt, skey); } +#endif /* ENCRYPT_ONLY */ /** Performs a self-test of the AES block cipher @@ -181,26 +184,33 @@ int AES_TEST(void) symmetric_key key; unsigned char tmp[2][16]; - int i, y; + int i; +#ifndef ENCRYPT_ONLY + int y; +#endif for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { zeromem(&key, sizeof(key)); - if ((err = aes_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + if ((err = AES_SETUP(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { return err; } - aes_ecb_encrypt(tests[i].pt, tmp[0], &key); - aes_ecb_decrypt(tmp[0], tmp[1], &key); - if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "AES Encrypt", i) || - compare_testvector(tmp[1], 16, tests[i].pt, 16, "AES Decrypt", i)) { + AES_ENC(tests[i].pt, tmp[0], &key); + if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "AES Encrypt", i)) { + return CRYPT_FAIL_TESTVECTOR; + } +#ifndef ENCRYPT_ONLY + AES_DEC(tmp[0], tmp[1], &key); + if (compare_testvector(tmp[1], 16, tests[i].pt, 16, "AES Decrypt", i)) { return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 16; y++) tmp[0][y] = 0; - for (y = 0; y < 1000; y++) aes_ecb_encrypt(tmp[0], tmp[0], &key); - for (y = 0; y < 1000; y++) aes_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) AES_ENC(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) AES_DEC(tmp[0], tmp[0], &key); for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; +#endif } return CRYPT_OK; #endif diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index 8b6f8781f..aeee34355 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -699,6 +699,7 @@ void aes_done(symmetric_key *skey); int aes_keysize(int *keysize); int aes_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int aes_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey); +int aes_enc_test(void); void aes_enc_done(symmetric_key *skey); int aes_enc_keysize(int *keysize); extern const struct ltc_cipher_descriptor aes_desc; diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h index 129f0245f..e10779280 100644 --- a/src/headers/tomcrypt_custom.h +++ b/src/headers/tomcrypt_custom.h @@ -375,9 +375,9 @@ /* with non-glibc or glibc 2.17+ prefer clock_gettime over gettimeofday */ #if defined(__GLIBC__) && defined(__GLIBC_PREREQ) -#if __GLIBC_PREREQ(2, 17) - #define LTC_CLOCK_GETTIME -#endif + #if __GLIBC_PREREQ(2, 17) + #define LTC_CLOCK_GETTIME + #endif #elif defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L #define LTC_CLOCK_GETTIME #endif @@ -407,6 +407,11 @@ #define LTC_FORTUNA_POOLS 32 #endif +/* at compile time you can decide whether fortuna uses the regular AES APIs + * or whether it will use the 'encrypt_only' variants. + * This is useful for custom builds of libtomcrypt for size-constrained targets. */ +/* #define LTC_FORTUNA_USE_ENCRYPT_ONLY */ + #endif /* LTC_FORTUNA */ diff --git a/src/misc/crypt/crypt.c b/src/misc/crypt/crypt.c index f91ae06ff..81f00dbf9 100644 --- a/src/misc/crypt/crypt.c +++ b/src/misc/crypt/crypt.c @@ -315,9 +315,12 @@ const char *crypt_build_settings = #if defined(LTC_FORTUNA) " Fortuna (" NAME_VALUE(LTC_FORTUNA_POOLS) ", " #if defined(LTC_FORTUNA_RESEED_RATELIMIT_TIMED) - "LTC_FORTUNA_RESEED_RATELIMIT_TIMED, " + "LTC_FORTUNA_RESEED_RATELIMIT_TIMED" #else "LTC_FORTUNA_RESEED_RATELIMIT_STATIC, " NAME_VALUE(LTC_FORTUNA_WD) +#endif +#if defined(LTC_FORTUNA_USE_ENCRYPT_ONLY) + ", LTC_FORTUNA_USE_ENCRYPT_ONLY" #endif ")\n" #endif diff --git a/src/prngs/fortuna.c b/src/prngs/fortuna.c index 6f500986c..9c92595e9 100644 --- a/src/prngs/fortuna.c +++ b/src/prngs/fortuna.c @@ -39,6 +39,18 @@ we reseed automatically when len(pool0) >= 64 or every LTC_FORTUNA_WD calls to t #error LTC_FORTUNA_POOLS must be in [4..32] #endif +#ifdef LTC_FORTUNA_USE_ENCRYPT_ONLY +#define AES_SETUP aes_enc_setup +#define AES_ENC aes_enc_ecb_encrypt +#define AES_DONE aes_enc_done +#define AES_TEST aes_enc_test +#else +#define AES_SETUP aes_setup +#define AES_ENC aes_ecb_encrypt +#define AES_DONE aes_done +#define AES_TEST aes_test +#endif + const struct ltc_prng_descriptor fortuna_desc = { "fortuna", 64, @@ -146,7 +158,7 @@ static int s_fortuna_reseed(prng_state *prng) if ((err = sha256_done(&md, prng->u.fortuna.K)) != CRYPT_OK) { return err; } - if ((err = rijndael_setup(prng->u.fortuna.K, 32, 0, &prng->u.fortuna.skey)) != CRYPT_OK) { + if ((err = AES_SETUP(prng->u.fortuna.K, 32, 0, &prng->u.fortuna.skey)) != CRYPT_OK) { return err; } s_fortuna_update_iv(prng); @@ -236,7 +248,7 @@ int fortuna_start(prng_state *prng) /* reset bufs */ zeromem(prng->u.fortuna.K, 32); - if ((err = rijndael_setup(prng->u.fortuna.K, 32, 0, &prng->u.fortuna.skey)) != CRYPT_OK) { + if ((err = AES_SETUP(prng->u.fortuna.K, 32, 0, &prng->u.fortuna.skey)) != CRYPT_OK) { for (x = 0; x < LTC_FORTUNA_POOLS; x++) { sha256_done(&prng->u.fortuna.pool[x], tmp); } @@ -395,7 +407,7 @@ unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state /* handle whole blocks without the extra XMEMCPY */ while (outlen >= 16) { /* encrypt the IV and store it */ - rijndael_ecb_encrypt(prng->u.fortuna.IV, out, &prng->u.fortuna.skey); + AES_ENC(prng->u.fortuna.IV, out, &prng->u.fortuna.skey); out += 16; outlen -= 16; s_fortuna_update_iv(prng); @@ -403,19 +415,19 @@ unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state /* left over bytes? */ if (outlen > 0) { - rijndael_ecb_encrypt(prng->u.fortuna.IV, tmp, &prng->u.fortuna.skey); + AES_ENC(prng->u.fortuna.IV, tmp, &prng->u.fortuna.skey); XMEMCPY(out, tmp, outlen); s_fortuna_update_iv(prng); } /* generate new key */ - rijndael_ecb_encrypt(prng->u.fortuna.IV, prng->u.fortuna.K , &prng->u.fortuna.skey); + AES_ENC(prng->u.fortuna.IV, prng->u.fortuna.K , &prng->u.fortuna.skey); s_fortuna_update_iv(prng); - rijndael_ecb_encrypt(prng->u.fortuna.IV, prng->u.fortuna.K+16, &prng->u.fortuna.skey); + AES_ENC(prng->u.fortuna.IV, prng->u.fortuna.K+16, &prng->u.fortuna.skey); s_fortuna_update_iv(prng); - if (rijndael_setup(prng->u.fortuna.K, 32, 0, &prng->u.fortuna.skey) != CRYPT_OK) { + if (AES_SETUP(prng->u.fortuna.K, 32, 0, &prng->u.fortuna.skey) != CRYPT_OK) { tlen = 0; } @@ -512,7 +524,7 @@ int fortuna_test(void) if ((err = sha256_test()) != CRYPT_OK) { return err; } - return rijndael_test(); + return AES_TEST(); #endif } diff --git a/tests/cipher_hash_test.c b/tests/cipher_hash_test.c index 4ddc0755d..431a7648c 100644 --- a/tests/cipher_hash_test.c +++ b/tests/cipher_hash_test.c @@ -20,6 +20,7 @@ int cipher_hash_test(void) } DO(rijndael_test()); #endif + DO(aes_enc_test()); /* test stream ciphers */ #ifdef LTC_CHACHA