diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 8cd461414..eed63fdd1 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,7 +2,11 @@ Thank you for your pull request. -If this fixes an existing github issue, make sure to have a line saying 'Fixes #XXXX' (without quotes) in the commit message. +If this fixes an existing github issue, make sure to have a line saying 'Fixes: ' (without quotes) in the commit message. +Please use the long format to refer to an issue 'libtom/libtomcrypt#'. + +If this fixes something (even if there exists no github issue), make sure to have a line saying 'Fixes: ("Description")' +This can be created via e.g. `git --no-pager log -1 --pretty=fixes --> @@ -11,3 +15,4 @@ If this fixes an existing github issue, make sure to have a line saying 'Fixes # * [ ] documentation is added or updated * [ ] tests are added or updated +* [ ] if this fixes something: added a `Fixes:` tag to the commit message diff --git a/appveyor.yml b/appveyor.yml index 29cbf812b..655f2be2e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -31,10 +31,12 @@ build_script: cp test.exe test-stock.exe cp timing.exe timing-stock.exe nmake -f makefile.msvc clean - nmake -f makefile.msvc all CFLAGS="/Ox /DUSE_LTM /DLTM_DESC /DLTC_NO_AES_NI /I../libtommath" + nmake -f makefile.msvc all CFLAGS="/Ox /DUSE_LTM /DLTM_DESC /DLTC_NO_ACCEL /I../libtommath" test_script: - cmd: >- test-stock.exe test.exe - timing-stock.exe cipher_ecb - timing.exe cipher_ecb + timing-stock.exe cipher_ecb aes + timing.exe cipher_ecb aes + timing-stock.exe hash sha + timing.exe hash sha diff --git a/demos/timing.c b/demos/timing.c index 1d9bd5ca8..a5e177cfb 100644 --- a/demos/timing.c +++ b/demos/timing.c @@ -1054,130 +1054,206 @@ static void time_ecc(void) static void time_ecc(void) { fprintf(stderr, "NO ECC\n"); } #endif -static void time_macs_(unsigned long MAC_SIZE) +typedef struct mac_ctx { + unsigned char *buf, key[32], tag[16]; + unsigned long size; + int cipher_idx, hash_idx; +} mac_ctx; + +#ifdef LTC_OMAC +static void time_omac(mac_ctx *ctx) { -#if defined(LTC_OMAC) || defined(LTC_XCBC) || defined(LTC_F9_MODE) || defined(LTC_PMAC) || defined(LTC_PELICAN) || defined(LTC_HMAC) - unsigned char *buf, key[16], tag[16]; ulong64 t1, t2; unsigned long x, z; - int err, cipher_idx, hash_idx; - - fprintf(stderr, "\nMAC Timings (cycles/byte on %luKB blocks):\n", MAC_SIZE); - - buf = XMALLOC(MAC_SIZE*1024); - if (buf == NULL) { - fprintf(stderr, "\n\nout of heap yo\n\n"); - exit(EXIT_FAILURE); - } - - cipher_idx = find_cipher("aes"); - hash_idx = find_hash("sha1"); + int err; - if (cipher_idx == -1 || hash_idx == -1) { - fprintf(stderr, "Warning the MAC tests requires AES and SHA1 to operate... so sorry\n"); - exit(EXIT_FAILURE); - } - - yarrow_read(buf, MAC_SIZE*1024, &yarrow_prng); - yarrow_read(key, 16, &yarrow_prng); - -#ifdef LTC_OMAC t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = omac_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { - fprintf(stderr, "\n\nomac-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err)); + if ((err = omac_memory(ctx->cipher_idx, ctx->key, 16, ctx->buf, ctx->size, ctx->tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\nomac-%s error... %s\n", cipher_descriptor[ctx->cipher_idx].name, error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "OMAC-%s\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "OMAC-%s\t\t%9"PRI64"u\n", cipher_descriptor[ctx->cipher_idx].name, t2/(ulong64)(ctx->size)); +} #endif #ifdef LTC_XCBC +static void time_xcbc(mac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = xcbc_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { - fprintf(stderr, "\n\nxcbc-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err)); + if ((err = xcbc_memory(ctx->cipher_idx, ctx->key, 16, ctx->buf, ctx->size, ctx->tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\nxcbc-%s error... %s\n", cipher_descriptor[ctx->cipher_idx].name, error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "XCBC-%s\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "XCBC-%s\t\t%9"PRI64"u\n", cipher_descriptor[ctx->cipher_idx].name, t2/(ulong64)(ctx->size)); +} #endif #ifdef LTC_F9_MODE +static void time_f9(mac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = f9_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { - fprintf(stderr, "\n\nF9-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err)); + if ((err = f9_memory(ctx->cipher_idx, ctx->key, 16, ctx->buf, ctx->size, ctx->tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\nF9-%s error... %s\n", cipher_descriptor[ctx->cipher_idx].name, error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "F9-%s\t\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "F9-%s\t\t\t%9"PRI64"u\n", cipher_descriptor[ctx->cipher_idx].name, t2/(ulong64)(ctx->size)); +} #endif #ifdef LTC_PMAC +static void time_pmac(mac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = pmac_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { - fprintf(stderr, "\n\npmac-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err)); + if ((err = pmac_memory(ctx->cipher_idx, ctx->key, 16, ctx->buf, ctx->size, ctx->tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\npmac-%s error... %s\n", cipher_descriptor[ctx->cipher_idx].name, error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "PMAC-%s\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "PMAC-%s\t\t%9"PRI64"u\n", cipher_descriptor[ctx->cipher_idx].name, t2/(ulong64)(ctx->size)); +} #endif #ifdef LTC_PELICAN +static void time_pelican(mac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x; + int err; + t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); - z = 16; - if ((err = pelican_memory(key, 16, buf, MAC_SIZE*1024, tag)) != CRYPT_OK) { + if ((err = pelican_memory(ctx->key, 16, ctx->buf, ctx->size, ctx->tag)) != CRYPT_OK) { fprintf(stderr, "\n\npelican error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "PELICAN \t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "PELICAN \t\t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); +} #endif #ifdef LTC_HMAC +static void time_hmac(mac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = hmac_memory(hash_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { - fprintf(stderr, "\n\nhmac-%s error... %s\n", hash_descriptor[hash_idx].name, error_to_string(err)); + if ((err = hmac_memory(ctx->hash_idx, ctx->key, 16, ctx->buf, ctx->size, ctx->tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\nhmac-%s error... %s\n", hash_descriptor[ctx->hash_idx].name, error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "HMAC-%s\t\t%9"PRI64"u\n", hash_descriptor[hash_idx].name, t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "HMAC-%s\t\t%9"PRI64"u\n", hash_descriptor[ctx->hash_idx].name, t2/(ulong64)(ctx->size)); +} +#endif + +static void time_macs_(unsigned long MAC_SIZE) +{ +#if defined(LTC_OMAC) || defined(LTC_XCBC) || defined(LTC_F9_MODE) || defined(LTC_PMAC) || defined(LTC_PELICAN) || defined(LTC_HMAC) + mac_ctx ctx; + struct { + const char *name; + void (*time_fun)(mac_ctx*); + } time_funs[] = { +#define TIME_FUN(n) { #n, time_ ## n } +#ifdef LTC_OMAC + TIME_FUN(omac), +#endif +#ifdef LTC_XCBC + TIME_FUN(xcbc), +#endif +#ifdef LTC_F9_MODE + TIME_FUN(f9), #endif +#ifdef LTC_PMAC + TIME_FUN(pmac), +#endif +#ifdef LTC_PELICAN + TIME_FUN(pelican), +#endif +#ifdef LTC_HMAC + TIME_FUN(hmac), +#endif +#undef TIME_FUN + }; + unsigned long n; + + fprintf(stderr, "\nMAC Timings (cycles/byte on %luKB blocks):\n", MAC_SIZE); + + ctx.size = MAC_SIZE*1024; + ctx.buf = XMALLOC(ctx.size); + if (ctx.buf == NULL) { + fprintf(stderr, "\n\nout of heap yo\n\n"); + exit(EXIT_FAILURE); + } + + ctx.cipher_idx = find_cipher("aes"); + ctx.hash_idx = find_hash("sha1"); + + if (ctx.cipher_idx == -1 || ctx.hash_idx == -1) { + fprintf(stderr, "Warning the MAC tests requires AES and SHA1 to operate... so sorry\n"); + exit(EXIT_FAILURE); + } + + yarrow_read(ctx.buf, ctx.size, &yarrow_prng); + yarrow_read(ctx.key, 16, &yarrow_prng); + + for (n = 0; n < LTC_ARRAY_SIZE(time_funs); ++n) { + if (!should_skip(time_funs[n].name)) + time_funs[n].time_fun(&ctx); + } - XFREE(buf); + XFREE(ctx.buf); #else LTC_UNUSED_PARAM(MAC_SIZE); fprintf(stderr, "NO MACs\n"); @@ -1191,137 +1267,147 @@ static void time_macs(void) time_macs_(32); } -static void time_encmacs_(unsigned long MAC_SIZE) -{ -#if defined(LTC_EAX_MODE) || defined(LTC_OCB_MODE) || defined(LTC_OCB3_MODE) || \ - defined(LTC_CCM_MODE) || defined(LTC_GCM_MODE) || defined(LTC_SIV_MODE) -#if defined(LTC_SIV_MODE) - unsigned char *aad[4]; - unsigned long buflen; -#endif +typedef struct eac_ctx { unsigned char *buf, IV[16], key[32], tag[16]; + unsigned long size; + int cipher_idx; +} eac_ctx; + +#ifdef LTC_EAX_MODE +static void time_eax(eac_ctx *ctx) +{ ulong64 t1, t2; unsigned long x, z; - int err, cipher_idx; - symmetric_ECB skey; - - fprintf(stderr, "\nENC+MAC Timings (zero byte AAD, 16 byte IV, cycles/byte on %luKB blocks):\n", MAC_SIZE); + int err; - buf = XMALLOC(MAC_SIZE*1024); - if (buf == NULL) { - fprintf(stderr, "\n\nout of heap yo\n\n"); - exit(EXIT_FAILURE); - } - - cipher_idx = find_cipher("aes"); - - yarrow_read(buf, MAC_SIZE*1024, &yarrow_prng); - yarrow_read(key, sizeof(key), &yarrow_prng); - yarrow_read(IV, sizeof(IV), &yarrow_prng); - -#ifdef LTC_EAX_MODE t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = eax_encrypt_authenticate_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) { + if ((err = eax_encrypt_authenticate_memory(ctx->cipher_idx, ctx->key, 16, ctx->IV, 16, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z)) != CRYPT_OK) { fprintf(stderr, "\nEAX error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "EAX \t\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "EAX \t\t\t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); +} #endif -#ifdef LTC_OCB_MODE +#if defined(LTC_OCB_MODE) +static void time_ocb(eac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = ocb_encrypt_authenticate_memory(cipher_idx, key, 16, IV, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) { + if ((err = ocb_encrypt_authenticate_memory(ctx->cipher_idx, ctx->key, 16, ctx->IV, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z)) != CRYPT_OK) { fprintf(stderr, "\nOCB error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "OCB \t\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "OCB \t\t\t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); +} #endif -#ifdef LTC_OCB3_MODE +#if defined(LTC_OCB3_MODE) +static void time_ocb3(eac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = ocb3_encrypt_authenticate_memory(cipher_idx, key, 16, IV, 15, (unsigned char*)"", 0, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) { + if ((err = ocb3_encrypt_authenticate_memory(ctx->cipher_idx, ctx->key, 16, ctx->IV, 15, (unsigned char*)"", 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z)) != CRYPT_OK) { fprintf(stderr, "\nOCB3 error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "OCB3 \t\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "OCB3 \t\t\t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); +} #endif -#ifdef LTC_CCM_MODE +#if defined(LTC_CCM_MODE) +static void time_ccm(eac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + symmetric_ECB skey; + t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = ccm_memory(cipher_idx, key, 16, NULL, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, CCM_ENCRYPT)) != CRYPT_OK) { + if ((err = ccm_memory(ctx->cipher_idx, ctx->key, 16, NULL, ctx->IV, 16, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z, CCM_ENCRYPT)) != CRYPT_OK) { fprintf(stderr, "\nCCM error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "CCM (no-precomp) \t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "CCM (no-precomp) \t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); - ecb_start(cipher_idx, key, 16, 0, &skey); + ecb_start(ctx->cipher_idx, ctx->key, 16, 0, &skey); t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = ccm_memory(cipher_idx, key, 16, &skey, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, CCM_ENCRYPT)) != CRYPT_OK) { + if ((err = ccm_memory(ctx->cipher_idx, ctx->key, 16, &skey, ctx->IV, 16, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z, CCM_ENCRYPT)) != CRYPT_OK) { fprintf(stderr, "\nCCM error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "CCM (precomp) \t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "CCM (precomp) \t\t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); ecb_done(&skey); +} #endif -#ifdef LTC_GCM_MODE +#if defined (LTC_GCM_MODE) +static void time_gcm(eac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + gcm_state gcm +#ifdef LTC_GCM_TABLES_SSE2 +__attribute__ ((aligned (16))) +#endif +; t2 = -1; for (x = 0; x < 100; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = gcm_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, GCM_ENCRYPT)) != CRYPT_OK) { + if ((err = gcm_memory(ctx->cipher_idx, ctx->key, 16, ctx->IV, 16, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z, GCM_ENCRYPT)) != CRYPT_OK) { fprintf(stderr, "\nGCM error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "GCM (no-precomp)\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); - - { - gcm_state gcm -#ifdef LTC_GCM_TABLES_SSE2 -__attribute__ ((aligned (16))) -#endif -; + fprintf(stderr, "GCM (no-precomp)\t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); - if ((err = gcm_init(&gcm, cipher_idx, key, 16)) != CRYPT_OK) { fprintf(stderr, "gcm_init: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } + if ((err = gcm_init(&gcm, ctx->cipher_idx, ctx->key, 16)) != CRYPT_OK) { fprintf(stderr, "gcm_init: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t2 = -1; for (x = 0; x < 10000; x++) { t_start(); @@ -1331,7 +1417,7 @@ __attribute__ ((aligned (16))) fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } - if ((err = gcm_add_iv(&gcm, IV, 16)) != CRYPT_OK) { + if ((err = gcm_add_iv(&gcm, ctx->IV, 16)) != CRYPT_OK) { fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } @@ -1339,36 +1425,44 @@ __attribute__ ((aligned (16))) fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } - if ((err = gcm_process(&gcm, buf, MAC_SIZE*1024, buf, GCM_ENCRYPT)) != CRYPT_OK) { + if ((err = gcm_process(&gcm, ctx->buf, ctx->size, ctx->buf, GCM_ENCRYPT)) != CRYPT_OK) { fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } - if ((err = gcm_done(&gcm, tag, &z)) != CRYPT_OK) { + if ((err = gcm_done(&gcm, ctx->tag, &z)) != CRYPT_OK) { fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "GCM (precomp)\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); - } + fprintf(stderr, "GCM (precomp)\t\t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); +} #endif -#ifdef LTC_SIV_MODE +#if defined(LTC_SIV_MODE) +static void time_siv(eac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + unsigned char *aad[4]; + unsigned long buflen; + for(z = 0; z < 4; z++) { - aad[z] = IV + z * 4; + aad[z] = ctx->IV + z * 4; } for(z = 0; z < 4; z++) { t2 = -1; for (x = 0; x < 10000; x++) { - buflen = MAC_SIZE*1024; + buflen = ctx->size; t_start(); t1 = t_read(); - if ((err = siv_memory(cipher_idx, LTC_ENCRYPT, - key, 32, - buf, MAC_SIZE*1024 - 16, - buf, &buflen, + if ((err = siv_memory(ctx->cipher_idx, LTC_ENCRYPT, + ctx->key, 32, + ctx->buf, ctx->size - 16, + ctx->buf, &buflen, aad[0], 16, aad[1], 12, aad[2], 8, @@ -1381,11 +1475,64 @@ __attribute__ ((aligned (16))) if (t1 < t2) t2 = t1; } aad[3-z] = NULL; - fprintf(stderr, "SIV (%lu x AAD)\t\t%9"PRI64"u\n", 4-z, t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "SIV (%lu x AAD)\t\t%9"PRI64"u\n", 4-z, t2/(ulong64)(ctx->size)); } +} +#endif + +static void time_eacs_(unsigned long MAC_SIZE) +{ +#if defined(LTC_EAX_MODE) || defined(LTC_OCB_MODE) || defined(LTC_OCB3_MODE) || \ + defined(LTC_CCM_MODE) || defined(LTC_GCM_MODE) || defined(LTC_SIV_MODE) + eac_ctx ctx; + struct { + const char *name; + void (*time_fun)(eac_ctx*); + } time_funs[] = { +#define TIME_FUN(n) { #n, time_ ## n } +#ifdef LTC_EAX_MODE + TIME_FUN(eax), #endif +#ifdef LTC_OCB_MODE + TIME_FUN(ocb), +#endif +#ifdef LTC_OCB3_MODE + TIME_FUN(ocb3), +#endif +#ifdef LTC_CCM_MODE + TIME_FUN(ccm), +#endif +#ifdef LTC_GCM_MODE + TIME_FUN(gcm), +#endif +#ifdef LTC_SIV_MODE + TIME_FUN(siv), +#endif +#undef TIME_FUN + }; + unsigned long n; + + fprintf(stderr, "\nENC+MAC Timings (zero byte AAD, 16 byte IV, cycles/byte on %luKB blocks):\n", MAC_SIZE); + + ctx.size = MAC_SIZE*1024; + ctx.buf = XMALLOC(ctx.size); + if (ctx.buf == NULL) { + fprintf(stderr, "\n\nout of heap yo\n\n"); + exit(EXIT_FAILURE); + } + + ctx.cipher_idx = find_cipher("aes"); + + yarrow_read(ctx.buf, ctx.size, &yarrow_prng); + yarrow_read(ctx.key, sizeof(ctx.key), &yarrow_prng); + yarrow_read(ctx.IV, sizeof(ctx.IV), &yarrow_prng); + + for (n = 0; n < LTC_ARRAY_SIZE(time_funs); ++n) { + if (!should_skip(time_funs[n].name)) + time_funs[n].time_fun(&ctx); + } - XFREE(buf); + XFREE(ctx.buf); #else LTC_UNUSED_PARAM(MAC_SIZE); fprintf(stderr, "NO ENCMACs\n"); @@ -1393,11 +1540,11 @@ __attribute__ ((aligned (16))) } -static void time_encmacs(void) +static void time_eacs(void) { - time_encmacs_(1); - time_encmacs_(4); - time_encmacs_(32); + time_eacs_(1); + time_eacs_(4); + time_eacs_(32); } static void LTC_NORETURN die(int status) @@ -1434,7 +1581,7 @@ const struct LTC_TEST_FN(cipher_lrw), LTC_TEST_FN(hash), LTC_TEST_FN(macs), - LTC_TEST_FN(encmacs), + LTC_TEST_FN(eacs), LTC_TEST_FN(prng), LTC_TEST_FN(mult), LTC_TEST_FN(sqr), diff --git a/doc/crypt.tex b/doc/crypt.tex index fc879fa9a..0328543e5 100644 --- a/doc/crypt.tex +++ b/doc/crypt.tex @@ -3027,10 +3027,15 @@ \subsection{Hash Registration} applicable block ciphers (such as AES) can be turned into hash functions that other LTC functions can use. In particular this allows a cryptosystem to be designed using very few moving parts. +The \code{CHC} mode implements a Miyaguchi–Preneel Hash Construction +\footnote{\href{https://en.wikipedia.org/wiki/One-way_compression_function\#Miyaguchi–Preneel}{\nolinkurl{https://en.wikipedia.org/wiki/One-way_compression_function\#Miyaguchi-Preneel}}} +(MPHC), but provides an improved, \code{chc\_done()} implementation. + + In order to use the CHC system the developer will have to take a few extra steps. First the \textit{chc\_desc} hash -descriptor must be registered with register\_hash(). At this point the CHC hash cannot be used to hash +descriptor must be registered with \code{register\_hash()}. At this point the CHC hash cannot be used to hash data. While it is in the hash system you still have to tell the CHC code which cipher to use. This is accomplished -via the chc\_register() function. +via the \code{chc\_register()} function. \index{chc\_register()} \begin{verbatim} @@ -3038,7 +3043,7 @@ \subsection{Hash Registration} \end{verbatim} A cipher has to be registered with CHC (and also in the cipher descriptor tables with -register\_cipher()). The chc\_register() function will bind a cipher to the CHC system. Only one cipher can +\code{register\_cipher()}). The \code{chc\_register()} function will bind a cipher to the CHC system. Only one cipher can be bound to the CHC hash at a time. There are additional requirements for the system to work. \begin{enumerate} diff --git a/src/ciphers/aes/aes_desc.c b/src/ciphers/aes/aes_desc.c index 2ff913e83..c03e1bb36 100644 --- a/src/ciphers/aes/aes_desc.c +++ b/src/ciphers/aes/aes_desc.c @@ -9,6 +9,60 @@ #include "tomcrypt_private.h" +#if defined(LTC_ARCH_X86) && (defined(LTC_AES_NI) || !defined(ENCRYPT_ONLY)) + +#if !defined (LTC_S_X86_CPUID) +#define LTC_S_X86_CPUID +static LTC_INLINE void s_x86_cpuid(int* regs, int leaf) +{ +#if defined _MSC_VER + __cpuid(regs, leaf); +#else + int a, b, c, d; + + a = leaf; + b = c = d = 0; + asm volatile ("cpuid" + :"=a"(a), "=b"(b), "=c"(c), "=d"(d) + :"a"(a), "c"(c) + ); + regs[0] = a; + regs[1] = b; + regs[2] = c; + regs[3] = d; +#endif +} +#endif /* LTC_S_X86_CPUID */ + +static LTC_INLINE int s_aesni_is_supported(void) +{ + static int initialized = 0, is_supported = 0; + + if (initialized == 0) { + /* Look for CPUID.1.0.ECX[19] (SSE4.1) and CPUID.1.0.ECX[25] (AES-NI) + * EAX = 1, ECX = 0 + */ + int regs[4]; + s_x86_cpuid(regs, 1); + is_supported = ((regs[2] >> 19) & 1) && ((regs[2] >> 25) & 1); + initialized = 1; + } + + return is_supported; +} +#endif /* LTC_ARCH_X86 */ + +#ifndef ENCRYPT_ONLY +int aesni_is_supported(void) +{ +#if defined(LTC_ARCH_X86) + return s_aesni_is_supported(); +#else + return 0; +#endif +} +#endif /* ENCRYPT_ONLY */ + #if defined(LTC_RIJNDAEL) #ifndef ENCRYPT_ONLY @@ -46,54 +100,6 @@ const struct ltc_cipher_descriptor aes_enc_desc = NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; -#endif - -/* Code partially borrowed from https://software.intel.com/content/www/us/en/develop/articles/intel-sha-extensions.html */ -#if defined(LTC_AES_NI) -static LTC_INLINE int s_aesni_is_supported(void) -{ - static int initialized = 0, is_supported = 0; - - if (initialized == 0) { - int a, b, c, d; - - /* Look for CPUID.1.0.ECX[19] (SSE4.1) and CPUID.1.0.ECX[25] (AES-NI) - * EAX = 1, ECX = 0 - */ - a = 1; - c = 0; - -#if defined(_MSC_VER) && !defined(__clang__) - int arr[4]; - __cpuidex(arr, a, c); - a = arr[0]; - b = arr[1]; - c = arr[2]; - d = arr[3]; -#else - __asm__ volatile ("cpuid" - :"=a"(a), "=b"(b), "=c"(c), "=d"(d) - :"a"(a), "c"(c) - ); -#endif - - is_supported = ((c >> 19) & 1) && ((c >> 25) & 1); - initialized = 1; - } - - return is_supported; -} -#endif - -#ifndef ENCRYPT_ONLY -int aesni_is_supported(void) -{ -#ifdef LTC_AES_NI - return s_aesni_is_supported(); -#else - return 0; -#endif -} #endif /** diff --git a/src/encauth/gcm/gcm_gf_mult.c b/src/encauth/gcm/gcm_gf_mult.c index 0b7a1c83c..10d0ef754 100644 --- a/src/encauth/gcm/gcm_gf_mult.c +++ b/src/encauth/gcm/gcm_gf_mult.c @@ -9,6 +9,9 @@ #if defined(LTC_GCM_MODE) || defined(LTC_LRW_MODE) #if defined(LTC_GCM_PCLMUL) + +#define LTC_GCM_PCLMUL_TARGET LTC_ATTRIBUTE((__target__("pclmul,ssse3"))) + #if defined(_MSC_VER) #include #else @@ -18,27 +21,38 @@ #include #include +#if !defined (LTC_S_X86_CPUID) +#define LTC_S_X86_CPUID +static LTC_INLINE void s_x86_cpuid(int* regs, int leaf) +{ +#if defined _MSC_VER + __cpuid(regs, leaf); +#else + int a, b, c, d; + + a = leaf; + b = c = d = 0; + asm volatile ("cpuid" + :"=a"(a), "=b"(b), "=c"(c), "=d"(d) + :"a"(a), "c"(c) + ); + regs[0] = a; + regs[1] = b; + regs[2] = c; + regs[3] = d; +#endif +} +#endif /* LTC_S_X86_CPUID */ + static LTC_INLINE int s_pclmul_is_supported(void) { static int initialized = 0, is_supported = 0; if (initialized == 0) { - /* Test CPUID.1.0.ECX[1] - * EAX = 1, ECX = 0 */ -#if defined(_MSC_VER) - int cpuInfo[4]; - __cpuid(cpuInfo, 1); - is_supported = ((cpuInfo[2] >> 1) & 1); -#else - int a = 1 , b, c = 0, d; - - asm volatile ("cpuid" - :"=a"(a), "=b"(b), "=c"(c), "=d"(d) - :"a"(a), "c"(c) - ); - - is_supported = ((c >> 1) & 1); -#endif + int regs[4]; + s_x86_cpuid(regs, 1); + /* Test CPUID.1.0.ECX[1] (PCLMUL) and CPUID.1.0.ECX[9] (SSSE3) */ + is_supported = ((regs[2] >> 1) & 1) && ((regs[2] >> 9) & 1); initialized = 1; } @@ -116,10 +130,11 @@ static void s_gcm_gf_mult_pclmul(const unsigned char *a, const unsigned char *b, #if defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wbad-function-cast" -#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wcast-align" #pragma GCC diagnostic ignored "-Wmissing-braces" -#pragma GCC diagnostic ignored "-Wsign-compare" #pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wsign-compare" +#pragma GCC diagnostic ignored "-Wunused-parameter" #endif #include #if defined(__GNUC__) diff --git a/src/hashes/sha1_x86.c b/src/hashes/sha1_x86.c index 8f65665da..a42134352 100644 --- a/src/hashes/sha1_x86.c +++ b/src/hashes/sha1_x86.c @@ -8,7 +8,7 @@ */ -#ifdef LTC_SHA1_X86 +#if defined(LTC_SHA1) && defined(LTC_SHA1_X86) #if defined(__GNUC__) #pragma GCC diagnostic push diff --git a/src/hashes/sha2/sha224_desc.c b/src/hashes/sha2/sha224_desc.c index ccf4b9e89..4a6c9ba36 100644 --- a/src/hashes/sha2/sha224_desc.c +++ b/src/hashes/sha2/sha224_desc.c @@ -27,7 +27,7 @@ const struct ltc_hash_descriptor sha224_desc = NULL }; -#if defined LTC_SHA256_X86 +#if defined LTC_SHA224_X86 #if !defined (LTC_S_X86_CPUID) #define LTC_S_X86_CPUID diff --git a/src/hashes/sha2/sha224_x86.c b/src/hashes/sha2/sha224_x86.c index 8f9dd831b..f562b34a0 100644 --- a/src/hashes/sha2/sha224_x86.c +++ b/src/hashes/sha2/sha224_x86.c @@ -7,7 +7,7 @@ #include "tomcrypt_private.h" -#if defined(LTC_SHA224) && defined(LTC_SHA256) && defined(LTC_SHA224_X86) +#if defined(LTC_SHA224) && defined(LTC_SHA256) && defined(LTC_SHA224_X86) && defined(LTC_SHA256_X86) const struct ltc_hash_descriptor sha224_x86_desc = { @@ -66,7 +66,7 @@ int sha224_x86_done(hash_state * md, unsigned char *out) LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); - err = sha256_done(md, buf); + err = sha256_x86_done(md, buf); XMEMCPY(out, buf, 28); #ifdef LTC_CLEAN_STACK zeromem(buf, sizeof(buf)); diff --git a/src/hashes/sha2/sha256_desc.c b/src/hashes/sha2/sha256_desc.c index 7367ec20b..f144bfd17 100644 --- a/src/hashes/sha2/sha256_desc.c +++ b/src/hashes/sha2/sha256_desc.c @@ -2,27 +2,7 @@ /* SPDX-License-Identifier: Unlicense */ #include "tomcrypt_private.h" -#ifdef LTC_SHA256 - -const struct ltc_hash_descriptor sha256_desc = -{ - "sha256", - 0, - 32, - 64, - - /* OID */ - { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, - 9, - - &sha256_init, - &sha256_process, - &sha256_done, - &sha256_test, - NULL -}; - -#if defined LTC_SHA256_X86 +#if defined LTC_ARCH_X86 #if !defined (LTC_S_X86_CPUID) #define LTC_S_X86_CPUID @@ -70,7 +50,36 @@ static LTC_INLINE int s_sha256_x86_is_supported(void) } return is_supported; } -#endif /* LTC_SHA256_X86 */ +#endif /* LTC_ARCH_X86 */ + +int shani_is_supported(void) +{ +#ifdef LTC_ARCH_X86 + return s_sha256_x86_is_supported(); +#else + return 0; +#endif +} + +#ifdef LTC_SHA256 + +const struct ltc_hash_descriptor sha256_desc = +{ + "sha256", + 0, + 32, + 64, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, + 9, + + &sha256_init, + &sha256_process, + &sha256_done, + &sha256_test, + NULL +}; /** Initialize the hash state diff --git a/src/headers/tomcrypt_cfg.h b/src/headers/tomcrypt_cfg.h index 6f82aa9a3..f0f5051e2 100644 --- a/src/headers/tomcrypt_cfg.h +++ b/src/headers/tomcrypt_cfg.h @@ -243,14 +243,22 @@ typedef unsigned long ltc_mp_digit; #undef ENDIAN_32BITWORD #undef ENDIAN_64BITWORD #undef LTC_FAST - #define LTC_NO_AES_NI + #define LTC_NO_ACCEL #define LTC_NO_BSWAP #define LTC_NO_CLZL #define LTC_NO_CTZL #define LTC_NO_ROLC #define LTC_NO_ROTATE +#endif + +/* Just portable C implementations */ +#ifdef LTC_NO_ACCEL + #define LTC_NO_AES_NI #define LTC_NO_GCM_PCLMUL #define LTC_NO_GCM_PMULL + #define LTC_NO_SHA1_X86 + #define LTC_NO_SHA224_X86 + #define LTC_NO_SHA256_X86 #endif /* No LTC_FAST if: explicitly disabled OR non-gcc/non-clang compiler OR old gcc OR using -ansi -std=c99 */ @@ -307,10 +315,15 @@ typedef unsigned long ltc_mp_digit; #define LTC_HAVE_CTZL_BUILTIN #endif -#if (defined(__x86_64__) || defined(_M_X64)) +#if (defined(__x86_64__) || defined(__i386__) || defined(_M_X64) || defined(_M_IX86)) + #define LTC_ARCH_X86 #if !defined(LTC_NO_AES_NI) #define LTC_AES_NI #endif + #if !defined(LTC_NO_GCM_PCLMUL) + #define LTC_GCM_PCLMUL + #undef LTC_GCM_TABLES + #endif #if !defined(LTC_NO_SHA1_X86) #define LTC_SHA1_X86 #endif @@ -384,19 +397,6 @@ typedef unsigned long ltc_mp_digit; # define LTC_ATTRIBUTE(x) #endif -#if !defined(LTC_NO_GCM_PCLMUL) && (defined(__x86_64__) || defined(__i386__) || defined(_M_X64) || defined(_M_IX86)) -#define LTC_GCM_PCLMUL -#undef LTC_GCM_TABLES -#endif - -#if defined(__clang__) || defined(__GNUC__) -#define LTC_GCM_PCLMUL_TARGET __attribute__((target("pclmul,ssse3"))) -#define LTC_SHA_TARGET __attribute__((__target__("sse2,ssse3,sse4.1,sha"))) -#else -#define LTC_GCM_PCLMUL_TARGET -#define LTC_SHA_TARGET -#endif - #if !defined(LTC_NO_GCM_PMULL) && (defined(__aarch64__) || defined(_M_ARM64)) #define LTC_GCM_PMULL #undef LTC_GCM_TABLES diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index b370fedb0..0f07f2417 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -711,9 +711,9 @@ void rijndael_enc_done(symmetric_key *skey); int rijndael_enc_keysize(int *keysize); extern const struct ltc_cipher_descriptor rijndael_desc; extern const struct ltc_cipher_descriptor rijndael_enc_desc; +#endif int aesni_is_supported(void); -#endif #if defined(LTC_AES_NI) int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h index ed1440082..914d190aa 100644 --- a/src/headers/tomcrypt_custom.h +++ b/src/headers/tomcrypt_custom.h @@ -126,6 +126,7 @@ #define LTC_RIJNDAEL #define LTC_SHA256 #define LTC_YARROW + #define LTC_ECB_MODE #define LTC_CTR_MODE #define LTC_RNG_MAKE_PRNG diff --git a/src/headers/tomcrypt_hash.h b/src/headers/tomcrypt_hash.h index a6bd75028..c80ad9590 100644 --- a/src/headers/tomcrypt_hash.h +++ b/src/headers/tomcrypt_hash.h @@ -375,6 +375,8 @@ int sha512_224_test(void); extern const struct ltc_hash_descriptor sha512_224_desc; #endif /* LTC_SHA512_224 */ +int shani_is_supported(void); + #ifdef LTC_SHA256 int sha256_init(hash_state * md); int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen); diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index 5fee1a2ba..25876f970 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -404,7 +404,8 @@ typedef struct ltc_ecc_sig_opts { * This must be set in case one requires the recovery ID of a * signature operation. */ - int *recid; + unsigned char enable_recovery_id; + int recovery_id; /** The hash algorithm to use when creating a signature. * Setting this will enable RFC6979 compatible signature generation. diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h index 1658cca7a..39c56454d 100644 --- a/src/headers/tomcrypt_private.h +++ b/src/headers/tomcrypt_private.h @@ -182,6 +182,9 @@ int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) return CRYPT_OK; \ } + +#define LTC_SHA_TARGET LTC_ATTRIBUTE((__target__("sse2,ssse3,sse4.1,sha"))) + #ifdef LTC_SHA1 int sha1_test_desc(const struct ltc_hash_descriptor *desc, const char *name); #endif diff --git a/src/math/rand_prime.c b/src/math/rand_prime.c index 0cd6c0dce..6f13806ce 100644 --- a/src/math/rand_prime.c +++ b/src/math/rand_prime.c @@ -9,21 +9,19 @@ Generate a random prime, Tom St Denis */ -#define USE_BBS 1 - int rand_prime(void *N, long len, prng_state *prng, int wprng) { - int err, res, type; - unsigned char *buf; + int err, res; + unsigned char *buf, bbs; LTC_ARGCHK(N != NULL); - /* get type */ if (len < 0) { - type = USE_BBS; + /* Create BBS (Blum Blum Shub) style prime */ + bbs = 0x02; len = -len; } else { - type = 0; + bbs = 0x00; } /* allow sizes between 2 and 512 bytes for a prime size */ @@ -51,7 +49,7 @@ int rand_prime(void *N, long len, prng_state *prng, int wprng) /* munge bits */ buf[0] |= 0x80 | 0x40; - buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); + buf[len-1] |= 0x01 | bbs; /* load value */ if ((err = ltc_mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) { diff --git a/src/misc/crypt/crypt.c b/src/misc/crypt/crypt.c index ccef4a0c7..26fe4fbb3 100644 --- a/src/misc/crypt/crypt.c +++ b/src/misc/crypt/crypt.c @@ -13,9 +13,12 @@ const char *crypt_build_settings = "LibTomCrypt " SCRYPT " (www.libtom.net)\n" "LibTomCrypt is public domain software.\n" #if defined(INCLUDE_BUILD_DATE) - "Built on " __DATE__ " at " __TIME__ "\n" + "Built on " __DATE__ " at " __TIME__ "\n\n" #endif - "\n\nEndianness: " +#if defined(LTC_ARCH_X86) + "LTC_ARCH_X86\n" +#endif + "\nEndianness: " #if defined(ENDIAN_NEUTRAL) "neutral/" #endif @@ -502,13 +505,13 @@ const char *crypt_build_settings = #if defined(LTC_PEM_SSH) " OpenSSH-PEM " #endif -#if defined(LTC_SHA1_X86) +#if defined(LTC_SHA1) && defined(LTC_SHA1_X86) " SHA1-NI " #endif -#if defined(LTC_SHA224_X86) +#if defined(LTC_SHA224) && defined(LTC_SHA224_X86) " SHA224-NI " #endif -#if defined(LTC_SHA256_X86) +#if defined(LTC_SHA256) && defined(LTC_SHA256_X86) " SHA256-NI " #endif #if defined(LTC_DEVRANDOM) diff --git a/src/pk/ecc/ecc_recover_key.c b/src/pk/ecc/ecc_recover_key.c index ebd1a410d..7d1e01e4c 100644 --- a/src/pk/ecc/ecc_recover_key.c +++ b/src/pk/ecc/ecc_recover_key.c @@ -65,7 +65,7 @@ int ecc_recover_key(const unsigned char *sig, unsigned long siglen, err = CRYPT_MEM; goto error; } - recid = (opts->recid != NULL) ? *(opts->recid) : -1; + recid = (opts->enable_recovery_id) ? opts->recovery_id : -1; if (opts->type == LTC_ECCSIG_RFC7518) { /* RFC7518 format - raw (r,s) */ diff --git a/src/pk/ecc/ecc_sign_hash_eth27.c b/src/pk/ecc/ecc_sign_hash_eth27.c index 4944d4527..d340070d5 100644 --- a/src/pk/ecc/ecc_sign_hash_eth27.c +++ b/src/pk/ecc/ecc_sign_hash_eth27.c @@ -19,7 +19,7 @@ int ecc_sign_hash_eth27(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, ltc_ecc_sig_opts *opts, const ecc_key *key) { - int err, recid; + int err; void *r, *s; unsigned long i; @@ -37,9 +37,9 @@ int ecc_sign_hash_eth27(const unsigned char *in, unsigned long inlen, return CRYPT_BUFFER_OVERFLOW; } + opts->enable_recovery_id = 1; + if ((err = ltc_mp_init_multi(&r, &s, LTC_NULL)) != CRYPT_OK) return err; - if (opts->recid == NULL) - opts->recid = &recid; if ((err = ecc_sign_hash_internal(in, inlen, r, s, opts, key)) != CRYPT_OK) goto error; zeromem(out, 65); @@ -48,12 +48,10 @@ int ecc_sign_hash_eth27(const unsigned char *in, unsigned long inlen, if ((err = ltc_mp_to_unsigned_bin(r, out + 32 - i)) != CRYPT_OK) goto error; i = ltc_mp_unsigned_bin_size(s); if ((err = ltc_mp_to_unsigned_bin(s, out + 64 - i)) != CRYPT_OK) goto error; - out[64] = (unsigned char)(*(opts->recid) + 27); /* Recovery ID is 27/28 for Ethereum */ + out[64] = (unsigned char)(opts->recovery_id + 27); /* Recovery ID is 27/28 for Ethereum */ err = CRYPT_OK; error: - if (opts->recid == &recid) - opts->recid = NULL; ltc_mp_deinit_multi(r, s, LTC_NULL); return err; } diff --git a/src/pk/ecc/ecc_sign_hash_internal.c b/src/pk/ecc/ecc_sign_hash_internal.c index 9e2db46bc..670fbe66f 100644 --- a/src/pk/ecc/ecc_sign_hash_internal.c +++ b/src/pk/ecc/ecc_sign_hash_internal.c @@ -67,7 +67,7 @@ int ecc_sign_hash_internal(const unsigned char *in, unsigned long inlen, /* find r = x1 mod n */ if ((err = ltc_mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; } - if (opts->recid) { + if (opts->enable_recovery_id) { /* find recovery ID (if needed) */ v = 0; if (ltc_mp_copy(pubkey.pubkey.x, s) != CRYPT_OK) { goto error; } @@ -102,7 +102,7 @@ int ecc_sign_hash_internal(const unsigned char *in, unsigned long inlen, goto errnokey; } - if (opts->recid) *opts->recid = v; + if (opts->enable_recovery_id) opts->recovery_id = v; goto errnokey; error: diff --git a/tests/cipher_hash_test.c b/tests/cipher_hash_test.c index 92e082307..699b7d365 100644 --- a/tests/cipher_hash_test.c +++ b/tests/cipher_hash_test.c @@ -56,6 +56,27 @@ int cipher_hash_test(void) DOX(hash_descriptor[x].test(), hash_descriptor[x].name); } + /* explicit SHA-NI + portable implementations tests */ + if (shani_is_supported()) { +#if defined(LTC_SHA256) && defined(LTC_SHA256_X86) + DO(sha256_x86_test()); +#endif +#if defined(LTC_SHA224) && defined(LTC_SHA224_X86) + DO(sha224_x86_test()); +#endif +#if defined(LTC_SHA1) && defined(LTC_SHA1_X86) + DO(sha1_x86_test()); +#endif + } +#if defined(LTC_SHA256) + DO(sha256_c_test()); +#endif +#if defined(LTC_SHA224) + DO(sha224_c_test()); +#endif +#if defined(LTC_SHA1) + DO(sha1_c_test()); +#endif #ifdef LTC_SHA3 /* SHAKE128 + SHAKE256 tests are a bit special */ DOX(sha3_shake_test(), "sha3_shake"); diff --git a/tests/ecc_test.c b/tests/ecc_test.c index f2c5ee1bf..90293ed35 100644 --- a/tests/ecc_test.c +++ b/tests/ecc_test.c @@ -643,21 +643,21 @@ static int s_ecc_new_api(void) #ifdef LTC_ECC_SHAMIR if (strcmp(ltc_mp.name, "TomsFastMath") != 0) { /* XXX-FIXME: TFM does not support sqrtmod_prime */ - int found = 0, recid; + int found = 0; ecc_key reckey; /* test recovery */ - sig_opts.recid = &recid; + sig_opts.enable_recovery_id = 1; len = sizeof(buf); DO(ecc_sign_hash_v2(data16, privkey.dp.size, buf, &len, &sig_opts, &privkey)); DO(ecc_set_curve(dp, &reckey)); for (k = 0; k < 2*(1+privkey.dp.cofactor); k++) { - recid = k; + sig_opts.recovery_id = k; stat = ecc_recover_key(buf, len, data16, privkey.dp.size, &sig_opts, &reckey); if (stat != CRYPT_OK) continue; /* last two will almost always fail, only possible if x<(prime mod order) */ stat = ecc_key_cmp(PK_PUBLIC, &pubkey, &reckey); if (stat == CRYPT_OK) found++; } - sig_opts.recid = NULL; + sig_opts.enable_recovery_id = 0; if (found != 1) return CRYPT_FAIL_TESTVECTOR; /* unique match */ ecc_free(&reckey); } @@ -995,7 +995,7 @@ static int s_ecc_rfc6979(void) } }, { - NULL + 0 } }; @@ -1971,7 +1971,7 @@ static int s_ecc_test_ethereum(void) static int s_ecc_test_recovery(void) { - int i, recid, stat; + int i, stat; const ltc_ecc_curve* dp; ecc_key key, privkey, pubkey, reckey; unsigned char buf[1000]; @@ -1998,7 +1998,7 @@ static int s_ecc_test_recovery(void) ltc_ecc_sig_opts sig_opts = { .prng = &yarrow_prng, .wprng = find_prng ("yarrow"), - .recid = &recid + .enable_recovery_id = 1, }; /* XXX-FIXME: TFM does not support sqrtmod_prime */ @@ -2011,14 +2011,14 @@ static int s_ecc_test_recovery(void) DO(ecc_set_key(eth_pubkey, sizeof(eth_pubkey), PK_PUBLIC, &pubkey)); DO(ecc_set_curve(dp, &reckey)); - recid = 0; + sig_opts.recovery_id = 0; sig_opts.type = LTC_ECCSIG_RFC7518; DO(ecc_recover_key(eth_sig, sizeof(eth_sig)-1, eth_hash, sizeof(eth_hash), &sig_opts, &reckey)); DO(ecc_key_cmp(PK_PUBLIC, &pubkey, &reckey)); ecc_free(&reckey); DO(ecc_set_curve(dp, &reckey)); - recid = -1; + sig_opts.recovery_id = -1; sig_opts.type = LTC_ECCSIG_ETH27; DO(ecc_recover_key(eth_sig, sizeof(eth_sig), eth_hash, sizeof(eth_hash), &sig_opts, &reckey)); DO(ecc_key_cmp(PK_PUBLIC, &pubkey, &reckey)); @@ -2055,7 +2055,7 @@ static int s_ecc_test_recovery(void) /* test signature */ len = sizeof(buf); - recid = 0; + sig_opts.recovery_id = 0; DO(ecc_sign_hash_v2(data16, 16, buf, &len, &sig_opts, &privkey)); /* test verification */ @@ -2098,5 +2098,9 @@ int ecc_test(void) #endif return CRYPT_OK; } - +#else +int ecc_test(void) +{ + return CRYPT_NOP; +} #endif diff --git a/tests/file_test.c b/tests/file_test.c index c410d8963..294e95500 100644 --- a/tests/file_test.c +++ b/tests/file_test.c @@ -28,6 +28,10 @@ int file_test(void) isha256 = find_hash("sha256"); iaes = find_cipher("aes"); + /* Suppress warnings when building with -DLTC_MINIMAL */ + LTC_UNUSED_PARAM(iaes); + LTC_UNUSED_PARAM(key); + len = sizeof(buf); if ((in = fopen(fname, "rb")) == NULL) return CRYPT_FILE_NOTFOUND; err = hash_filehandle(isha256, in, buf, &len); diff --git a/tests/multi_test.c b/tests/multi_test.c index e02940554..94236c1b1 100644 --- a/tests/multi_test.c +++ b/tests/multi_test.c @@ -9,10 +9,16 @@ int multi_test(void) unsigned char buf[2][MAXBLOCKSIZE]; unsigned long len, len2; + /* Suppress warnings when building with -DLTC_MINIMAL */ + LTC_UNUSED_PARAM(key); + LTC_UNUSED_PARAM(buf); + LTC_UNUSED_PARAM(len); + LTC_UNUSED_PARAM(len2); /* register algos */ register_hash(&sha256_desc); register_cipher(&aes_desc); +#ifdef LTC_HASH_HELPERS /* HASH testing */ len = sizeof(buf[0]); #if defined(ENDIAN_32BITWORD) || defined(_WIN32) || defined(ENDIAN_64BITWORD_ILP32) @@ -43,6 +49,7 @@ int multi_test(void) printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return CRYPT_FAIL_TESTVECTOR; } +#endif #ifdef LTC_HMAC len = sizeof(buf[0]); diff --git a/tests/test.c b/tests/test.c index 8eb7d7d0b..f2f5ed0c5 100644 --- a/tests/test.c +++ b/tests/test.c @@ -344,6 +344,9 @@ int main(int argc, char **argv) printf("LTC_VERSION = %s\n%s\n\n", GIT_VERSION, crypt_build_settings); + printf("AES-NI CPU support = %d\n", aesni_is_supported()); + printf("SHA-NI CPU support = %d\n\n", shani_is_supported()); + #ifdef USE_LTM mpi_provider = "ltm"; #elif defined(USE_TFM)