diff --git a/demos/latex-tables.c b/demos/latex-tables.c index becd94208..776b028df 100644 --- a/demos/latex-tables.c +++ b/demos/latex-tables.c @@ -69,37 +69,10 @@ static const char *s_map_mode(enum cipher_mode mode) exit(1); } - -static void LTC_NORETURN die(int status) -{ - FILE* o = status == EXIT_SUCCESS ? stdout : stderr; - fprintf(o, - "Usage: latex-tables [<-h>]\n\n" - "Generate LaTeX tables from some library internal data.\n\n" - "\t-h\tThe help you're looking at.\n" - ); - exit(status); -} - -static int s_to_lower(const char *in, char *out, unsigned long *outlen) -{ - unsigned long n; - for (n = 0; n < *outlen && in[n]; ++n) { - out[n] = tolower(in[n]); - } - if (n == *outlen) - return CRYPT_BUFFER_OVERFLOW; - out[n] = '\0'; - *outlen = n; - return CRYPT_OK; -} - -int main(int argc, char **argv) +static int print_pem_ciphers(void) { unsigned long n; - if (argc > 1 && strstr(argv[1], "-h")) - die(0); - printf("PEM ciphers:\n\n"); + printf("\nPEM ciphers:\n\n"); for (n = 0; n < pem_dek_infos_num; ++n) { char nbuf[32] = {0}; size_t nlen = strlen(pem_dek_infos[n].name); @@ -110,7 +83,12 @@ int main(int argc, char **argv) pem_dek_infos[n].keylen * 8, s_map_mode(pem_dek_infos[n].mode)); } + return 0; +} +static int print_ssh_ciphers(void) +{ + unsigned long n; printf("\nSSH ciphers:\n\n"); for (n = 0; n < ssh_ciphers_num; ++n) { char nbuf[32] = {0}; @@ -119,10 +97,28 @@ int main(int argc, char **argv) nbuf[nlen] = '}'; printf("\\hline \\texttt{%-30s & %-16s & %-24ld & %-6s \\\\\n", nbuf, s_map_cipher(ssh_ciphers[n].algo), - ssh_ciphers[n].keylen * 8, + ssh_ciphers[n].keylen * 8, s_map_mode(ssh_ciphers[n].mode)); } + return 0; +} + +static int s_to_lower(const char *in, char *out, unsigned long *outlen) +{ + unsigned long n; + for (n = 0; n < *outlen && in[n]; ++n) { + out[n] = tolower(in[n]); + } + if (n == *outlen) + return CRYPT_BUFFER_OVERFLOW; + out[n] = '\0'; + *outlen = n; + return CRYPT_OK; +} +static int print_ecc_curves(void) +{ + unsigned long n; printf("\nECC curves:\n\n"); for (n = 0; ltc_ecc_curves[n].OID != NULL; ++n) { const char * const *names; @@ -166,6 +162,174 @@ int main(int argc, char **argv) lower[lowerl + 2] = '\0'; printf("\\hline \\texttt%-17s & %-36s & %-21s \\\\\n", lower, buf, ltc_ecc_curves[n].OID); } + return 0; +} + +static int s_to_upper(const char *in, char *out, unsigned long *outlen) +{ + unsigned long n; + for (n = 0; n < *outlen && in[n]; ++n) { + out[n] = toupper(in[n]); + } + if (n == *outlen) + return CRYPT_BUFFER_OVERFLOW; + out[n] = '\0'; + *outlen = n; + return CRYPT_OK; +} + +static int s_to_desc(const char *in, char *out, unsigned long outlen, int has_desc) +{ + unsigned long n, m; + if (outlen < 6) goto err_exit; + XMEMCPY(out, "\\code{", 6); + m = 6; + for (n = 0; m < outlen - 1 && in[n]; ++n, ++m) { + if (in[n] == '-' || in[n] == '_') { + out[m++] = '\\'; + out[m] = '_'; + } else + out[m] = tolower(in[n]); + } + if (outlen <= m) goto err_exit; + if (!has_desc) { + XMEMCPY(&out[m], "\\_desc", 6); + m += 6; + } + out[m++] = '}'; + out[m] = '\0'; + return CRYPT_OK; +err_exit: + fprintf(stderr, "Error: Can't print descriptor %s\n", in); + exit(1); +} + +struct desc { + void *orig; + char desc[64]; +}; + +static int hash_sorter(const void *a, const void *b) +{ + const struct ltc_hash_descriptor *A, *B; + A = ((const struct desc*)a)->orig; + B = ((const struct desc*)b)->orig; + if (A->hashsize < B->hashsize) return 1; + if (A->hashsize > B->hashsize) return -1; + if (A->ID < B->ID) return -1; + if (A->ID > B->ID) return 1; + return 0; +} + +static void print_hash_line(const char *name, const struct ltc_hash_descriptor *p) +{ + char nbuf[32]; + unsigned long nlen = sizeof(nbuf); + s_to_upper(p->name, nbuf, &nlen); + printf("\\hline %-17s & %-32s & %lu & %2d \\\\\n", nbuf, name, p->hashsize, p->ID); +} + +static int print_hash_descriptors(void) +{ + const struct { + const char *name; + const struct ltc_hash_descriptor * desc; + } special_hash_descriptors[] = { +#define HASH_DESC(name) { #name, &name } + HASH_DESC(sha256_portable_desc), +#ifdef LTC_SHA256_X86 + HASH_DESC(sha256_x86_desc), +#endif + HASH_DESC(sha224_portable_desc), +#ifdef LTC_SHA224_X86 + HASH_DESC(sha224_x86_desc), +#endif + HASH_DESC(sha1_portable_desc), +#ifdef LTC_SHA1_X86 + HASH_DESC(sha1_x86_desc), +#endif + }; + struct desc descs[TAB_SIZE + 1] = {0}; + int ids[TAB_SIZE + 1] = {0}; + unsigned long n; + + printf("\nhash descriptors:\n\n"); + register_all_hashes(); + + for (n = 0; hash_descriptor[n].name != NULL && n < TAB_SIZE; ++n) { + if (hash_descriptor[n].ID > TAB_SIZE) { + printf("Hash descriptor '%s' has invalid ID %d\n", hash_descriptor[n].name, hash_descriptor[n].ID); + return EXIT_FAILURE; + } + if (ids[hash_descriptor[n].ID] != 0) { + printf("Hash descriptor '%s' has duplicate ID %d\n", hash_descriptor[n].name, hash_descriptor[n].ID); + return EXIT_FAILURE; + } + ids[hash_descriptor[n].ID] = 1; + descs[n].orig = &hash_descriptor[n]; + s_to_desc(hash_descriptor[n].name, descs[n].desc, sizeof(descs[n].desc), 0); + } + qsort(descs, n, sizeof(struct desc), &hash_sorter); + for (n = 0; hash_descriptor[n].name != NULL && n < TAB_SIZE; ++n) { + print_hash_line(descs[n].desc, descs[n].orig); + } + + printf("\nspecial hash descriptors:\n\n"); + for (n = 0; n < LTC_ARRAY_SIZE(special_hash_descriptors); ++n) { + char nbuf[64]; + unsigned long nlen = sizeof(nbuf); + s_to_desc(special_hash_descriptors[n].name, nbuf, nlen, 1); + print_hash_line(nbuf, special_hash_descriptors[n].desc); + } + return 0; +} + +static void LTC_NORETURN die(int status) +{ + FILE* o = status == EXIT_SUCCESS ? stdout : stderr; + fprintf(o, + "Usage: latex-tables [<-h|-l|type>]\n\n" + "Generate LaTeX tables from some library internal data.\n\n" + "\ttype\tThe type of table to print.\n" + "\t-l\tList all built-in types that can be printed.\n" + "\t-h\tThe help you're looking at.\n" + ); + exit(status); +} + +int main(int argc, char **argv) +{ + const struct { + const char *name; + int (*printer)(void); + } printers[] = { + #define PRINTER(name) { #name, print_ ## name } + PRINTER(hash_descriptors), + PRINTER(pem_ciphers), + PRINTER(ssh_ciphers), + PRINTER(ecc_curves), + #undef PRINTER + }; + int err; + unsigned long n; + if (argc > 1) { + if (strstr(argv[1], "-h")) + die(0); + if (strstr(argv[1], "-l")) { + for (n = 0; n < LTC_ARRAY_SIZE(printers); ++n) { + printf("%s\n", printers[n].name); + } + return 0; + } + } + printf("libtomcrypt latex tables\n"); + + for (n = 0; n < LTC_ARRAY_SIZE(printers); ++n) { + if (argc > 1 && strstr(printers[n].name, argv[1]) == NULL) + continue; + if ((err = printers[n].printer()) != 0) + return err; + } return 0; } diff --git a/doc/crypt.tex b/doc/crypt.tex index 22e1337fe..8b850823c 100644 --- a/doc/crypt.tex +++ b/doc/crypt.tex @@ -3034,52 +3034,75 @@ \subsection{Hash Registration} \end{verbatim} The following hashes are provided as of this release within the LibTomCrypt library: -\index{Hash descriptor table} +\index{Hash descriptor tables} \begin{figure}[H] \begin{center} \begin{tabular}{|c|c|c|c|} - \hline \textbf{Name} & \textbf{Descriptor Name} & \textbf{Size of Message Digest (bytes)} & \textbf{Id} \\ - \hline WHIRLPOOL & whirlpool\_desc & 64 & 11 \\ - \hline Keccak512 & keccak\_512\_desc & 64 & 32 \\ - \hline SHA3-512 & sha3\_512\_desc & 64 & 20 \\ - \hline SHA-512 & sha512\_desc & 64 & 5 \\ - \hline BLAKE2B-512 & blake2b\_512\_desc & 64 & 28 \\ - \hline Keccak384 & keccak\_384\_desc & 48 & 31 \\ - \hline SHA3-384 & sha3\_384\_desc & 48 & 19 \\ - \hline SHA-384 & sha384\_desc & 48 & 4 \\ - \hline BLAKE2B-384 & blake2b\_384\_desc & 48 & 27 \\ - \hline RIPEMD-320 & rmd160\_desc & 40 & 14 \\ - \hline SHA-512/256 & sha512\_256\_desc & 32 & 16 \\ - \hline Keccak256 & keccak\_256\_desc & 32 & 30 \\ - \hline SHA3-256 & sha3\_256\_desc & 32 & 18 \\ - \hline SHA-256 & sha256\_desc & 32 & 0 \\ - \hline RIPEMD-256 & rmd160\_desc & 32 & 13 \\ - \hline BLAKE2S-256 & blake2s\_256\_desc & 32 & 24 \\ - \hline BLAKE2B-256 & blake2b\_256\_desc & 32 & 26 \\ - \hline SM3 & sm3\_desc & 32 & 34 \\ - \hline SHA-512/224 & sha512\_224\_desc & 28 & 15 \\ - \hline Keccak224 & keccak\_224\_desc & 28 & 29 \\ - \hline SHA3-224 & sha3\_224\_desc & 28 & 17 \\ - \hline SHA-224 & sha224\_desc & 28 & 10 \\ - \hline BLAKE2S-224 & blake2s\_224\_desc & 28 & 23 \\ - \hline TIGER-192 & tiger\_desc & 24 & 1 \\ - \hline TIGER2-192 & tiger2\_desc & 24 & 33 \\ - \hline SHA-1 & sha1\_desc & 20 & 2 \\ - \hline RIPEMD-160 & rmd160\_desc & 20 & 9 \\ - \hline BLAKE2S-160 & blake2s\_160\_desc & 20 & 22 \\ - \hline BLAKE2B-160 & blake2b\_160\_desc & 20 & 25 \\ - \hline RIPEMD-128 & rmd128\_desc & 16 & 8 \\ - \hline MD5 & md5\_desc & 16 & 3 \\ - \hline MD4 & md4\_desc & 16 & 6 \\ - \hline MD2 & md2\_desc & 16 & 7 \\ - \hline BLAKE2S-128 & blake2s\_128\_desc & 16 & 21 \\ - \hline +\hline \textbf{Name} & \textbf{Descriptor Name} & \textbf{Size of Message Digest (bytes)} & \textbf{Id} \\ + +\hline SHA512 & \code{sha512\_desc} & 64 & 5 \\ +\hline WHIRLPOOL & \code{whirlpool\_desc} & 64 & 11 \\ +\hline SHA3-512 & \code{sha3\_512\_desc} & 64 & 20 \\ +\hline BLAKE2B-512 & \code{blake2b\_512\_desc} & 64 & 28 \\ +\hline KECCAK512 & \code{keccak512\_desc} & 64 & 32 \\ +\hline SHAKE256 & \code{shake256\_desc} & 64 & 35 \\ +\hline SHA384 & \code{sha384\_desc} & 48 & 4 \\ +\hline SHA3-384 & \code{sha3\_384\_desc} & 48 & 19 \\ +\hline BLAKE2B-384 & \code{blake2b\_384\_desc} & 48 & 27 \\ +\hline KECCAK384 & \code{keccak384\_desc} & 48 & 31 \\ +\hline RMD320 & \code{rmd320\_desc} & 40 & 14 \\ +\hline SHA256 & \code{sha256\_desc} & 32 & 0 \\ +\hline RMD256 & \code{rmd256\_desc} & 32 & 13 \\ +\hline SHA512-256 & \code{sha512\_256\_desc} & 32 & 16 \\ +\hline SHA3-256 & \code{sha3\_256\_desc} & 32 & 18 \\ +\hline BLAKE2S-256 & \code{blake2s\_256\_desc} & 32 & 24 \\ +\hline BLAKE2B-256 & \code{blake2b\_256\_desc} & 32 & 26 \\ +\hline KECCAK256 & \code{keccak256\_desc} & 32 & 30 \\ +\hline SHAKE128 & \code{shake128\_desc} & 32 & 34 \\ +\hline SM3 & \code{sm3\_desc} & 32 & 36 \\ +\hline SHA224 & \code{sha224\_desc} & 28 & 10 \\ +\hline SHA512-224 & \code{sha512\_224\_desc} & 28 & 15 \\ +\hline SHA3-224 & \code{sha3\_224\_desc} & 28 & 17 \\ +\hline BLAKE2S-224 & \code{blake2s\_224\_desc} & 28 & 23 \\ +\hline KECCAK224 & \code{keccak224\_desc} & 28 & 29 \\ +\hline TIGER & \code{tiger\_desc} & 24 & 1 \\ +\hline TIGER2 & \code{tiger2\_desc} & 24 & 33 \\ +\hline SHA1 & \code{sha1\_desc} & 20 & 2 \\ +\hline RMD160 & \code{rmd160\_desc} & 20 & 9 \\ +\hline BLAKE2S-160 & \code{blake2s\_160\_desc} & 20 & 22 \\ +\hline BLAKE2B-160 & \code{blake2b\_160\_desc} & 20 & 25 \\ +\hline MD5 & \code{md5\_desc} & 16 & 3 \\ +\hline MD4 & \code{md4\_desc} & 16 & 6 \\ +\hline MD2 & \code{md2\_desc} & 16 & 7 \\ +\hline RMD128 & \code{rmd128\_desc} & 16 & 8 \\ +\hline BLAKE2S-128 & \code{blake2s\_128\_desc} & 16 & 21 \\ + +\hline \end{tabular} \end{center} -\caption{Built--In Software Hashes} +\caption{Built--In Hashes} \end{figure} -\vfil + +Additional to those standard descriptors, there exist the following target-specific hash descriptors: + +\begin{figure}[H] +\begin{center} +\begin{tabular}{|c|c|c|c|} +\hline \textbf{Name} & \textbf{Descriptor Name} & \textbf{Size of Message Digest (bytes)} & \textbf{Id} \\ +\hline SHA256 & \code{sha256\_portable\_desc} & 32 & 0 \\ +\hline SHA256 & \code{sha256\_x86\_desc} & 32 & 0 \\ +\hline SHA224 & \code{sha224\_portable\_desc} & 28 & 10 \\ +\hline SHA224 & \code{sha224\_x86\_desc} & 28 & 10 \\ +\hline SHA1 & \code{sha1\_portable\_desc} & 20 & 2 \\ +\hline SHA1 & \code{sha1\_x86\_desc} & 20 & 2 \\ +\hline +\end{tabular} +\end{center} +\caption{Target--specific hash descriptors} +\end{figure} + +Those descriptors don't necessarily exist in all builds and their usage may only make sense in some setups. \mysection{Cipher Hash Construction} \index{Cipher Hash Construction} diff --git a/src/hashes/sha1.c b/src/hashes/sha1.c index 72ef692d1..b24683941 100644 --- a/src/hashes/sha1.c +++ b/src/hashes/sha1.c @@ -179,27 +179,6 @@ static int s_sha1_c_compress(hash_state *md, const unsigned char *buf) } #endif -/** - Initialize the hash state - @param md The hash state you wish to initialize - @return CRYPT_OK if successful -*/ -int sha1_c_init(hash_state * md) -{ - LTC_ARGCHK(md != NULL); - - md->sha1.state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); - - md->sha1.state[0] = 0x67452301UL; - md->sha1.state[1] = 0xefcdab89UL; - md->sha1.state[2] = 0x98badcfeUL; - md->sha1.state[3] = 0x10325476UL; - md->sha1.state[4] = 0xc3d2e1f0UL; - md->sha1.curlen = 0; - md->sha1.length = 0; - return CRYPT_OK; -} - /** Process a block of memory though the hash @param md The hash state @@ -207,7 +186,23 @@ int sha1_c_init(hash_state * md) @param inlen The length of the data (octets) @return CRYPT_OK if successful */ -HASH_PROCESS(sha1_c_process, s_sha1_c_compress, sha1, 64) +static HASH_PROCESS(s_sha1_c_process, s_sha1_c_compress, sha1, 64) + +static LTC_INLINE void s_sha1_c_fixup_state(hash_state * md) +{ + ulong32 *state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); + if (state != md->sha1.state) { + XMEMMOVE(state, md->sha1.state_buf + md->sha1.align, 5 * sizeof(ulong32)); + md->sha1.state = state; + md->sha1.align = (unsigned char*)state - md->sha1.state_buf; + } +} + +int sha1_c_process (hash_state * md, const unsigned char *in, unsigned long inlen) +{ + s_sha1_c_fixup_state(md); + return s_sha1_c_process(md, in, inlen); +} /** Terminate the hash to get the digest @@ -226,6 +221,8 @@ int sha1_c_done(hash_state * md, unsigned char *out) return CRYPT_INVALID_ARG; } + s_sha1_c_fixup_state(md); + /* increase the length of the message */ md->sha1.length += md->sha1.curlen * 8; diff --git a/src/hashes/sha1_desc.c b/src/hashes/sha1_desc.c index 8b83687ea..bf2102604 100644 --- a/src/hashes/sha1_desc.c +++ b/src/hashes/sha1_desc.c @@ -79,12 +79,19 @@ static LTC_INLINE int s_sha1_x86_is_supported(void) */ int sha1_init(hash_state * md) { -#if defined LTC_SHA1_X86 - if(s_sha1_x86_is_supported()) { - return sha1_x86_init(md); - } -#endif - return sha1_c_init(md); + LTC_ARGCHK(md != NULL); + + md->sha1.state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); + md->sha1.align = (unsigned char*)md->sha1.state - md->sha1.state_buf; + + md->sha1.state[0] = 0x67452301UL; + md->sha1.state[1] = 0xefcdab89UL; + md->sha1.state[2] = 0x98badcfeUL; + md->sha1.state[3] = 0x10325476UL; + md->sha1.state[4] = 0xc3d2e1f0UL; + md->sha1.curlen = 0; + md->sha1.length = 0; + return CRYPT_OK; } /** diff --git a/src/hashes/sha1_x86.c b/src/hashes/sha1_x86.c index c1c5408be..740f52fd0 100644 --- a/src/hashes/sha1_x86.c +++ b/src/hashes/sha1_x86.c @@ -191,27 +191,6 @@ static int s_sha1_x86_compress(hash_state *md, const unsigned char *buf) } #endif -/** - Initialize the hash state - @param md The hash state you wish to initialize - @return CRYPT_OK if successful -*/ -int sha1_x86_init(hash_state * md) -{ - LTC_ARGCHK(md != NULL); - - md->sha1.state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); - - md->sha1.state[0] = 0x67452301UL; - md->sha1.state[1] = 0xefcdab89UL; - md->sha1.state[2] = 0x98badcfeUL; - md->sha1.state[3] = 0x10325476UL; - md->sha1.state[4] = 0xc3d2e1f0UL; - md->sha1.curlen = 0; - md->sha1.length = 0; - return CRYPT_OK; -} - /** Process a block of memory though the hash @param md The hash state @@ -219,7 +198,23 @@ int sha1_x86_init(hash_state * md) @param inlen The length of the data (octets) @return CRYPT_OK if successful */ -HASH_PROCESS(sha1_x86_process, s_sha1_x86_compress, sha1, 64) +static HASH_PROCESS(s_sha1_x86_process, s_sha1_x86_compress, sha1, 64) + +static LTC_INLINE void s_sha1_x86_fixup_state(hash_state * md) +{ + ulong32 *state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); + if (state != md->sha1.state) { + XMEMMOVE(state, md->sha1.state_buf + md->sha1.align, 5 * sizeof(ulong32)); + md->sha1.state = state; + md->sha1.align = (unsigned char*)state - md->sha1.state_buf; + } +} + +int sha1_x86_process (hash_state * md, const unsigned char *in, unsigned long inlen) +{ + s_sha1_x86_fixup_state(md); + return s_sha1_x86_process(md, in, inlen); +} /** Terminate the hash to get the digest @@ -238,6 +233,8 @@ int sha1_x86_done(hash_state * md, unsigned char *out) return CRYPT_INVALID_ARG; } + s_sha1_x86_fixup_state(md); + /* increase the length of the message */ md->sha1.length += md->sha1.curlen * 8; diff --git a/src/hashes/sha2/sha224.c b/src/hashes/sha2/sha224.c index 15fc36767..69ccf90bf 100644 --- a/src/hashes/sha2/sha224.c +++ b/src/hashes/sha2/sha224.c @@ -20,38 +20,13 @@ const struct ltc_hash_descriptor sha224_portable_desc = { 2, 16, 840, 1, 101, 3, 4, 2, 4, }, 9, - &sha224_c_init, - &sha256_c_process, + &sha224_init, + &sha224_c_process, &sha224_c_done, - &sha224_test, + &sha224_c_test, NULL }; -/* init the sha256 er... sha224 state ;-) */ -/** - Initialize the hash state - @param md The hash state you wish to initialize - @return CRYPT_OK if successful -*/ -int sha224_c_init(hash_state * md) -{ - LTC_ARGCHK(md != NULL); - - md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); - - md->sha256.curlen = 0; - md->sha256.length = 0; - md->sha256.state[0] = 0xc1059ed8UL; - md->sha256.state[1] = 0x367cd507UL; - md->sha256.state[2] = 0x3070dd17UL; - md->sha256.state[3] = 0xf70e5939UL; - md->sha256.state[4] = 0xffc00b31UL; - md->sha256.state[5] = 0x68581511UL; - md->sha256.state[6] = 0x64f98fa7UL; - md->sha256.state[7] = 0xbefa4fa4UL; - return CRYPT_OK; -} - /** Terminate the hash to get the digest @param md The hash state @@ -66,7 +41,7 @@ int sha224_c_done(hash_state * md, unsigned char *out) LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); - err = sha256_done(md, buf); + err = sha256_c_done(md, buf); XMEMCPY(out, buf, 28); #ifdef LTC_CLEAN_STACK zeromem(buf, sizeof(buf)); diff --git a/src/hashes/sha2/sha224_desc.c b/src/hashes/sha2/sha224_desc.c index 6aa9dfd20..9c2ea4b2e 100644 --- a/src/hashes/sha2/sha224_desc.c +++ b/src/hashes/sha2/sha224_desc.c @@ -85,12 +85,22 @@ static LTC_INLINE int s_sha224_x86_is_supported(void) */ int sha224_init(hash_state * md) { -#if defined LTC_SHA224_X86 - if(s_sha224_x86_is_supported()) { - return sha224_x86_init(md); - } -#endif - return sha224_c_init(md); + LTC_ARGCHK(md != NULL); + + md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + md->sha256.align = (unsigned char*)md->sha256.state - md->sha256.state_buf; + + md->sha256.curlen = 0; + md->sha256.length = 0; + md->sha256.state[0] = 0xc1059ed8UL; + md->sha256.state[1] = 0x367cd507UL; + md->sha256.state[2] = 0x3070dd17UL; + md->sha256.state[3] = 0xf70e5939UL; + md->sha256.state[4] = 0xffc00b31UL; + md->sha256.state[5] = 0x68581511UL; + md->sha256.state[6] = 0x64f98fa7UL; + md->sha256.state[7] = 0xbefa4fa4UL; + return CRYPT_OK; } /** diff --git a/src/hashes/sha2/sha224_x86.c b/src/hashes/sha2/sha224_x86.c index f562b34a0..980ae80d4 100644 --- a/src/hashes/sha2/sha224_x86.c +++ b/src/hashes/sha2/sha224_x86.c @@ -20,38 +20,13 @@ const struct ltc_hash_descriptor sha224_x86_desc = { 2, 16, 840, 1, 101, 3, 4, 2, 4, }, 9, - &sha224_x86_init, - &sha256_x86_process, + &sha224_init, + &sha224_x86_process, &sha224_x86_done, &sha224_x86_test, NULL }; -/* init the sha256 er... sha224 state ;-) */ -/** - Initialize the hash state - @param md The hash state you wish to initialize - @return CRYPT_OK if successful -*/ -int sha224_x86_init(hash_state * md) -{ - LTC_ARGCHK(md != NULL); - - md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); - - md->sha256.curlen = 0; - md->sha256.length = 0; - md->sha256.state[0] = 0xc1059ed8UL; - md->sha256.state[1] = 0x367cd507UL; - md->sha256.state[2] = 0x3070dd17UL; - md->sha256.state[3] = 0xf70e5939UL; - md->sha256.state[4] = 0xffc00b31UL; - md->sha256.state[5] = 0x68581511UL; - md->sha256.state[6] = 0x64f98fa7UL; - md->sha256.state[7] = 0xbefa4fa4UL; - return CRYPT_OK; -} - /** Terminate the hash to get the digest @param md The hash state diff --git a/src/hashes/sha2/sha256.c b/src/hashes/sha2/sha256.c index a37028d64..a69650e17 100644 --- a/src/hashes/sha2/sha256.c +++ b/src/hashes/sha2/sha256.c @@ -20,7 +20,7 @@ const struct ltc_hash_descriptor sha256_portable_desc = { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, 9, - &sha256_c_init, + &sha256_init, &sha256_c_process, &sha256_c_done, &sha256_c_test, @@ -226,30 +226,6 @@ static int s_sha256_compress(hash_state * md, const unsigned char *buf) } #endif -/** - Initialize the hash state - @param md The hash state you wish to initialize - @return CRYPT_OK if successful -*/ -int sha256_c_init(hash_state * md) -{ - LTC_ARGCHK(md != NULL); - - md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); - - md->sha256.curlen = 0; - md->sha256.length = 0; - md->sha256.state[0] = 0x6A09E667UL; - md->sha256.state[1] = 0xBB67AE85UL; - md->sha256.state[2] = 0x3C6EF372UL; - md->sha256.state[3] = 0xA54FF53AUL; - md->sha256.state[4] = 0x510E527FUL; - md->sha256.state[5] = 0x9B05688CUL; - md->sha256.state[6] = 0x1F83D9ABUL; - md->sha256.state[7] = 0x5BE0CD19UL; - return CRYPT_OK; -} - /** Process a block of memory though the hash @param md The hash state @@ -257,7 +233,23 @@ int sha256_c_init(hash_state * md) @param inlen The length of the data (octets) @return CRYPT_OK if successful */ -HASH_PROCESS(sha256_c_process,s_sha256_compress, sha256, 64) +static HASH_PROCESS(s_sha256_c_process,s_sha256_compress, sha256, 64) + +static LTC_INLINE void s_sha256_c_fixup_state(hash_state * md) +{ + ulong32 *state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + if (state != md->sha256.state) { + XMEMMOVE(state, md->sha256.state_buf + md->sha256.align, 8 * sizeof(ulong32)); + md->sha256.state = state; + md->sha256.align = (unsigned char*)state - md->sha256.state_buf; + } +} + +int sha256_c_process (hash_state * md, const unsigned char *in, unsigned long inlen) +{ + s_sha256_c_fixup_state(md); + return s_sha256_c_process(md, in, inlen); +} /** Terminate the hash to get the digest @@ -276,6 +268,7 @@ int sha256_c_done(hash_state * md, unsigned char *out) return CRYPT_INVALID_ARG; } + s_sha256_c_fixup_state(md); /* increase the length of the message */ md->sha256.length += md->sha256.curlen * 8; diff --git a/src/hashes/sha2/sha256_desc.c b/src/hashes/sha2/sha256_desc.c index 1bf0c1f7a..f990ac46b 100644 --- a/src/hashes/sha2/sha256_desc.c +++ b/src/hashes/sha2/sha256_desc.c @@ -88,12 +88,22 @@ const struct ltc_hash_descriptor sha256_desc = */ int sha256_init(hash_state * md) { -#if defined LTC_SHA256_X86 - if(s_sha256_x86_is_supported()) { - return sha256_x86_init(md); - } -#endif - return sha256_c_init(md); + LTC_ARGCHK(md != NULL); + + md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + md->sha256.align = (unsigned char*)md->sha256.state - md->sha256.state_buf; + + md->sha256.curlen = 0; + md->sha256.length = 0; + md->sha256.state[0] = 0x6A09E667UL; + md->sha256.state[1] = 0xBB67AE85UL; + md->sha256.state[2] = 0x3C6EF372UL; + md->sha256.state[3] = 0xA54FF53AUL; + md->sha256.state[4] = 0x510E527FUL; + md->sha256.state[5] = 0x9B05688CUL; + md->sha256.state[6] = 0x1F83D9ABUL; + md->sha256.state[7] = 0x5BE0CD19UL; + return CRYPT_OK; } /** diff --git a/src/hashes/sha2/sha256_x86.c b/src/hashes/sha2/sha256_x86.c index 43a23c913..8f4d32f6f 100644 --- a/src/hashes/sha2/sha256_x86.c +++ b/src/hashes/sha2/sha256_x86.c @@ -37,7 +37,7 @@ const struct ltc_hash_descriptor sha256_x86_desc = { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, 9, - &sha256_x86_init, + &sha256_init, &sha256_x86_process, &sha256_x86_done, &sha256_x86_test, @@ -258,30 +258,6 @@ static int s_sha256_compress(hash_state * md, const unsigned char *buf) } #endif -/** - Initialize the hash state - @param md The hash state you wish to initialize - @return CRYPT_OK if successful -*/ -int sha256_x86_init(hash_state * md) -{ - LTC_ARGCHK(md != NULL); - - md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); - - md->sha256.curlen = 0; - md->sha256.length = 0; - md->sha256.state[0] = 0x6A09E667UL; - md->sha256.state[1] = 0xBB67AE85UL; - md->sha256.state[2] = 0x3C6EF372UL; - md->sha256.state[3] = 0xA54FF53AUL; - md->sha256.state[4] = 0x510E527FUL; - md->sha256.state[5] = 0x9B05688CUL; - md->sha256.state[6] = 0x1F83D9ABUL; - md->sha256.state[7] = 0x5BE0CD19UL; - return CRYPT_OK; -} - /** Process a block of memory though the hash @param md The hash state @@ -289,7 +265,23 @@ int sha256_x86_init(hash_state * md) @param inlen The length of the data (octets) @return CRYPT_OK if successful */ -HASH_PROCESS(sha256_x86_process,s_sha256_x86_compress, sha256, 64) +static HASH_PROCESS(s_sha256_x86_process,s_sha256_x86_compress, sha256, 64) + +static LTC_INLINE void s_sha256_x86_fixup_state(hash_state * md) +{ + ulong32 *state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + if (state != md->sha256.state) { + XMEMMOVE(state, md->sha256.state_buf + md->sha256.align, 8 * sizeof(ulong32)); + md->sha256.state = state; + md->sha256.align = (unsigned char*)state - md->sha256.state_buf; + } +} + +int sha256_x86_process (hash_state * md, const unsigned char *in, unsigned long inlen) +{ + s_sha256_x86_fixup_state(md); + return s_sha256_x86_process(md, in, inlen); +} /** Terminate the hash to get the digest @@ -308,6 +300,7 @@ int sha256_x86_done(hash_state * md, unsigned char *out) return CRYPT_INVALID_ARG; } + s_sha256_x86_fixup_state(md); /* increase the length of the message */ md->sha256.length += md->sha256.curlen * 8; diff --git a/src/hashes/sha3.c b/src/hashes/sha3.c index 07965f404..ec29e3864 100644 --- a/src/hashes/sha3.c +++ b/src/hashes/sha3.c @@ -99,7 +99,7 @@ const struct ltc_hash_descriptor shake256_desc = #endif #ifdef LTC_KECCAK -const struct ltc_hash_descriptor keccak_224_desc = +const struct ltc_hash_descriptor keccak224_desc = { "keccak224", /* name of hash */ 29, /* internal ID */ @@ -113,7 +113,7 @@ const struct ltc_hash_descriptor keccak_224_desc = NULL }; -const struct ltc_hash_descriptor keccak_256_desc = +const struct ltc_hash_descriptor keccak256_desc = { "keccak256", /* name of hash */ 30, /* internal ID */ @@ -127,7 +127,7 @@ const struct ltc_hash_descriptor keccak_256_desc = NULL }; -const struct ltc_hash_descriptor keccak_384_desc = +const struct ltc_hash_descriptor keccak384_desc = { "keccak384", /* name of hash */ 31, /* internal ID */ @@ -141,7 +141,7 @@ const struct ltc_hash_descriptor keccak_384_desc = NULL }; -const struct ltc_hash_descriptor keccak_512_desc = +const struct ltc_hash_descriptor keccak512_desc = { "keccak512", /* name of hash */ 32, /* internal ID */ diff --git a/src/hashes/sm3.c b/src/hashes/sm3.c index acc73aee6..f72ae81dd 100644 --- a/src/hashes/sm3.c +++ b/src/hashes/sm3.c @@ -16,7 +16,7 @@ const struct ltc_hash_descriptor sm3_desc = { "sm3", /* name of hash */ - 34, /* internal ID */ + 36, /* internal ID */ 32, /* Size of digest in octets */ 64, /* Input block size in octets */ {1,2,156,10197,1,401}, /* ASN.1 OID 1.2.156.10197.1.401 */ diff --git a/src/headers/tomcrypt_hash.h b/src/headers/tomcrypt_hash.h index 0be5b4c56..29b220445 100644 --- a/src/headers/tomcrypt_hash.h +++ b/src/headers/tomcrypt_hash.h @@ -39,7 +39,7 @@ struct sha256_state { ulong64 length; ulong32 *state, curlen; unsigned char buf[64]; - unsigned char state_buf[LTC_ALIGNED_BUF_SIZE(ulong32, 8, 16)]; + unsigned char state_buf[LTC_ALIGNED_BUF_SIZE(ulong32, 8, 16)], align; }; #endif @@ -48,7 +48,7 @@ struct sha1_state { ulong64 length; ulong32 *state, curlen; unsigned char buf[64]; - unsigned char state_buf[LTC_ALIGNED_BUF_SIZE(ulong32, 5, 16)]; + unsigned char state_buf[LTC_ALIGNED_BUF_SIZE(ulong32, 5, 16)], align; }; #endif @@ -331,13 +331,13 @@ int sha3_shake_memory(int num, const unsigned char *in, unsigned long inlen, uns #define keccak_256_init(a) sha3_256_init(a) #define keccak_224_init(a) sha3_224_init(a) #define keccak_process(a,b,c) sha3_process(a,b,c) -extern const struct ltc_hash_descriptor keccak_512_desc; +extern const struct ltc_hash_descriptor keccak512_desc; int keccak_512_test(void); -extern const struct ltc_hash_descriptor keccak_384_desc; +extern const struct ltc_hash_descriptor keccak384_desc; int keccak_384_test(void); -extern const struct ltc_hash_descriptor keccak_256_desc; +extern const struct ltc_hash_descriptor keccak256_desc; int keccak_256_test(void); -extern const struct ltc_hash_descriptor keccak_224_desc; +extern const struct ltc_hash_descriptor keccak224_desc; int keccak_224_test(void); int keccak_done(hash_state *md, unsigned char *out); #endif @@ -407,14 +407,14 @@ int sha256_done(hash_state * md, unsigned char *out); int sha256_test(void); extern const struct ltc_hash_descriptor sha256_desc; -int sha256_c_init(hash_state * md); +#define sha256_c_init sha256_init int sha256_c_process(hash_state * md, const unsigned char *in, unsigned long inlen); int sha256_c_done(hash_state * md, unsigned char *out); int sha256_c_test(void); extern const struct ltc_hash_descriptor sha256_portable_desc; #ifdef LTC_SHA256_X86 -int sha256_x86_init(hash_state * md); +#define sha256_x86_init sha256_init int sha256_x86_process(hash_state * md, const unsigned char *in, unsigned long inlen); int sha256_x86_done(hash_state * md, unsigned char *out); int sha256_x86_test(void); @@ -432,14 +432,14 @@ int sha224_done(hash_state * md, unsigned char *out); int sha224_test(void); extern const struct ltc_hash_descriptor sha224_desc; -int sha224_c_init(hash_state * md); +#define sha224_c_init sha224_init #define sha224_c_process sha256_c_process int sha224_c_done(hash_state * md, unsigned char *out); int sha224_c_test(void); extern const struct ltc_hash_descriptor sha224_portable_desc; #ifdef LTC_SHA224_X86 -int sha224_x86_init(hash_state * md); +#define sha224_x86_init sha224_init #define sha224_x86_process sha256_x86_process int sha224_x86_done(hash_state * md, unsigned char *out); int sha224_x86_test(void); @@ -454,14 +454,14 @@ int sha1_done(hash_state * md, unsigned char *out); int sha1_test(void); extern const struct ltc_hash_descriptor sha1_desc; -int sha1_c_init(hash_state * md); +#define sha1_c_init sha1_init int sha1_c_process(hash_state * md, const unsigned char *in, unsigned long inlen); int sha1_c_done(hash_state * md, unsigned char *out); int sha1_c_test(void); extern const struct ltc_hash_descriptor sha1_portable_desc; #ifdef LTC_SHA1_X86 -int sha1_x86_init(hash_state * md); +#define sha1_x86_init sha1_init int sha1_x86_process(hash_state * md, const unsigned char *in, unsigned long inlen); int sha1_x86_done(hash_state * md, unsigned char *out); int sha1_x86_test(void); diff --git a/src/misc/crypt/crypt_register_all_hashes.c b/src/misc/crypt/crypt_register_all_hashes.c index dcf3d5925..151555dac 100644 --- a/src/misc/crypt/crypt_register_all_hashes.c +++ b/src/misc/crypt/crypt_register_all_hashes.c @@ -69,10 +69,10 @@ int register_all_hashes(void) REGISTER_HASH(&blake2b_512_desc); #endif #ifdef LTC_KECCAK - REGISTER_HASH(&keccak_224_desc); - REGISTER_HASH(&keccak_256_desc); - REGISTER_HASH(&keccak_384_desc); - REGISTER_HASH(&keccak_512_desc); + REGISTER_HASH(&keccak224_desc); + REGISTER_HASH(&keccak256_desc); + REGISTER_HASH(&keccak384_desc); + REGISTER_HASH(&keccak512_desc); #endif #ifdef LTC_RIPEMD128 REGISTER_HASH(&rmd128_desc); diff --git a/src/misc/pem/pem_pkcs.c b/src/misc/pem/pem_pkcs.c index 6a6d4e457..2bd3f8536 100644 --- a/src/misc/pem/pem_pkcs.c +++ b/src/misc/pem/pem_pkcs.c @@ -216,9 +216,10 @@ int pem_decode_pkcs_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *pw_c int pem_decode_pkcs(const void *buf, unsigned long len, ltc_pka_key *k, const password_ctx *pw_ctx) { - LTC_ARGCHK(buf != NULL); - LTC_ARGCHK(len != 0); + LTC_ARGCHK(buf != NULL || len == 0); LTC_ARGCHK(k != NULL); + if (len == 0) + return CRYPT_OK; { struct get_char g = pem_get_char_init(buf, len); return s_decode(&g, k, pw_ctx); diff --git a/src/misc/pem/pem_ssh.c b/src/misc/pem/pem_ssh.c index d4de0865a..04b353788 100644 --- a/src/misc/pem/pem_ssh.c +++ b/src/misc/pem/pem_ssh.c @@ -541,11 +541,15 @@ static int s_parse_line(char *line, unsigned long *len, ltc_pka_key *key, char * static int s_read_authorized_keys(const void *buf, unsigned long len, ssh_authorized_key_cb cb, void *ctx) { char *s; - int err; + int err = CRYPT_OK; unsigned long clen = len; - ltc_pka_key *key = XCALLOC(1, sizeof(*key)); + ltc_pka_key *key = NULL; char *comment = NULL; - void *cpy = XMALLOC(len); + void *cpy = NULL; + if (clen == 0) + return CRYPT_OK; + key = XCALLOC(1, sizeof(*key)); + cpy = XMALLOC(len); if (key == NULL || cpy == NULL) { if (cpy) XFREE(cpy); @@ -834,9 +838,10 @@ int ssh_read_authorized_keys_filehandle(FILE *f, ssh_authorized_key_cb cb, void int pem_decode_openssh(const void *buf, unsigned long len, ltc_pka_key *k, const password_ctx *pw_ctx) { - LTC_ARGCHK(buf != NULL); - LTC_ARGCHK(len != 0); + LTC_ARGCHK(buf != NULL || len == 0); LTC_ARGCHK(k != NULL); + if (len == 0) + return CRYPT_OK; { struct get_char g = pem_get_char_init(buf, len); return s_decode_openssh(&g, k, pw_ctx); @@ -845,9 +850,10 @@ int pem_decode_openssh(const void *buf, unsigned long len, ltc_pka_key *k, const int ssh_read_authorized_keys(const void *buf, unsigned long len, ssh_authorized_key_cb cb, void *ctx) { - LTC_ARGCHK(buf != NULL); - LTC_ARGCHK(len != 0); + LTC_ARGCHK(buf != NULL || len == 0); LTC_ARGCHK(cb != NULL); + if (len == 0) + return CRYPT_OK; return s_read_authorized_keys(buf, len, cb, ctx); } diff --git a/src/pk/asn1/x509/x509_import_spki.c b/src/pk/asn1/x509/x509_import_spki.c index 4e007acf0..b1b92ea5b 100644 --- a/src/pk/asn1/x509/x509_import_spki.c +++ b/src/pk/asn1/x509/x509_import_spki.c @@ -37,6 +37,32 @@ static int s_ed25519_import_spki(const unsigned char *in, unsigned long inlen, v } #endif +#ifdef LTC_CURVE448 +static int s_x448_import_pub(const unsigned char *in, unsigned long inlen, void *key) +{ + return x448_import_raw(in, inlen, PK_PUBLIC, key); +} +static int s_x448_import_spki(const unsigned char *in, unsigned long inlen, void *key) +{ + return x509_process_public_key_from_spki(in, inlen, + LTC_OID_X448, + LTC_ASN1_EOL, NULL, NULL, + s_x448_import_pub, key); +} + +static int s_ed448_import_pub(const unsigned char *in, unsigned long inlen, void *key) +{ + return ed448_import_raw(in, inlen, PK_PUBLIC, key); +} +static int s_ed448_import_spki(const unsigned char *in, unsigned long inlen, void *key) +{ + return x509_process_public_key_from_spki(in, inlen, + LTC_OID_ED448, + LTC_ASN1_EOL, NULL, NULL, + s_ed448_import_pub, key); +} +#endif + static const import_fn s_import_spki_fns[LTC_PKA_NUM] = { #ifdef LTC_MRSA [LTC_PKA_RSA] = (import_fn)rsa_import_spki, @@ -53,8 +79,8 @@ static const import_fn s_import_spki_fns[LTC_PKA_NUM] = { [LTC_PKA_ED25519] = (import_fn)s_ed25519_import_spki, #endif #ifdef LTC_CURVE448 - [LTC_PKA_X448] = (import_fn)x448_import_x509, - [LTC_PKA_ED448] = (import_fn)ed448_import_x509, + [LTC_PKA_X448] = (import_fn)s_x448_import_spki, + [LTC_PKA_ED448] = (import_fn)s_ed448_import_spki, #endif }; diff --git a/tests/cipher_hash_test.c b/tests/cipher_hash_test.c index c296fffd8..f214a7911 100644 --- a/tests/cipher_hash_test.c +++ b/tests/cipher_hash_test.c @@ -4,12 +4,66 @@ #include +static int do_hash_test(const struct ltc_hash_descriptor *desc, hash_state *md, hash_state *md2, unsigned long n) +{ + hash_state md3_, *md3 = &md3_; + char pt[] = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."; + unsigned long ptlen = sizeof(pt); + unsigned long ptlen_part1 = (ptlen*2)/3; + unsigned long ptlen_part2 = (ptlen - ptlen_part1) / 2; + unsigned char buf[2][MAXBLOCKSIZE]; + void *pt0 = pt, *pt1 = (pt + ptlen_part1); + void *pt2 = (pt + ptlen_part1 + ptlen_part2); + + desc->init(md); + desc->process(md, pt0, ptlen_part1); + XMEMCPY(md2, md, sizeof(*md)); + desc->process(md, pt1, ptlen_part2); + desc->process(md2, pt1, ptlen_part2); + XMEMCPY(md3, md2, sizeof(*md2)); + desc->process(md, pt2, ptlen - ptlen_part1 - ptlen_part2); + desc->process(md3, pt2, ptlen - ptlen_part1 - ptlen_part2); + desc->done(md, buf[0]); + desc->done(md3, buf[1]); + if (ltc_compare_testvector(buf[1], desc->hashsize, buf[0], desc->hashsize, desc->name, n)) { + return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; +} + +static int unaligned_hash_md_tests(void) +{ + unsigned char md_buf[sizeof(hash_state) + 16]; + unsigned long n; + hash_state md; + for (n = 0; n < 16; n+=8) { + hash_state *md2 = (void*)&md_buf[n]; + int x; + for (x = 0; x < TAB_SIZE && hash_descriptor[x].name != NULL; x++) { + DO(do_hash_test(&hash_descriptor[x], &md, md2, n)); + } + + if (shani_is_supported()) { +#if defined(LTC_SHA256) && defined(LTC_SHA256_X86) + DO(do_hash_test(&sha256_x86_desc, &md, md2, n)); +#endif +#if defined(LTC_SHA224) && defined(LTC_SHA224_X86) + DO(do_hash_test(&sha224_x86_desc, &md, md2, n)); +#endif +#if defined(LTC_SHA1) && defined(LTC_SHA1_X86) + DO(do_hash_test(&sha1_x86_desc, &md, md2, n)); +#endif + } + } + return CRYPT_OK; +} + int cipher_hash_test(void) { int x; /* test block ciphers */ - for (x = 0; cipher_descriptor[x].name != NULL; x++) { + for (x = 0; x < TAB_SIZE && cipher_descriptor[x].name != NULL; x++) { DOX(cipher_descriptor[x].test(), cipher_descriptor[x].name); } @@ -55,7 +109,7 @@ int cipher_hash_test(void) #endif /* test hashes */ - for (x = 0; hash_descriptor[x].name != NULL; x++) { + for (x = 0; x < TAB_SIZE && hash_descriptor[x].name != NULL; x++) { DOX(hash_descriptor[x].test(), hash_descriptor[x].name); } @@ -91,5 +145,7 @@ int cipher_hash_test(void) DO(kangaroo_twelve_test()); #endif + DO(unaligned_hash_md_tests()); + return 0; } diff --git a/tests/common.c b/tests/common.c index c37b19356..67e4a4d27 100644 --- a/tests/common.c +++ b/tests/common.c @@ -72,6 +72,8 @@ static off_t fsize(const char *filename) struct stat st; if (stat(filename, &st) == 0) { + if (S_ISDIR(st.st_mode)) + return -2; /* filename is no regular file */ if (!S_ISREG(st.st_mode)) return 0; @@ -135,7 +137,7 @@ int test_process_dir(const char *path, void *ctx, dir_iter_cb iter, dir_fiter_cb strcat(fname, "/"); strcat(fname, de->d_name); fsz = fsize(fname); - if (fsz == 0) + if (fsz == -2) continue; if (fsz == -1) { err = CRYPT_FILE_NOTFOUND; diff --git a/tests/pem/empty b/tests/pem/empty new file mode 100644 index 000000000..e69de29bb diff --git a/tests/pem/ssh/authorized_keys/empty b/tests/pem/ssh/authorized_keys/empty new file mode 100644 index 000000000..e69de29bb diff --git a/tests/pem/ssh/empty b/tests/pem/ssh/empty new file mode 100644 index 000000000..e69de29bb diff --git a/tests/prng_test.c b/tests/prng_test.c index d8d481173..61d633e54 100644 --- a/tests/prng_test.c +++ b/tests/prng_test.c @@ -51,7 +51,7 @@ int prng_test(void) #endif /* test prngs (test, import/export) */ - for (x = 0; prng_descriptor[x].name != NULL; x++) { + for (x = 0; x < TAB_SIZE && prng_descriptor[x].name != NULL; x++) { if(strstr(prng_descriptor[x].name, "no_prng") == prng_descriptor[x].name) continue; DOX(prng_descriptor[x].test(), prng_descriptor[x].name); DOX(prng_descriptor[x].start(&nprng), prng_descriptor[x].name); diff --git a/tests/test.c b/tests/test.c index 57db1754a..336ffd5c0 100644 --- a/tests/test.c +++ b/tests/test.c @@ -6,7 +6,7 @@ #define GIT_VERSION "Undefined version" #endif -#define LTC_TEST_FN(f) { f, #f } +#define LTC_TEST_FN(f) { f ## _test, #f } typedef struct { int (*fn)(void); @@ -15,41 +15,41 @@ typedef struct { static const test_function test_functions[] = { - LTC_TEST_FN(store_test), - LTC_TEST_FN(rotate_test), - LTC_TEST_FN(cipher_hash_test), - LTC_TEST_FN(misc_test), - LTC_TEST_FN(mpi_test), - LTC_TEST_FN(mac_test), - LTC_TEST_FN(modes_test), - LTC_TEST_FN(der_test), - LTC_TEST_FN(pkcs_1_test), - LTC_TEST_FN(pkcs_1_pss_test), - LTC_TEST_FN(pkcs_1_oaep_test), - LTC_TEST_FN(pkcs_1_emsa_test), - LTC_TEST_FN(pkcs_1_eme_test), - LTC_TEST_FN(rsa_test), - LTC_TEST_FN(dh_test), - LTC_TEST_FN(ecc_test), - LTC_TEST_FN(dsa_test), - LTC_TEST_FN(ed25519_test), - LTC_TEST_FN(ed25519_mpi_test), - LTC_TEST_FN(x25519_test), - LTC_TEST_FN(x25519_mpi_test), - LTC_TEST_FN(ed448_test), - LTC_TEST_FN(ed448_mpi_test), - LTC_TEST_FN(x448_test), - LTC_TEST_FN(x448_mpi_test), - LTC_TEST_FN(file_test), - LTC_TEST_FN(multi_test), - LTC_TEST_FN(pem_test), - LTC_TEST_FN(deprecated_test), - LTC_TEST_FN(nop_test), + LTC_TEST_FN(store), + LTC_TEST_FN(rotate), + LTC_TEST_FN(cipher_hash), + LTC_TEST_FN(misc), + LTC_TEST_FN(mpi), + LTC_TEST_FN(mac), + LTC_TEST_FN(modes), + LTC_TEST_FN(der), + LTC_TEST_FN(pkcs_1), + LTC_TEST_FN(pkcs_1_pss), + LTC_TEST_FN(pkcs_1_oaep), + LTC_TEST_FN(pkcs_1_emsa), + LTC_TEST_FN(pkcs_1_eme), + LTC_TEST_FN(rsa), + LTC_TEST_FN(dh), + LTC_TEST_FN(ecc), + LTC_TEST_FN(dsa), + LTC_TEST_FN(ed25519), + LTC_TEST_FN(ed25519_mpi), + LTC_TEST_FN(x25519), + LTC_TEST_FN(x25519_mpi), + LTC_TEST_FN(ed448), + LTC_TEST_FN(ed448_mpi), + LTC_TEST_FN(x448), + LTC_TEST_FN(x448_mpi), + LTC_TEST_FN(file), + LTC_TEST_FN(multi), + LTC_TEST_FN(pem), + LTC_TEST_FN(deprecated), + LTC_TEST_FN(nop), /* keep the prng_test always at the end as * it has to be handled specially when * testing with LTC_PTHREAD enabled */ - LTC_TEST_FN(prng_test), + LTC_TEST_FN(prng), }; @@ -258,10 +258,10 @@ static void s_unregister_all(void) unregister_hash(&shake256_desc); #endif #ifdef LTC_KECCAK - unregister_hash(&keccak_224_desc); - unregister_hash(&keccak_256_desc); - unregister_hash(&keccak_384_desc); - unregister_hash(&keccak_512_desc); + unregister_hash(&keccak224_desc); + unregister_hash(&keccak256_desc); + unregister_hash(&keccak384_desc); + unregister_hash(&keccak512_desc); #endif #ifdef LTC_RIPEMD128 unregister_hash(&rmd128_desc); @@ -343,6 +343,21 @@ static void register_algs(void) exit(EXIT_FAILURE); } } +static void LTC_NORETURN die(int status) +{ + FILE* o = status == EXIT_SUCCESS ? stdout : stderr; + fprintf(o, + "Usage: test [<-h|-l|case>] [mpi]\n\n" + "Run all built-in tests, or only the one given in .\n\n" + "\tcase\tThe algorithms to test. Use the '-l' option to check for valid values.\n" + "\tmpi\tThe MPI provider to use.\n" + "\t-l\tList all tests that can be executed.\n" + "\t-h\tThe help you're looking at.\n\n" + "Examples:\n" + "\ttest rsa tfm\t\tWill run only the RSA tests with TomsFastMath as MPI provider.\n" + ); + exit(status); +} int main(int argc, char **argv) { @@ -355,6 +370,23 @@ int main(int argc, char **argv) char *single_test = NULL; ulong64 ts; long delta, dur, real = 0; + + if (argc > 1) { + if (strstr(argv[1], "-h")) { + die(EXIT_SUCCESS); + } else if (strstr(argv[1], "-l")) { + printf("The following tests are available:\n"); + for (i = 0; i < LTC_ARRAY_SIZE(test_functions); ++i) { + if (i % 4 == 0) + putchar('\n'); + printf(" %-13s", test_functions[i].name); + } + putchar('\n'); + exit(0); + } + } + + register_algs(); printf("LTC_VERSION = %s\n%s\n\n", GIT_VERSION, crypt_build_settings); @@ -412,7 +444,7 @@ int main(int argc, char **argv) #endif } - fn_len = fn_len + (4 - (fn_len % 4)); + fn_len = fn_len + (8 - (fn_len % 8)); /* single test name from commandline */ if (argc > 1) single_test = argv[1]; @@ -469,6 +501,12 @@ int main(int argc, char **argv) XFREE(tinfo); #endif + if (cipher_descriptor[TAB_SIZE - 1].name != NULL) + printf("cipher_descriptor Table full\n"); + if (hash_descriptor[TAB_SIZE - 1].name != NULL) + printf("hash_descriptor Table full\n"); + if (prng_descriptor[TAB_SIZE - 1].name != NULL) + printf("prng_descriptor Table full\n"); x = (fail > 0 || fail+pass+nop == 0) ? EXIT_FAILURE : EXIT_SUCCESS; printf("\n\n%s: passed=%d failed=%d nop=%d duration=%.1fsec real=%.1fsec\n", x ? "FAILURE" : "SUCCESS", pass, fail, nop, (double)(dur)/(1000*1000), (double)(real)/(1000*1000)); return x;