Create table of supported ECC curves programmatically

Related to #349

Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
This commit is contained in:
Steffen Jaeckel 2025-10-06 12:08:47 +02:00
parent 47162b9609
commit d8a62f3367
9 changed files with 121 additions and 47 deletions

View file

@ -22,12 +22,12 @@ fi
function run_gcc() {
bash .ci/check_source.sh "CHECK_SOURCES" "$2" "$3" "$4" "$5"
make -j$(nproc) pem-info V=0
make -j$(nproc) latex-tables V=0
echo "verify docs..."
while read -r line; do
grep -q -e "$line" doc/crypt.tex || { echo "Failed to find \"$line\" in doc/crypt.tex"; exit 1; }
done < <(./pem-info | grep '^\\' | sed 's@\\@\\\\@g')
done < <(./latex-tables | grep '^\\' | sed 's@\\@\\\\@g')
echo "docs OK"
make clean &>/dev/null

4
.gitignore vendored
View file

@ -42,8 +42,8 @@ openssl-enc
openssl-enc.exe
openssh-privkey
openssh-privkey.exe
pem-info
pem-info.exe
latex-tables
latex-tables.exe
sizes
sizes.exe
small

View file

@ -4,7 +4,7 @@
option(BUILD_USEFUL_DEMOS "Build useful demos (hashsum)" FALSE)
option(
BUILD_USABLE_DEMOS
"Build usable demos (aesgcm constants crypt openssh-privkey openssl-enc pem-info sizes timing)"
"Build usable demos (aesgcm constants crypt openssh-privkey openssl-enc latex-tables sizes timing)"
FALSE
)
option(BUILD_TEST_DEMOS "Build test demos (small tv_gen)" FALSE)
@ -28,7 +28,7 @@ endif()
#
# Demos that are usable but only rarely make sense to be installed
#
# USEABLE_DEMOS = aesgcm constants crypt der_print_flexi openssh-privkey openssl-enc pem-info sizes timing
# USEABLE_DEMOS = aesgcm constants crypt der_print_flexi latex-tables openssh-privkey openssl-enc sizes timing
# -----------------------------------------------------------------------------
if(BUILD_USABLE_DEMOS)
@ -39,9 +39,9 @@ if(BUILD_USABLE_DEMOS)
constants
crypt
der_print_flexi
latex-tables
openssh-privkey
openssl-enc
pem-info
sizes
timing
)

View file

@ -74,13 +74,26 @@ static void LTC_NORETURN die(int status)
{
FILE* o = status == EXIT_SUCCESS ? stdout : stderr;
fprintf(o,
"Usage: pem-info [<-h>]\n\n"
"Generate LaTeX tables from the supported PEM resp. SSH ciphers.\n\n"
"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)
{
unsigned long n;
@ -110,6 +123,50 @@ int main(int argc, char **argv)
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;
char lower[32] = {0}, buf[64] = {0};
unsigned long m, bufl = 0, lowerl;
int err = ecc_get_curve_names(ltc_ecc_curves[n].OID, &names);
if (err != CRYPT_OK) {
printf("\\error: OID %s not found (%s)\n", ltc_ecc_curves[n].OID, error_to_string(err));
return EXIT_FAILURE;
}
for (m = 1; names[m]; ++m) {
const char *name = names[m];
if (memcmp(name, "P-", 2) == 0 || memcmp(name, "ECC-", 4) == 0) {
/* Use the original name */
} else {
lowerl = sizeof(lower);
if ((err = s_to_lower(name, lower, &lowerl)) != CRYPT_OK) {
printf("\\error: %s could not be converted to lowercase (%s)\n", name, error_to_string(err));
return EXIT_FAILURE;
}
name = lower;
}
if (m == 1) {
err = snprintf(buf + bufl, sizeof(buf) - bufl, "%s", name);
} else {
err = snprintf(buf + bufl, sizeof(buf) - bufl, ", %s", name);
}
if (err == -1 || (unsigned)err > sizeof(buf) - bufl) {
printf("\\error: snprintf returned %d at %s\n", err, name);
return EXIT_FAILURE;
}
bufl += err;
}
lower[0] = '{';
lowerl = sizeof(lower) - 2;
if ((err = s_to_lower(names[0], &lower[1], &lowerl)) != CRYPT_OK) {
printf("\\error: %s could not be converted to lowercase (%s)\n", names[0], error_to_string(err));
return EXIT_FAILURE;
}
lower[lowerl + 1] = '}';
lower[lowerl + 2] = '\0';
printf("\\hline \\texttt%-17s & %-36s & %-21s \\\\\n", lower, buf, ltc_ecc_curves[n].OID);
}
return 0;
}
#else

View file

@ -5331,42 +5331,42 @@ defined by own parameters (the only limitation is that the curve must be based o
\begin{table}[H]
\begin{center}
\begin{tabular}{|l|l|l|l|}
\hline \textbf{Curve Name} & \textbf{Alternative Names} & \textbf{OID} \\
\hline secp112r1 & & 1.3.132.0.6 \\
\hline secp112r2 & & 1.3.132.0.7 \\
\hline secp128r1 & & 1.3.132.0.28 \\
\hline secp128r2 & & 1.3.132.0.29 \\
\hline secp160r1 & & 1.3.132.0.8 \\
\hline secp160r2 & & 1.3.132.0.30 \\
\hline secp160k1 & & 1.3.132.0.9 \\
\hline secp192r1 & nistp192, prime192v1, P-192 & 1.2.840.10045.3.1.1 \\
\hline prime192v2 & & 1.2.840.10045.3.1.2 \\
\hline prime192v3 & & 1.2.840.10045.3.1.3 \\
\hline secp192k1 & & 1.3.132.0.31 \\
\hline secp224r1 & nistp224, P-224 & 1.3.132.0.33 \\
\hline secp224k1 & & 1.3.132.0.32 \\
\hline secp256r1 & nistp256, prime256v1, P-256 & 1.2.840.10045.3.1.7 \\
\hline secp256k1 & & 1.3.132.0.10 \\
\hline secp384r1 & nistp384, P-384 & 1.3.132.0.34 \\
\hline secp521r1 & nistp521, P-521 & 1.3.132.0.35 \\
\hline prime239v1 & & 1.2.840.10045.3.1.4 \\
\hline prime239v2 & & 1.2.840.10045.3.1.5 \\
\hline prime239v3 & & 1.2.840.10045.3.1.6 \\
\hline brainpoolP160r1 & & 1.3.36.3.3.2.8.1.1.1 \\
\hline brainpoolP192r1 & & 1.3.36.3.3.2.8.1.1.3 \\
\hline brainpoolP224r1 & & 1.3.36.3.3.2.8.1.1.5 \\
\hline brainpoolP256r1 & & 1.3.36.3.3.2.8.1.1.7 \\
\hline brainpoolP320r1 & & 1.3.36.3.3.2.8.1.1.9 \\
\hline brainpoolP384r1 & & 1.3.36.3.3.2.8.1.1.11 \\
\hline brainpoolP512r1 & & 1.3.36.3.3.2.8.1.1.13 \\
\hline brainpoolP160t1 & & 1.3.36.3.3.2.8.1.1.2 \\
\hline brainpoolP192t1 & & 1.3.36.3.3.2.8.1.1.4 \\
\hline brainpoolP224t1 & & 1.3.36.3.3.2.8.1.1.6 \\
\hline brainpoolP256t1 & & 1.3.36.3.3.2.8.1.1.8 \\
\hline brainpoolP320t1 & & 1.3.36.3.3.2.8.1.1.10 \\
\hline brainpoolP384t1 & & 1.3.36.3.3.2.8.1.1.12 \\
\hline brainpoolP512t1 & & 1.3.36.3.3.2.8.1.1.14 \\
\hline
\hline \textbf{Curve Name} & \textbf{Alternative Names} & \textbf{OID} \\
\hline \texttt{secp112r1} & ECC-112 & 1.3.132.0.6 \\
\hline \texttt{secp112r2} & & 1.3.132.0.7 \\
\hline \texttt{secp128r1} & ECC-128 & 1.3.132.0.28 \\
\hline \texttt{secp128r2} & & 1.3.132.0.29 \\
\hline \texttt{secp160r1} & ECC-160 & 1.3.132.0.8 \\
\hline \texttt{secp160r2} & & 1.3.132.0.30 \\
\hline \texttt{secp160k1} & & 1.3.132.0.9 \\
\hline \texttt{secp192r1} & nistp192, prime192v1, ECC-192, P-192 & 1.2.840.10045.3.1.1 \\
\hline \texttt{prime192v2} & & 1.2.840.10045.3.1.2 \\
\hline \texttt{prime192v3} & & 1.2.840.10045.3.1.3 \\
\hline \texttt{secp192k1} & & 1.3.132.0.31 \\
\hline \texttt{secp224r1} & nistp224, ECC-224, P-224 & 1.3.132.0.33 \\
\hline \texttt{secp224k1} & & 1.3.132.0.32 \\
\hline \texttt{secp256r1} & nistp256, prime256v1, ECC-256, P-256 & 1.2.840.10045.3.1.7 \\
\hline \texttt{secp256k1} & & 1.3.132.0.10 \\
\hline \texttt{secp384r1} & nistp384, ECC-384, P-384 & 1.3.132.0.34 \\
\hline \texttt{secp521r1} & nistp521, ECC-521, P-521 & 1.3.132.0.35 \\
\hline \texttt{prime239v1} & & 1.2.840.10045.3.1.4 \\
\hline \texttt{prime239v2} & & 1.2.840.10045.3.1.5 \\
\hline \texttt{prime239v3} & & 1.2.840.10045.3.1.6 \\
\hline \texttt{brainpoolp160r1} & & 1.3.36.3.3.2.8.1.1.1 \\
\hline \texttt{brainpoolp192r1} & & 1.3.36.3.3.2.8.1.1.3 \\
\hline \texttt{brainpoolp224r1} & & 1.3.36.3.3.2.8.1.1.5 \\
\hline \texttt{brainpoolp256r1} & & 1.3.36.3.3.2.8.1.1.7 \\
\hline \texttt{brainpoolp320r1} & & 1.3.36.3.3.2.8.1.1.9 \\
\hline \texttt{brainpoolp384r1} & & 1.3.36.3.3.2.8.1.1.11 \\
\hline \texttt{brainpoolp512r1} & & 1.3.36.3.3.2.8.1.1.13 \\
\hline \texttt{brainpoolp160t1} & & 1.3.36.3.3.2.8.1.1.2 \\
\hline \texttt{brainpoolp192t1} & & 1.3.36.3.3.2.8.1.1.4 \\
\hline \texttt{brainpoolp224t1} & & 1.3.36.3.3.2.8.1.1.6 \\
\hline \texttt{brainpoolp256t1} & & 1.3.36.3.3.2.8.1.1.8 \\
\hline \texttt{brainpoolp320t1} & & 1.3.36.3.3.2.8.1.1.10 \\
\hline \texttt{brainpoolp384t1} & & 1.3.36.3.3.2.8.1.1.12 \\
\hline \texttt{brainpoolp512t1} & & 1.3.36.3.3.2.8.1.1.14 \\
\hline
\end{tabular}
\caption{Built--In Elliptic Curves over GF(p)}
\end{center}

View file

@ -180,7 +180,7 @@ TEST=test
USEFUL_DEMOS = hashsum
# Demos that are usable but only rarely make sense to be installed
USEABLE_DEMOS = aesgcm constants crypt der_print_flexi openssh-privkey openssl-enc pem-info sizes timing
USEABLE_DEMOS = aesgcm constants crypt der_print_flexi latex-tables openssh-privkey openssl-enc sizes timing
# Demos that are used for testing or measuring
TEST_DEMOS = small tv_gen

View file

@ -433,6 +433,7 @@ int dh_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dh_key
int ecc_set_curve_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key);
int ecc_copy_curve(const ecc_key *srckey, ecc_key *key);
int ecc_set_curve_by_size(int size, ecc_key *key);
int ecc_get_curve_names(const char *oid, const char * const **names);
int ecc_import_subject_public_key_info(const unsigned char *in, unsigned long inlen, ecc_key *key);
#ifdef LTC_DER
int ecc_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, ecc_key *key);

View file

@ -28,7 +28,7 @@ const struct blockcipher_info ssh_ciphers[] =
{ .name = "aes256-gcm@openssh.com", .algo = "aes", .keylen = 256 / 8, .mode = cm_gcm },
{ .name = "blowfish128-cbc", .algo = "blowfish", .keylen = 128 / 8, .mode = cm_cbc },
{ .name = "blowfish128-ctr", .algo = "blowfish", .keylen = 128 / 8, .mode = cm_ctr },
/* The algo name doesn't matter, it's only used in pem-info */
/* The algo name doesn't matter, it's only used in latex-tables */
{ .name = "chacha20-poly1305@openssh.com", .algo = "c20p1305", .keylen = 256 / 8, .mode = cm_stream | cm_openssh },
{ .name = "des-cbc", .algo = "des", .keylen = 64 / 8, .mode = cm_cbc },
{ .name = "3des-cbc", .algo = "3des", .keylen = 192 / 8, .mode = cm_cbc },

View file

@ -206,6 +206,22 @@ static int s_name_match(const char *left, const char *right)
return 0;
}
int ecc_get_curve_names(const char *oid, const char * const **names)
{
unsigned long i;
LTC_ARGCHK(oid != NULL);
LTC_ARGCHK(names != NULL);
for (i = 0; s_curve_names[i].OID != NULL; ++i) {
if (XSTRCMP(s_curve_names[i].OID, oid) == 0) {
*names = s_curve_names[i].names;
return CRYPT_OK;
}
}
return CRYPT_INVALID_ARG; /* not found */
}
int ecc_find_curve(const char *name_or_oid, const ltc_ecc_curve **cu)
{
int i, j;