1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-10-19 02:29:40 +00:00

Expand coverage of different buffer sizes.

- When -z is used, include small buffers from 1 to 32 bytes to test
  stream ciphers.  Note that while AES-XTS claims to support a block
  size of 1 in OpenSSL, it does require a minimum of 1 block of cipher
  text as it is not a stream cipher but depends on CTS to pad out the
  final partial block.

- Permit multiple AAD sizes to be set via multiple -A options, or via
  -z.  When -z is set, use small buffers from 0 to 32 bytes followed
  by powers of 2 up to 256.  When multiple sizes are specified, the
  ETA and AEAD algorithms perform the full matrix of AAD sizes by
  payload sizes.

- Only warn on unchanged ciphertext instead of erroring.  The
  currently generated plaintext and key for a couple of AES-CTR tests
  with a buffer size of 1 results in ciphertext that matches the
  plaintext.

Reviewed by:	cem
Sponsored by:	Netflix
Differential Revision:	https://reviews.freebsd.org/D25006
This commit is contained in:
John Baldwin 2020-05-25 23:04:18 +00:00
parent 8c01c3dc46
commit 7d50aff082
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=361487

View File

@ -216,7 +216,8 @@ const struct alg {
static bool verbose; static bool verbose;
static int crid; static int crid;
static size_t aad_len; static size_t aad_sizes[48], sizes[128];
static u_int naad_sizes, nsizes;
static void static void
usage(void) usage(void)
@ -754,6 +755,20 @@ run_cipher_test(const struct alg *alg, size_t size)
return; return;
} }
/*
* XTS requires at least one full block so that any partial
* block at the end has cipher text to steal. Hardcoding the
* AES block size isn't ideal, but OpenSSL doesn't have a
* notion of a "native" block size.
*/
if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE &&
size < AES_BLOCK_LEN) {
if (verbose)
printf("%s (%zu): invalid buffer size\n", alg->name,
size);
return;
}
key_len = EVP_CIPHER_key_length(cipher); key_len = EVP_CIPHER_key_length(cipher);
iv_len = EVP_CIPHER_iv_length(cipher); iv_len = EVP_CIPHER_iv_length(cipher);
@ -766,7 +781,7 @@ run_cipher_test(const struct alg *alg, size_t size)
/* OpenSSL cipher. */ /* OpenSSL cipher. */
openssl_cipher(alg, cipher, key, iv, cleartext, ciphertext, size, 1); openssl_cipher(alg, cipher, key, iv, cleartext, ciphertext, size, 1);
if (size > 0 && memcmp(cleartext, ciphertext, size) == 0) if (size > 0 && memcmp(cleartext, ciphertext, size) == 0)
errx(1, "OpenSSL %s (%zu): cipher text unchanged", alg->name, warnx("OpenSSL %s (%zu): cipher text unchanged", alg->name,
size); size);
openssl_cipher(alg, cipher, key, iv, ciphertext, buffer, size, 0); openssl_cipher(alg, cipher, key, iv, ciphertext, buffer, size, 0);
if (memcmp(cleartext, buffer, size) != 0) { if (memcmp(cleartext, buffer, size) != 0) {
@ -877,7 +892,7 @@ ocf_eta(const struct ocf_session *ses, const struct alg *alg, const char *iv,
} }
static void static void
run_eta_test(const struct alg *alg, size_t size) run_eta_test(const struct alg *alg, size_t aad_len, size_t size)
{ {
struct ocf_session ses; struct ocf_session ses;
const EVP_CIPHER *cipher; const EVP_CIPHER *cipher;
@ -892,8 +907,18 @@ run_eta_test(const struct alg *alg, size_t size)
if (size % EVP_CIPHER_block_size(cipher) != 0) { if (size % EVP_CIPHER_block_size(cipher) != 0) {
if (verbose) if (verbose)
printf( printf(
"%s (%zu): invalid buffer size (block size %d)\n", "%s (%zu, %zu): invalid buffer size (block size %d)\n",
alg->name, size, EVP_CIPHER_block_size(cipher)); alg->name, aad_len, size,
EVP_CIPHER_block_size(cipher));
return;
}
/* See comment in run_cipher_test. */
if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE &&
size < AES_BLOCK_LEN) {
if (verbose)
printf("%s (%zu): invalid buffer size\n", alg->name,
size);
return; return;
} }
@ -920,13 +945,13 @@ run_eta_test(const struct alg *alg, size_t size)
ciphertext + aad_len, size, 1); ciphertext + aad_len, size, 1);
if (size > 0 && memcmp(cleartext + aad_len, ciphertext + aad_len, if (size > 0 && memcmp(cleartext + aad_len, ciphertext + aad_len,
size) == 0) size) == 0)
errx(1, "OpenSSL %s (%zu): cipher text unchanged", alg->name, warnx("OpenSSL %s (%zu, %zu): cipher text unchanged",
size); alg->name, aad_len, size);
digest_len = sizeof(control_digest); digest_len = sizeof(control_digest);
if (HMAC(md, auth_key, auth_key_len, (u_char *)ciphertext, if (HMAC(md, auth_key, auth_key_len, (u_char *)ciphertext,
aad_len + size, (u_char *)control_digest, &digest_len) == NULL) aad_len + size, (u_char *)control_digest, &digest_len) == NULL)
errx(1, "OpenSSL %s (%zu) HMAC failed: %s", alg->name, errx(1, "OpenSSL %s (%zu, %zu) HMAC failed: %s", alg->name,
size, ERR_error_string(ERR_get_error(), NULL)); aad_len, size, ERR_error_string(ERR_get_error(), NULL));
if (!ocf_init_eta_session(alg, cipher_key, cipher_key_len, auth_key, if (!ocf_init_eta_session(alg, cipher_key, cipher_key_len, auth_key,
auth_key_len, &ses)) auth_key_len, &ses))
@ -937,12 +962,13 @@ run_eta_test(const struct alg *alg, size_t size)
aad_len != 0 ? cleartext : NULL, aad_len, cleartext + aad_len, aad_len != 0 ? cleartext : NULL, aad_len, cleartext + aad_len,
buffer + aad_len, size, test_digest, COP_ENCRYPT); buffer + aad_len, size, test_digest, COP_ENCRYPT);
if (error != 0) { if (error != 0) {
warnc(error, "cryptodev %s (%zu) ETA failed for device %s", warnc(error, "cryptodev %s (%zu, %zu) ETA failed for device %s",
alg->name, size, crfind(ses.crid)); alg->name, aad_len, size, crfind(ses.crid));
goto out; goto out;
} }
if (memcmp(ciphertext + aad_len, buffer + aad_len, size) != 0) { if (memcmp(ciphertext + aad_len, buffer + aad_len, size) != 0) {
printf("%s (%zu) encryption mismatch:\n", alg->name, size); printf("%s (%zu, %zu) encryption mismatch:\n", alg->name,
aad_len, size);
printf("control:\n"); printf("control:\n");
hexdump(ciphertext + aad_len, size, NULL, 0); hexdump(ciphertext + aad_len, size, NULL, 0);
printf("test (cryptodev device %s):\n", crfind(ses.crid)); printf("test (cryptodev device %s):\n", crfind(ses.crid));
@ -951,11 +977,11 @@ run_eta_test(const struct alg *alg, size_t size)
} }
if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) { if (memcmp(control_digest, test_digest, sizeof(control_digest)) != 0) {
if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0) if (memcmp(control_digest, test_digest, EVP_MD_size(md)) == 0)
printf("%s (%zu) enc hash mismatch in trailer:\n", printf("%s (%zu, %zu) enc hash mismatch in trailer:\n",
alg->name, size); alg->name, aad_len, size);
else else
printf("%s (%zu) enc hash mismatch:\n", alg->name, printf("%s (%zu, %zu) enc hash mismatch:\n", alg->name,
size); aad_len, size);
printf("control:\n"); printf("control:\n");
hexdump(control_digest, sizeof(control_digest), NULL, 0); hexdump(control_digest, sizeof(control_digest), NULL, 0);
printf("test (cryptodev device %s):\n", crfind(ses.crid)); printf("test (cryptodev device %s):\n", crfind(ses.crid));
@ -968,12 +994,13 @@ run_eta_test(const struct alg *alg, size_t size)
aad_len != 0 ? ciphertext : NULL, aad_len, ciphertext + aad_len, aad_len != 0 ? ciphertext : NULL, aad_len, ciphertext + aad_len,
buffer + aad_len, size, test_digest, COP_DECRYPT); buffer + aad_len, size, test_digest, COP_DECRYPT);
if (error != 0) { if (error != 0) {
warnc(error, "cryptodev %s (%zu) ETA failed for device %s", warnc(error, "cryptodev %s (%zu, %zu) ETA failed for device %s",
alg->name, size, crfind(ses.crid)); alg->name, aad_len, size, crfind(ses.crid));
goto out; goto out;
} }
if (memcmp(cleartext + aad_len, buffer + aad_len, size) != 0) { if (memcmp(cleartext + aad_len, buffer + aad_len, size) != 0) {
printf("%s (%zu) decryption mismatch:\n", alg->name, size); printf("%s (%zu, %zu) decryption mismatch:\n", alg->name,
aad_len, size);
printf("control:\n"); printf("control:\n");
hexdump(cleartext, size, NULL, 0); hexdump(cleartext, size, NULL, 0);
printf("test (cryptodev device %s):\n", crfind(ses.crid)); printf("test (cryptodev device %s):\n", crfind(ses.crid));
@ -989,18 +1016,18 @@ run_eta_test(const struct alg *alg, size_t size)
if (error != EBADMSG) { if (error != EBADMSG) {
if (error != 0) if (error != 0)
warnc(error, warnc(error,
"cryptodev %s (%zu) corrupt tag failed for device %s", "cryptodev %s (%zu, %zu) corrupt tag failed for device %s",
alg->name, size, crfind(ses.crid)); alg->name, aad_len, size, crfind(ses.crid));
else else
warnx( warnx(
"cryptodev %s (%zu) corrupt tag didn't fail for device %s", "cryptodev %s (%zu, %zu) corrupt tag didn't fail for device %s",
alg->name, size, crfind(ses.crid)); alg->name, aad_len, size, crfind(ses.crid));
goto out; goto out;
} }
if (verbose) if (verbose)
printf("%s (%zu) matched (cryptodev device %s)\n", printf("%s (%zu, %zu) matched (cryptodev device %s)\n",
alg->name, size, crfind(ses.crid)); alg->name, aad_len, size, crfind(ses.crid));
out: out:
ocf_destroy_session(&ses); ocf_destroy_session(&ses);
@ -1303,7 +1330,7 @@ ocf_aead(const struct ocf_session *ses, const struct alg *alg, const char *iv,
#define AEAD_MAX_TAG_LEN MAX(AES_GMAC_HASH_LEN, AES_CBC_MAC_HASH_LEN) #define AEAD_MAX_TAG_LEN MAX(AES_GMAC_HASH_LEN, AES_CBC_MAC_HASH_LEN)
static void static void
run_aead_test(const struct alg *alg, size_t size) run_aead_test(const struct alg *alg, size_t aad_len, size_t size)
{ {
struct ocf_session ses; struct ocf_session ses;
const EVP_CIPHER *cipher; const EVP_CIPHER *cipher;
@ -1317,8 +1344,9 @@ run_aead_test(const struct alg *alg, size_t size)
if (size % EVP_CIPHER_block_size(cipher) != 0) { if (size % EVP_CIPHER_block_size(cipher) != 0) {
if (verbose) if (verbose)
printf( printf(
"%s (%zu): invalid buffer size (block size %d)\n", "%s (%zu, %zu): invalid buffer size (block size %d)\n",
alg->name, size, EVP_CIPHER_block_size(cipher)); alg->name, aad_len, size,
EVP_CIPHER_block_size(cipher));
return; return;
} }
@ -1366,12 +1394,13 @@ run_aead_test(const struct alg *alg, size_t size)
error = ocf_aead(&ses, alg, iv, iv_len, aad, aad_len, cleartext, buffer, error = ocf_aead(&ses, alg, iv, iv_len, aad, aad_len, cleartext, buffer,
size, test_tag, COP_ENCRYPT); size, test_tag, COP_ENCRYPT);
if (error != 0) { if (error != 0) {
warnc(error, "cryptodev %s (%zu) failed for device %s", warnc(error, "cryptodev %s (%zu, %zu) failed for device %s",
alg->name, size, crfind(ses.crid)); alg->name, aad_len, size, crfind(ses.crid));
goto out; goto out;
} }
if (memcmp(ciphertext, buffer, size) != 0) { if (memcmp(ciphertext, buffer, size) != 0) {
printf("%s (%zu) encryption mismatch:\n", alg->name, size); printf("%s (%zu, %zu) encryption mismatch:\n", alg->name,
aad_len, size);
printf("control:\n"); printf("control:\n");
hexdump(ciphertext, size, NULL, 0); hexdump(ciphertext, size, NULL, 0);
printf("test (cryptodev device %s):\n", crfind(crid)); printf("test (cryptodev device %s):\n", crfind(crid));
@ -1379,7 +1408,8 @@ run_aead_test(const struct alg *alg, size_t size)
goto out; goto out;
} }
if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) { if (memcmp(control_tag, test_tag, sizeof(control_tag)) != 0) {
printf("%s (%zu) enc tag mismatch:\n", alg->name, size); printf("%s (%zu, %zu) enc tag mismatch:\n", alg->name, aad_len,
size);
printf("control:\n"); printf("control:\n");
hexdump(control_tag, sizeof(control_tag), NULL, 0); hexdump(control_tag, sizeof(control_tag), NULL, 0);
printf("test (cryptodev device %s):\n", crfind(crid)); printf("test (cryptodev device %s):\n", crfind(crid));
@ -1391,12 +1421,13 @@ run_aead_test(const struct alg *alg, size_t size)
error = ocf_aead(&ses, alg, iv, iv_len, aad, aad_len, ciphertext, error = ocf_aead(&ses, alg, iv, iv_len, aad, aad_len, ciphertext,
buffer, size, control_tag, COP_DECRYPT); buffer, size, control_tag, COP_DECRYPT);
if (error != 0) { if (error != 0) {
warnc(error, "cryptodev %s (%zu) failed for device %s", warnc(error, "cryptodev %s (%zu, %zu) failed for device %s",
alg->name, size, crfind(ses.crid)); alg->name, aad_len, size, crfind(ses.crid));
goto out; goto out;
} }
if (memcmp(cleartext, buffer, size) != 0) { if (memcmp(cleartext, buffer, size) != 0) {
printf("%s (%zu) decryption mismatch:\n", alg->name, size); printf("%s (%zu, %zu) decryption mismatch:\n", alg->name,
aad_len, size);
printf("control:\n"); printf("control:\n");
hexdump(cleartext, size, NULL, 0); hexdump(cleartext, size, NULL, 0);
printf("test (cryptodev device %s):\n", crfind(crid)); printf("test (cryptodev device %s):\n", crfind(crid));
@ -1411,18 +1442,18 @@ run_aead_test(const struct alg *alg, size_t size)
if (error != EBADMSG) { if (error != EBADMSG) {
if (error != 0) if (error != 0)
warnc(error, warnc(error,
"cryptodev %s (%zu) corrupt tag failed for device %s", "cryptodev %s (%zu, %zu) corrupt tag failed for device %s",
alg->name, size, crfind(ses.crid)); alg->name, aad_len, size, crfind(ses.crid));
else else
warnx( warnx(
"cryptodev %s (%zu) corrupt tag didn't fail for device %s", "cryptodev %s (%zu, %zu) corrupt tag didn't fail for device %s",
alg->name, size, crfind(ses.crid)); alg->name, aad_len, size, crfind(ses.crid));
goto out; goto out;
} }
if (verbose) if (verbose)
printf("%s (%zu) matched (cryptodev device %s)\n", printf("%s (%zu, %zu) matched (cryptodev device %s)\n",
alg->name, size, crfind(ses.crid)); alg->name, aad_len, size, crfind(ses.crid));
out: out:
ocf_destroy_session(&ses); ocf_destroy_session(&ses);
@ -1435,7 +1466,7 @@ run_aead_test(const struct alg *alg, size_t size)
} }
static void static void
run_test(const struct alg *alg, size_t size) run_test(const struct alg *alg, size_t aad_len, size_t size)
{ {
switch (alg->type) { switch (alg->type) {
@ -1452,55 +1483,65 @@ run_test(const struct alg *alg, size_t size)
run_cipher_test(alg, size); run_cipher_test(alg, size);
break; break;
case T_ETA: case T_ETA:
run_eta_test(alg, size); run_eta_test(alg, aad_len, size);
break; break;
case T_AEAD: case T_AEAD:
run_aead_test(alg, size); run_aead_test(alg, aad_len, size);
break; break;
} }
} }
static void static void
run_test_sizes(const struct alg *alg, size_t *sizes, u_int nsizes) run_test_sizes(const struct alg *alg)
{ {
u_int i; u_int i, j;
for (i = 0; i < nsizes; i++) switch (alg->type) {
run_test(alg, sizes[i]); default:
for (i = 0; i < nsizes; i++)
run_test(alg, 0, sizes[i]);
break;
case T_ETA:
case T_AEAD:
for (i = 0; i < naad_sizes; i++)
for (j = 0; j < nsizes; j++)
run_test(alg, aad_sizes[i], sizes[j]);
break;
}
} }
static void static void
run_hash_tests(size_t *sizes, u_int nsizes) run_hash_tests(void)
{ {
u_int i; u_int i;
for (i = 0; i < nitems(algs); i++) for (i = 0; i < nitems(algs); i++)
if (algs[i].type == T_HASH) if (algs[i].type == T_HASH)
run_test_sizes(&algs[i], sizes, nsizes); run_test_sizes(&algs[i]);
} }
static void static void
run_mac_tests(size_t *sizes, u_int nsizes) run_mac_tests(void)
{ {
u_int i; u_int i;
for (i = 0; i < nitems(algs); i++) for (i = 0; i < nitems(algs); i++)
if (algs[i].type == T_HMAC || algs[i].type == T_GMAC) if (algs[i].type == T_HMAC || algs[i].type == T_GMAC)
run_test_sizes(&algs[i], sizes, nsizes); run_test_sizes(&algs[i]);
} }
static void static void
run_cipher_tests(size_t *sizes, u_int nsizes) run_cipher_tests(void)
{ {
u_int i; u_int i;
for (i = 0; i < nitems(algs); i++) for (i = 0; i < nitems(algs); i++)
if (algs[i].type == T_CIPHER) if (algs[i].type == T_CIPHER)
run_test_sizes(&algs[i], sizes, nsizes); run_test_sizes(&algs[i]);
} }
static void static void
run_eta_tests(size_t *sizes, u_int nsizes) run_eta_tests(void)
{ {
const struct alg *cipher, *mac; const struct alg *cipher, *mac;
struct alg *eta; struct alg *eta;
@ -1515,20 +1556,20 @@ run_eta_tests(size_t *sizes, u_int nsizes)
if (mac->type != T_HMAC) if (mac->type != T_HMAC)
continue; continue;
eta = build_eta(cipher, mac); eta = build_eta(cipher, mac);
run_test_sizes(eta, sizes, nsizes); run_test_sizes(eta);
free_eta(eta); free_eta(eta);
} }
} }
} }
static void static void
run_aead_tests(size_t *sizes, u_int nsizes) run_aead_tests(void)
{ {
u_int i; u_int i;
for (i = 0; i < nitems(algs); i++) for (i = 0; i < nitems(algs); i++)
if (algs[i].type == T_AEAD) if (algs[i].type == T_AEAD)
run_test_sizes(&algs[i], sizes, nsizes); run_test_sizes(&algs[i]);
} }
int int
@ -1537,8 +1578,9 @@ main(int ac, char **av)
const char *algname; const char *algname;
const struct alg *alg; const struct alg *alg;
struct alg *eta; struct alg *eta;
size_t sizes[128]; char *cp;
u_int i, nsizes; size_t base_size;
u_int i;
bool testall; bool testall;
int ch; int ch;
@ -1549,7 +1591,14 @@ main(int ac, char **av)
while ((ch = getopt(ac, av, "A:a:d:vz")) != -1) while ((ch = getopt(ac, av, "A:a:d:vz")) != -1)
switch (ch) { switch (ch) {
case 'A': case 'A':
aad_len = atoi(optarg); if (naad_sizes >= nitems(aad_sizes)) {
warnx("Too many AAD sizes, ignoring extras");
break;
}
aad_sizes[naad_sizes] = strtol(optarg, &cp, 0);
if (*cp != '\0')
errx(1, "Bad AAD size %s", optarg);
naad_sizes++;
break; break;
case 'a': case 'a':
algname = optarg; algname = optarg;
@ -1570,8 +1619,6 @@ main(int ac, char **av)
av += optind; av += optind;
nsizes = 0; nsizes = 0;
while (ac > 0) { while (ac > 0) {
char *cp;
if (nsizes >= nitems(sizes)) { if (nsizes >= nitems(sizes)) {
warnx("Too many sizes, ignoring extras"); warnx("Too many sizes, ignoring extras");
break; break;
@ -1586,48 +1633,78 @@ main(int ac, char **av)
if (algname == NULL) if (algname == NULL)
errx(1, "Algorithm required"); errx(1, "Algorithm required");
if (nsizes == 0) {
sizes[0] = 16; if (naad_sizes == 0) {
nsizes++;
if (testall) { if (testall) {
while (sizes[nsizes - 1] * 2 < 240 * 1024) { for (i = 0; i <= 32; i++) {
assert(nsizes < nitems(sizes)); aad_sizes[naad_sizes] = i;
sizes[nsizes] = sizes[nsizes - 1] * 2; naad_sizes++;
}
base_size = 32;
while (base_size * 2 < 512) {
base_size *= 2;
assert(naad_sizes < nitems(aad_sizes));
aad_sizes[naad_sizes] = base_size;
naad_sizes++;
}
} else {
aad_sizes[0] = 0;
naad_sizes = 1;
}
}
if (nsizes == 0) {
if (testall) {
for (i = 1; i <= 32; i++) {
sizes[nsizes] = i;
nsizes++; nsizes++;
} }
base_size = 32;
while (base_size * 2 < 240 * 1024) {
base_size *= 2;
assert(nsizes < nitems(sizes));
sizes[nsizes] = base_size;
nsizes++;
}
if (sizes[nsizes - 1] < 240 * 1024) { if (sizes[nsizes - 1] < 240 * 1024) {
assert(nsizes < nitems(sizes)); assert(nsizes < nitems(sizes));
sizes[nsizes] = 240 * 1024; sizes[nsizes] = 240 * 1024;
nsizes++; nsizes++;
} }
} else {
sizes[0] = 16;
nsizes = 1;
} }
} }
if (strcasecmp(algname, "hash") == 0) if (strcasecmp(algname, "hash") == 0)
run_hash_tests(sizes, nsizes); run_hash_tests();
else if (strcasecmp(algname, "mac") == 0) else if (strcasecmp(algname, "mac") == 0)
run_mac_tests(sizes, nsizes); run_mac_tests();
else if (strcasecmp(algname, "cipher") == 0) else if (strcasecmp(algname, "cipher") == 0)
run_cipher_tests(sizes, nsizes); run_cipher_tests();
else if (strcasecmp(algname, "eta") == 0) else if (strcasecmp(algname, "eta") == 0)
run_eta_tests(sizes, nsizes); run_eta_tests();
else if (strcasecmp(algname, "aead") == 0) else if (strcasecmp(algname, "aead") == 0)
run_aead_tests(sizes, nsizes); run_aead_tests();
else if (strcasecmp(algname, "all") == 0) { else if (strcasecmp(algname, "all") == 0) {
run_hash_tests(sizes, nsizes); run_hash_tests();
run_mac_tests(sizes, nsizes); run_mac_tests();
run_cipher_tests(sizes, nsizes); run_cipher_tests();
run_eta_tests(sizes, nsizes); run_eta_tests();
run_aead_tests(sizes, nsizes); run_aead_tests();
} else if (strchr(algname, '+') != NULL) { } else if (strchr(algname, '+') != NULL) {
eta = build_eta_name(algname); eta = build_eta_name(algname);
run_test_sizes(eta, sizes, nsizes); run_test_sizes(eta);
free_eta(eta); free_eta(eta);
} else { } else {
alg = find_alg(algname); alg = find_alg(algname);
if (alg == NULL) if (alg == NULL)
errx(1, "Invalid algorithm %s", algname); errx(1, "Invalid algorithm %s", algname);
run_test_sizes(alg, sizes, nsizes); run_test_sizes(alg);
} }
return (0); return (0);