Auto-generate table of hashes.

Fixes: 6c885c7732 ("SM3 hash function")
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
This commit is contained in:
Steffen Jaeckel 2026-05-20 13:43:15 +02:00 committed by Karel Miko
parent 54f5803ad8
commit fb857d83ed
3 changed files with 263 additions and 76 deletions

View file

@ -63,16 +63,38 @@ static const char *s_map_mode(enum cipher_mode mode)
exit(1);
}
static void LTC_NORETURN die(int status)
static int print_pem_ciphers(void)
{
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);
unsigned long 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);
memcpy(nbuf, pem_dek_infos[n].name, nlen);
nbuf[nlen-1] = '}';
printf("\\hline \\texttt{%-18s & %-15s & %-25ld & %-6s \\\\\n",
nbuf, s_map_cipher(pem_dek_infos[n].algo),
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};
size_t nlen = strlen(ssh_ciphers[n].name);
memcpy(nbuf, ssh_ciphers[n].name, nlen);
nbuf[nlen] = '}';
printf("\\hline \\texttt{%-30s & %-16s & %-24ld & %-6s \\\\\n",
nbuf, s_map_cipher(ssh_ciphers[n].algo),
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)
@ -88,35 +110,9 @@ static int s_to_lower(const char *in, char *out, unsigned long *outlen)
return CRYPT_OK;
}
int main(int argc, char **argv)
static int print_ecc_curves(void)
{
unsigned long n;
if (argc > 1 && strstr(argv[1], "-h"))
die(0);
printf("PEM 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);
memcpy(nbuf, pem_dek_infos[n].name, nlen);
nbuf[nlen-1] = '}';
printf("\\hline \\texttt{%-18s & %-15s & %-25ld & %-6s \\\\\n",
nbuf, s_map_cipher(pem_dek_infos[n].algo),
pem_dek_infos[n].keylen * 8,
s_map_mode(pem_dek_infos[n].mode));
}
printf("\nSSH ciphers:\n\n");
for (n = 0; n < ssh_ciphers_num; ++n) {
char nbuf[32] = {0};
size_t nlen = strlen(ssh_ciphers[n].name);
memcpy(nbuf, ssh_ciphers[n].name, nlen);
nbuf[nlen] = '}';
printf("\\hline \\texttt{%-30s & %-16s & %-24ld & %-6s \\\\\n",
nbuf, s_map_cipher(ssh_ciphers[n].algo),
ssh_ciphers[n].keylen * 8,
s_map_mode(ssh_ciphers[n].mode));
}
printf("\nECC curves:\n\n");
for (n = 0; ltc_ecc_curves[n].OID != NULL; ++n) {
const char * const *names;
@ -160,6 +156,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;
}

View file

@ -3066,52 +3066,75 @@ int unregister_hash(const struct ltc_hash_descriptor *hash);
\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}

View file

@ -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 */