libgcrypt/libgcrypt-1.9.3-fips-tests.patch

1805 lines
49 KiB
Diff

commit 57cf83834bc00a7431378aabda692bf700e4876c
Author: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Date: Sat Apr 17 17:06:40 2021 +0300
tests/bench-slope: add ECC benchmarking
* tests/bench-slope.c (bench_print_result_nsec_per_iteration): New.
(bench_print_header_nsec_per_iteration): New.
(kdf_bench_one, kdf_bench): Use new print helper functions.
[USE_ECC]: New ECC benchmarks.
(ecc_bench): New.
(print_help): Add 'ecc' option.
(main): Add ECC benchmarks.
--
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
diff --git a/tests/bench-slope.c b/tests/bench-slope.c
index c8647b6b..9b4a139a 100644
--- a/tests/bench-slope.c
+++ b/tests/bench-slope.c
@@ -783,6 +783,54 @@ bench_print_result (double nsecs_per_byte)
bench_print_result_std (nsecs_per_byte);
}
+static void
+bench_print_result_nsec_per_iteration (double nsecs_per_iteration)
+{
+ double cycles_per_iteration;
+ char nsecpiter_buf[16];
+ char cpiter_buf[16];
+ char mhz_buf[16];
+
+ strcpy(cpiter_buf, csv_mode ? "" : "-");
+ strcpy(mhz_buf, csv_mode ? "" : "-");
+
+ double_to_str (nsecpiter_buf, sizeof (nsecpiter_buf), nsecs_per_iteration);
+
+ /* If user didn't provide CPU speed, we cannot show cycles/iter results. */
+ if (bench_ghz > 0.0)
+ {
+ cycles_per_iteration = nsecs_per_iteration * bench_ghz;
+ double_to_str (cpiter_buf, sizeof (cpiter_buf), cycles_per_iteration);
+ double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000);
+ }
+
+ if (csv_mode)
+ {
+ if (auto_ghz)
+ printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter,%s,Mhz\n",
+ current_section_name,
+ current_algo_name ? current_algo_name : "",
+ current_mode_name ? current_mode_name : "",
+ nsecpiter_buf,
+ cpiter_buf,
+ mhz_buf);
+ else
+ printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n",
+ current_section_name,
+ current_algo_name ? current_algo_name : "",
+ current_mode_name ? current_mode_name : "",
+ nsecpiter_buf,
+ cpiter_buf);
+ }
+ else
+ {
+ if (auto_ghz)
+ printf ("%14s %13s %9s\n", nsecpiter_buf, cpiter_buf, mhz_buf);
+ else
+ printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf);
+ }
+}
+
static void
bench_print_section (const char *section_name, const char *print_name)
{
@@ -819,6 +867,28 @@ bench_print_header (int algo_width, const char *algo_name)
}
}
+static void
+bench_print_header_nsec_per_iteration (int algo_width, const char *algo_name)
+{
+ if (csv_mode)
+ {
+ gcry_free (current_algo_name);
+ current_algo_name = gcry_xstrdup (algo_name);
+ }
+ else
+ {
+ if (algo_width < 0)
+ printf (" %-*s | ", -algo_width, algo_name);
+ else
+ printf (" %-*s | ", algo_width, algo_name);
+
+ if (auto_ghz)
+ printf ("%14s %13s %9s\n", "nanosecs/iter", "cycles/iter", "auto Mhz");
+ else
+ printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter");
+ }
+}
+
static void
bench_print_algo (int algo_width, const char *algo_name)
{
@@ -1991,11 +2061,7 @@ kdf_bench_one (int algo, int subalgo)
struct bench_kdf_mode mode = { &kdf_ops };
struct bench_obj obj = { 0 };
double nsecs_per_iteration;
- double cycles_per_iteration;
char algo_name[32];
- char nsecpiter_buf[16];
- char cpiter_buf[16];
- char mhz_buf[16];
mode.algo = algo;
mode.subalgo = subalgo;
@@ -2030,45 +2096,7 @@ kdf_bench_one (int algo, int subalgo)
obj.priv = &mode;
nsecs_per_iteration = do_slope_benchmark (&obj);
-
- strcpy(cpiter_buf, csv_mode ? "" : "-");
- strcpy(mhz_buf, csv_mode ? "" : "-");
-
- double_to_str (nsecpiter_buf, sizeof (nsecpiter_buf), nsecs_per_iteration);
-
- /* If user didn't provide CPU speed, we cannot show cycles/iter results. */
- if (bench_ghz > 0.0)
- {
- cycles_per_iteration = nsecs_per_iteration * bench_ghz;
- double_to_str (cpiter_buf, sizeof (cpiter_buf), cycles_per_iteration);
- double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000);
- }
-
- if (csv_mode)
- {
- if (auto_ghz)
- printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter,%s,Mhz\n",
- current_section_name,
- current_algo_name ? current_algo_name : "",
- current_mode_name ? current_mode_name : "",
- nsecpiter_buf,
- cpiter_buf,
- mhz_buf);
- else
- printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n",
- current_section_name,
- current_algo_name ? current_algo_name : "",
- current_mode_name ? current_mode_name : "",
- nsecpiter_buf,
- cpiter_buf);
- }
- else
- {
- if (auto_ghz)
- printf ("%14s %13s %9s\n", nsecpiter_buf, cpiter_buf, mhz_buf);
- else
- printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf);
- }
+ bench_print_result_nsec_per_iteration (nsecs_per_iteration);
}
void
@@ -2079,14 +2107,7 @@ kdf_bench (char **argv, int argc)
bench_print_section ("kdf", "KDF");
- if (!csv_mode)
- {
- printf (" %-*s | ", 24, "");
- if (auto_ghz)
- printf ("%14s %13s %9s\n", "nanosecs/iter", "cycles/iter", "auto Mhz");
- else
- printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter");
- }
+ bench_print_header_nsec_per_iteration (24, "");
if (argv && argc)
{
@@ -2116,13 +2137,571 @@ kdf_bench (char **argv, int argc)
}
+/************************************************************ ECC benchmarks. */
+
+#if USE_ECC
+enum bench_ecc_algo
+{
+ ECC_ALGO_ED25519 = 0,
+ ECC_ALGO_ED448,
+ ECC_ALGO_NIST_P192,
+ ECC_ALGO_NIST_P224,
+ ECC_ALGO_NIST_P256,
+ ECC_ALGO_NIST_P384,
+ ECC_ALGO_NIST_P521,
+ ECC_ALGO_SECP256K1,
+ __MAX_ECC_ALGO
+};
+
+enum bench_ecc_operation
+{
+ ECC_OPER_MULT = 0,
+ ECC_OPER_KEYGEN,
+ ECC_OPER_SIGN,
+ ECC_OPER_VERIFY,
+ __MAX_ECC_OPER
+};
+
+struct bench_ecc_oper
+{
+ enum bench_ecc_operation oper;
+ const char *name;
+ struct bench_ops *ops;
+
+ enum bench_ecc_algo algo;
+};
+
+struct bench_ecc_mult_hd
+{
+ gcry_ctx_t ec;
+ gcry_mpi_t k, x, y;
+ gcry_mpi_point_t G, Q;
+};
+
+struct bench_ecc_hd
+{
+ gcry_sexp_t key_spec;
+ gcry_sexp_t data;
+ gcry_sexp_t pub_key;
+ gcry_sexp_t sec_key;
+ gcry_sexp_t sig;
+};
+
+
+static const char *
+ecc_algo_name (int algo)
+{
+ switch (algo)
+ {
+ case ECC_ALGO_ED25519:
+ return "Ed25519";
+ case ECC_ALGO_ED448:
+ return "Ed448";
+ case ECC_ALGO_NIST_P192:
+ return "NIST-P192";
+ case ECC_ALGO_NIST_P224:
+ return "NIST-P224";
+ case ECC_ALGO_NIST_P256:
+ return "NIST-P256";
+ case ECC_ALGO_NIST_P384:
+ return "NIST-P384";
+ case ECC_ALGO_NIST_P521:
+ return "NIST-P521";
+ case ECC_ALGO_SECP256K1:
+ return "secp256k1";
+ default:
+ return NULL;
+ }
+}
+
+static const char *
+ecc_algo_curve (int algo)
+{
+ switch (algo)
+ {
+ case ECC_ALGO_ED25519:
+ return "Ed25519";
+ case ECC_ALGO_ED448:
+ return "Ed448";
+ case ECC_ALGO_NIST_P192:
+ return "NIST P-192";
+ case ECC_ALGO_NIST_P224:
+ return "NIST P-224";
+ case ECC_ALGO_NIST_P256:
+ return "NIST P-256";
+ case ECC_ALGO_NIST_P384:
+ return "NIST P-384";
+ case ECC_ALGO_NIST_P521:
+ return "NIST P-521";
+ case ECC_ALGO_SECP256K1:
+ return "secp256k1";
+ default:
+ return NULL;
+ }
+}
+
+static int
+ecc_nbits (int algo)
+{
+ switch (algo)
+ {
+ case ECC_ALGO_ED25519:
+ return 255;
+ case ECC_ALGO_ED448:
+ return 448;
+ case ECC_ALGO_NIST_P192:
+ return 192;
+ case ECC_ALGO_NIST_P224:
+ return 224;
+ case ECC_ALGO_NIST_P256:
+ return 256;
+ case ECC_ALGO_NIST_P384:
+ return 384;
+ case ECC_ALGO_NIST_P521:
+ return 521;
+ case ECC_ALGO_SECP256K1:
+ return 256;
+ default:
+ return 0;
+ }
+}
+
+static int
+ecc_map_name (const char *name)
+{
+ int i;
+
+ for (i = 0; i < __MAX_ECC_ALGO; i++)
+ {
+ if (strcmp(ecc_algo_name(i), name) == 0)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+
+static int
+bench_ecc_mult_init (struct bench_obj *obj)
+{
+ struct bench_ecc_oper *oper = obj->priv;
+ struct bench_ecc_mult_hd *hd;
+ int p_size = ecc_nbits (oper->algo);
+ gpg_error_t err;
+ gcry_mpi_t p;
+
+ obj->min_bufsize = 1;
+ obj->max_bufsize = 4;
+ obj->step_size = 1;
+ obj->num_measure_repetitions =
+ num_measurement_repetitions / obj->max_bufsize;
+
+ while (obj->num_measure_repetitions == 0)
+ {
+ if (obj->max_bufsize == 2)
+ {
+ obj->num_measure_repetitions = 2;
+ }
+ else
+ {
+ obj->max_bufsize--;
+ obj->num_measure_repetitions =
+ num_measurement_repetitions / obj->max_bufsize;
+ }
+ }
+
+ hd = calloc (1, sizeof(*hd));
+ if (!hd)
+ return -1;
+
+ err = gcry_mpi_ec_new (&hd->ec, NULL, ecc_algo_curve(oper->algo));
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_mpi_ec_new failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ hd->G = gcry_mpi_ec_get_point ("g", hd->ec, 1);
+ hd->Q = gcry_mpi_point_new (0);
+ hd->x = gcry_mpi_new (0);
+ hd->y = gcry_mpi_new (0);
+ hd->k = gcry_mpi_new (p_size);
+ gcry_mpi_randomize (hd->k, p_size, GCRY_WEAK_RANDOM);
+ p = gcry_mpi_ec_get_mpi ("p", hd->ec, 1);
+ gcry_mpi_mod (hd->k, hd->k, p);
+ gcry_mpi_release (p);
+
+ obj->hd = hd;
+ return 0;
+}
+
+static void
+bench_ecc_mult_free (struct bench_obj *obj)
+{
+ struct bench_ecc_mult_hd *hd = obj->hd;
+
+ gcry_mpi_release (hd->k);
+ gcry_mpi_release (hd->y);
+ gcry_mpi_release (hd->x);
+ gcry_mpi_point_release (hd->Q);
+ gcry_mpi_point_release (hd->G);
+ gcry_ctx_release (hd->ec);
+ free (hd);
+ obj->hd = NULL;
+}
+
+static void
+bench_ecc_mult_do_bench (struct bench_obj *obj, void *buf, size_t num_iter)
+{
+ struct bench_ecc_mult_hd *hd = obj->hd;
+ size_t i;
+
+ (void)buf;
+
+ for (i = 0; i < num_iter; i++)
+ {
+ gcry_mpi_ec_mul (hd->Q, hd->k, hd->G, hd->ec);
+ if (gcry_mpi_ec_get_affine (hd->x, hd->y, hd->Q, hd->ec))
+ {
+ fprintf (stderr, PGM ": gcry_mpi_ec_get_affine failed\n");
+ exit (1);
+ }
+ }
+}
+
+
+static int
+bench_ecc_init (struct bench_obj *obj)
+{
+ struct bench_ecc_oper *oper = obj->priv;
+ struct bench_ecc_hd *hd;
+ int p_size = ecc_nbits (oper->algo);
+ gpg_error_t err;
+ gcry_mpi_t x;
+
+ obj->min_bufsize = 1;
+ obj->max_bufsize = 4;
+ obj->step_size = 1;
+ obj->num_measure_repetitions =
+ num_measurement_repetitions / obj->max_bufsize;
+
+ while (obj->num_measure_repetitions == 0)
+ {
+ if (obj->max_bufsize == 2)
+ {
+ obj->num_measure_repetitions = 2;
+ }
+ else
+ {
+ obj->max_bufsize--;
+ obj->num_measure_repetitions =
+ num_measurement_repetitions / obj->max_bufsize;
+ }
+ }
+
+ hd = calloc (1, sizeof(*hd));
+ if (!hd)
+ return -1;
+
+ x = gcry_mpi_new (p_size);
+ gcry_mpi_randomize (x, p_size, GCRY_WEAK_RANDOM);
+
+ switch (oper->algo)
+ {
+ default:
+ return -1;
+
+ case ECC_ALGO_ED25519:
+ err = gcry_sexp_build (&hd->key_spec, NULL,
+ "(genkey (ecdsa (curve \"Ed25519\")"
+ "(flags eddsa)))");
+ if (err)
+ break;
+ err = gcry_sexp_build (&hd->data, NULL,
+ "(data (flags eddsa)(hash-algo sha512)"
+ " (value %m))", x);
+ break;
+
+ case ECC_ALGO_ED448:
+ err = gcry_sexp_build (&hd->key_spec, NULL,
+ "(genkey (ecdsa (curve \"Ed448\")"
+ "(flags eddsa)))");
+ if (err)
+ break;
+ err = gcry_sexp_build (&hd->data, NULL,
+ "(data (flags eddsa)(hash-algo shake256)"
+ " (value %m))", x);
+ break;
+
+ case ECC_ALGO_NIST_P192:
+ case ECC_ALGO_NIST_P224:
+ case ECC_ALGO_NIST_P256:
+ case ECC_ALGO_NIST_P384:
+ case ECC_ALGO_NIST_P521:
+ err = gcry_sexp_build (&hd->key_spec, NULL,
+ "(genkey (ECDSA (nbits %d)))", p_size);
+ if (err)
+ break;
+ err = gcry_sexp_build (&hd->data, NULL,
+ "(data (flags raw) (value %m))", x);
+ break;
+ }
+
+ gcry_mpi_release (x);
+
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_sexp_build failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+
+ obj->hd = hd;
+ return 0;
+}
+
+static void
+bench_ecc_free (struct bench_obj *obj)
+{
+ struct bench_ecc_hd *hd = obj->hd;
+
+ gcry_sexp_release (hd->sig);
+ gcry_sexp_release (hd->pub_key);
+ gcry_sexp_release (hd->sec_key);
+ gcry_sexp_release (hd->data);
+ gcry_sexp_release (hd->key_spec);
+ free (hd);
+ obj->hd = NULL;
+}
+
+static void
+bench_ecc_keygen (struct bench_ecc_hd *hd)
+{
+ gcry_sexp_t key_pair;
+ gpg_error_t err;
+
+ err = gcry_pk_genkey (&key_pair, hd->key_spec);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_pk_genkey failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+
+ hd->pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
+ if (!hd->pub_key)
+ {
+ fprintf (stderr, PGM ": public part missing in key\n");
+ exit (1);
+ }
+ hd->sec_key = gcry_sexp_find_token (key_pair, "private-key", 0);
+ if (!hd->sec_key)
+ {
+ fprintf (stderr, PGM ": private part missing in key\n");
+ exit (1);
+ }
+
+ gcry_sexp_release (key_pair);
+}
+
+static void
+bench_ecc_keygen_do_bench (struct bench_obj *obj, void *buf, size_t num_iter)
+{
+ struct bench_ecc_hd *hd = obj->hd;
+ size_t i;
+
+ (void)buf;
+
+ for (i = 0; i < num_iter; i++)
+ {
+ bench_ecc_keygen (hd);
+ gcry_sexp_release (hd->pub_key);
+ gcry_sexp_release (hd->sec_key);
+ }
+
+ hd->pub_key = NULL;
+ hd->sec_key = NULL;
+}
+
+static void
+bench_ecc_sign_do_bench (struct bench_obj *obj, void *buf, size_t num_iter)
+{
+ struct bench_ecc_hd *hd = obj->hd;
+ gpg_error_t err;
+ size_t i;
+
+ (void)buf;
+
+ bench_ecc_keygen (hd);
+
+ for (i = 0; i < num_iter; i++)
+ {
+ err = gcry_pk_sign (&hd->sig, hd->data, hd->sec_key);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_pk_sign failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ gcry_sexp_release (hd->sig);
+ }
+
+ gcry_sexp_release (hd->pub_key);
+ gcry_sexp_release (hd->sec_key);
+ hd->sig = NULL;
+ hd->pub_key = NULL;
+ hd->sec_key = NULL;
+}
+
+static void
+bench_ecc_verify_do_bench (struct bench_obj *obj, void *buf, size_t num_iter)
+{
+ struct bench_ecc_hd *hd = obj->hd;
+ gpg_error_t err;
+ int i;
+
+ (void)buf;
+
+ bench_ecc_keygen (hd);
+ err = gcry_pk_sign (&hd->sig, hd->data, hd->sec_key);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_pk_sign failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+
+ for (i = 0; i < num_iter; i++)
+ {
+ err = gcry_pk_verify (hd->sig, hd->data, hd->pub_key);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gcry_pk_verify failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ }
+
+ gcry_sexp_release (hd->sig);
+ gcry_sexp_release (hd->pub_key);
+ gcry_sexp_release (hd->sec_key);
+ hd->sig = NULL;
+ hd->pub_key = NULL;
+ hd->sec_key = NULL;
+}
+
+
+static struct bench_ops ecc_mult_ops = {
+ &bench_ecc_mult_init,
+ &bench_ecc_mult_free,
+ &bench_ecc_mult_do_bench
+};
+
+static struct bench_ops ecc_keygen_ops = {
+ &bench_ecc_init,
+ &bench_ecc_free,
+ &bench_ecc_keygen_do_bench
+};
+
+static struct bench_ops ecc_sign_ops = {
+ &bench_ecc_init,
+ &bench_ecc_free,
+ &bench_ecc_sign_do_bench
+};
+
+static struct bench_ops ecc_verify_ops = {
+ &bench_ecc_init,
+ &bench_ecc_free,
+ &bench_ecc_verify_do_bench
+};
+
+
+static struct bench_ecc_oper ecc_operations[] = {
+ { ECC_OPER_MULT, "mult", &ecc_mult_ops },
+ { ECC_OPER_KEYGEN, "keygen", &ecc_keygen_ops },
+ { ECC_OPER_SIGN, "sign", &ecc_sign_ops },
+ { ECC_OPER_VERIFY, "verify", &ecc_verify_ops },
+ { 0, NULL, NULL }
+};
+
+
+static void
+cipher_ecc_one (enum bench_ecc_algo algo, struct bench_ecc_oper *poper)
+{
+ struct bench_ecc_oper oper = *poper;
+ struct bench_obj obj = { 0 };
+ double result;
+
+ if (algo == ECC_ALGO_SECP256K1 && oper.oper != ECC_OPER_MULT)
+ return;
+
+ oper.algo = algo;
+
+ bench_print_mode (14, oper.name);
+
+ obj.ops = oper.ops;
+ obj.priv = &oper;
+
+ result = do_slope_benchmark (&obj);
+ bench_print_result_nsec_per_iteration (result);
+}
+
+
+static void
+_ecc_bench (int algo)
+{
+ const char *algo_name;
+ int i;
+
+ algo_name = ecc_algo_name (algo);
+
+ bench_print_header_nsec_per_iteration (14, algo_name);
+
+ for (i = 0; ecc_operations[i].name; i++)
+ cipher_ecc_one (algo, &ecc_operations[i]);
+
+ bench_print_footer (14);
+}
+#endif
+
+
+void
+ecc_bench (char **argv, int argc)
+{
+#if USE_ECC
+ int i, algo;
+
+ bench_print_section ("ecc", "ECC");
+
+ if (argv && argc)
+ {
+ for (i = 0; i < argc; i++)
+ {
+ algo = ecc_map_name (argv[i]);
+ if (algo >= 0)
+ _ecc_bench (algo);
+ }
+ }
+ else
+ {
+ for (i = 0; i < __MAX_ECC_ALGO; i++)
+ _ecc_bench (i);
+ }
+#else
+ (void)argv;
+ (void)argc;
+#endif
+}
+
/************************************************************** Main program. */
void
print_help (void)
{
static const char *help_lines[] = {
- "usage: bench-slope [options] [hash|mac|cipher|kdf [algonames]]",
+ "usage: bench-slope [options] [hash|mac|cipher|kdf|ecc [algonames]]",
"",
" options:",
" --cpu-mhz <mhz> Set CPU speed for calculating cycles",
@@ -2304,6 +2883,7 @@ main (int argc, char **argv)
mac_bench (NULL, 0);
cipher_bench (NULL, 0);
kdf_bench (NULL, 0);
+ ecc_bench (NULL, 0);
}
else if (!strcmp (*argv, "hash"))
{
@@ -2337,6 +2917,14 @@ main (int argc, char **argv)
warm_up_cpu ();
kdf_bench ((argc == 0) ? NULL : argv, argc);
}
+ else if (!strcmp (*argv, "ecc"))
+ {
+ argc--;
+ argv++;
+
+ warm_up_cpu ();
+ ecc_bench ((argc == 0) ? NULL : argv, argc);
+ }
else
{
fprintf (stderr, PGM ": unknown argument: %s\n", *argv);
commit 9911069388e762d2a85bc2a11ca6cfcc4c895e4f
Author: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Date: Wed Jun 16 20:27:01 2021 +0300
bench-slope: add X25519 and X448 scalar multiplication
* tests/bench-slope.c (ECC_ALGO_X25519, ECC_ALGO_X448): New.
(ecc_algo_name, ecc_algo_curve, ecc_nbits): Add X25519 and X448.
(bench_ecc_mult_do_bench): Pass Y as NULL to ec_get_affine with
X25519 and X448.
(cipher_ecc_one): Run only multiplication bench for X25519 and X448.
--
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
diff --git a/tests/bench-slope.c b/tests/bench-slope.c
index 9b4a139a..35272094 100644
--- a/tests/bench-slope.c
+++ b/tests/bench-slope.c
@@ -2144,6 +2144,8 @@ enum bench_ecc_algo
{
ECC_ALGO_ED25519 = 0,
ECC_ALGO_ED448,
+ ECC_ALGO_X25519,
+ ECC_ALGO_X448,
ECC_ALGO_NIST_P192,
ECC_ALGO_NIST_P224,
ECC_ALGO_NIST_P256,
@@ -2197,6 +2199,10 @@ ecc_algo_name (int algo)
return "Ed25519";
case ECC_ALGO_ED448:
return "Ed448";
+ case ECC_ALGO_X25519:
+ return "X25519";
+ case ECC_ALGO_X448:
+ return "X448";
case ECC_ALGO_NIST_P192:
return "NIST-P192";
case ECC_ALGO_NIST_P224:
@@ -2223,6 +2229,10 @@ ecc_algo_curve (int algo)
return "Ed25519";
case ECC_ALGO_ED448:
return "Ed448";
+ case ECC_ALGO_X25519:
+ return "Curve25519";
+ case ECC_ALGO_X448:
+ return "X448";
case ECC_ALGO_NIST_P192:
return "NIST P-192";
case ECC_ALGO_NIST_P224:
@@ -2249,6 +2259,10 @@ ecc_nbits (int algo)
return 255;
case ECC_ALGO_ED448:
return 448;
+ case ECC_ALGO_X25519:
+ return 255;
+ case ECC_ALGO_X448:
+ return 448;
case ECC_ALGO_NIST_P192:
return 192;
case ECC_ALGO_NIST_P224:
@@ -2355,15 +2369,26 @@ bench_ecc_mult_free (struct bench_obj *obj)
static void
bench_ecc_mult_do_bench (struct bench_obj *obj, void *buf, size_t num_iter)
{
+ struct bench_ecc_oper *oper = obj->priv;
struct bench_ecc_mult_hd *hd = obj->hd;
+ gcry_mpi_t y;
size_t i;
(void)buf;
+ if (oper->algo == ECC_ALGO_X25519 || oper->algo == ECC_ALGO_X448)
+ {
+ y = NULL;
+ }
+ else
+ {
+ y = hd->y;
+ }
+
for (i = 0; i < num_iter; i++)
{
gcry_mpi_ec_mul (hd->Q, hd->k, hd->G, hd->ec);
- if (gcry_mpi_ec_get_affine (hd->x, hd->y, hd->Q, hd->ec))
+ if (gcry_mpi_ec_get_affine (hd->x, y, hd->Q, hd->ec))
{
fprintf (stderr, PGM ": gcry_mpi_ec_get_affine failed\n");
exit (1);
@@ -2634,7 +2659,8 @@ cipher_ecc_one (enum bench_ecc_algo algo, struct bench_ecc_oper *poper)
struct bench_obj obj = { 0 };
double result;
- if (algo == ECC_ALGO_SECP256K1 && oper.oper != ECC_OPER_MULT)
+ if ((algo == ECC_ALGO_X25519 || algo == ECC_ALGO_X448 ||
+ algo == ECC_ALGO_SECP256K1) && oper.oper != ECC_OPER_MULT)
return;
oper.algo = algo;
From bd49a4fa915b8a078c341b35f5a51fcb2a004c35 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Mon, 12 Jul 2021 21:35:18 +0200
Subject: [PATCH 1/8] mac: Disable AES GMAC in FIPS mode
* cipher/mac-gmac.c (_gcry_mac_type_spec_gmac_aes): Remove FIPS flag
--
The GMAC does not work in FIPS mode until libgcrypt will have internal
IV generator.
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
---
cipher/mac-gmac.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cipher/mac-gmac.c b/cipher/mac-gmac.c
index e04c6d1e..1d59d085 100644
--- a/cipher/mac-gmac.c
+++ b/cipher/mac-gmac.c
@@ -157,7 +157,7 @@ static gcry_mac_spec_ops_t gmac_ops = {
#if USE_AES
gcry_mac_spec_t _gcry_mac_type_spec_gmac_aes = {
- GCRY_MAC_GMAC_AES, {0, 1}, "GMAC_AES",
+ GCRY_MAC_GMAC_AES, {0, 0}, "GMAC_AES",
&gmac_ops
};
#endif
--
2.31.1
From fd0e1c3e7f6062579869d345875d6ef823706e56 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Mon, 12 Jul 2021 21:36:34 +0200
Subject: [PATCH 2/8] tests: Do not expect GCM work in FIPS
* tests/basic.c (check_one_cipher_core): Expect GCM ciphers to fail in
FIPS mode
(check_cipher_modes): Skip GCM ciphers tests as they fail quite late
in gcry_cipher_gettag().
--
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
---
tests/basic.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/tests/basic.c b/tests/basic.c
index 0572c46e..d7b7f496 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -9510,6 +9510,13 @@ check_one_cipher_core (int algo, int mode, int flags,
clutter_vector_registers();
err = gcry_cipher_encrypt (hd, out, nplain, plain, nplain);
+ if (in_fips_mode && mode == GCRY_CIPHER_MODE_GCM)
+ {
+ if (!err)
+ fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt is expected to "
+ "fail in FIPS mode: %s\n", pass, algo, mode, gpg_strerror (err));
+ goto err_out_free;
+ }
if (err)
{
fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt failed: %s\n",
@@ -10257,7 +10264,12 @@ check_cipher_modes(void)
check_cfb_cipher ();
check_ofb_cipher ();
check_ccm_cipher ();
- check_gcm_cipher ();
+ if (!in_fips_mode)
+ {
+ /* This will have to go through modifications as the GCM fails in fips
+ * as late as in gcry_cipher_gettag, but we want to allow it in the end */
+ check_gcm_cipher ();
+ }
check_poly1305_cipher ();
check_ocb_cipher ();
check_xts_cipher ();
--
2.31.1
From ccbb1694693080822858e2065cf88ab43ec03fbc Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 13 Jul 2021 09:18:52 +0200
Subject: [PATCH 3/8] tests: Skip unsupported mechanisms in FIPS mode
* tests/bench-slope.c (cipher_bench_one): Skip GCM mode in FIPS mode
(ecc_algo_fips_allowed): New function
(_ecc_bench): Skip algorithms disabled in FIPS mode
(main): Check for FIPS mode
* tests/benchmark.c (cipher_bench): Skip GCM in FIPS mode
--
In FIPS mode, not all the curves are allowed. This is already checked in
other parts of the code base, but not in the benchmark test.
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
---
tests/bench-slope.c | 33 +++++++++++++++++++++++++++++++--
tests/benchmark.c | 4 ++++
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/tests/bench-slope.c b/tests/bench-slope.c
index 35272094..5bdb391e 100644
--- a/tests/bench-slope.c
+++ b/tests/bench-slope.c
@@ -70,6 +70,7 @@ static double bench_ghz;
/* Current accuracy of auto-detected CPU Ghz. */
static double bench_ghz_diff;
+static int in_fips_mode = 0;
/*************************************** Default parameters for measurements. */
@@ -1642,8 +1643,8 @@ cipher_bench_one (int algo, struct bench_cipher_mode *pmode)
if (mode.mode == GCRY_CIPHER_MODE_CCM && blklen != GCRY_CCM_BLOCK_LEN)
return;
- /* GCM has restrictions for block-size */
- if (mode.mode == GCRY_CIPHER_MODE_GCM && blklen != GCRY_GCM_BLOCK_LEN)
+ /* GCM has restrictions for block-size; not allowed in FIPS mode */
+ if (mode.mode == GCRY_CIPHER_MODE_GCM && (in_fips_mode || blklen != GCRY_GCM_BLOCK_LEN))
return;
/* XTS has restrictions for block-size */
@@ -2190,6 +2191,27 @@ struct bench_ecc_hd
};
+static int
+ecc_algo_fips_allowed (int algo)
+{
+ switch (algo)
+ {
+ case ECC_ALGO_NIST_P224:
+ case ECC_ALGO_NIST_P256:
+ case ECC_ALGO_NIST_P384:
+ case ECC_ALGO_NIST_P521:
+ return 1;
+ case ECC_ALGO_SECP256K1:
+ case ECC_ALGO_ED25519:
+ case ECC_ALGO_ED448:
+ case ECC_ALGO_X25519:
+ case ECC_ALGO_X448:
+ case ECC_ALGO_NIST_P192:
+ default:
+ return 0;
+ }
+}
+
static const char *
ecc_algo_name (int algo)
{
@@ -2681,6 +2703,10 @@ _ecc_bench (int algo)
const char *algo_name;
int i;
+ /* Skip not allowed mechanisms */
+ if (!ecc_algo_fips_allowed(algo))
+ return;
+
algo_name = ecc_algo_name (algo);
bench_print_header_nsec_per_iteration (14, algo_name);
@@ -2899,6 +2925,9 @@ main (int argc, char **argv)
xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ if (gcry_fips_mode_active ())
+ in_fips_mode = 1;
+
if (in_regression_test)
fputs ("Note: " PGM " running in quick regression test mode.\n", stdout);
diff --git a/tests/benchmark.c b/tests/benchmark.c
index 605b50c6..24141371 100644
--- a/tests/benchmark.c
+++ b/tests/benchmark.c
@@ -943,6 +943,10 @@ cipher_bench ( const char *algoname )
&& algo != GCRY_CIPHER_CHACHA20)
continue;
+ /* GCM is not available in FIPS mode */
+ if (in_fips_mode && modes[modeidx].mode == GCRY_CIPHER_MODE_GCM)
+ continue;
+
if (modes[modeidx].req_blocksize > 0
&& blklen != modes[modeidx].req_blocksize)
{
--
2.31.1
From 744baa85722da10d7374c6eca6b08b8197819ab6 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 13 Jul 2021 09:20:18 +0200
Subject: [PATCH 4/8] tests: Expect curves 25519/448 to fail in FIPS mode
* tests/t-cv25519.c (test_cv_hl): Expect the operation to fail in FIPS
mode.
(test_cv_x25519, test_it): Ditto.
(main) Detect FIPS mode.
* tests/t-ed25519.c (one_test): Expect the operation to fail in FIPS
mode.
(main) Detect FIPS mode.
* tests/t-ed448.c (one_test): Expect the operation to fail in FIPS
mode.
(main) Detect FIPS mode.
* tests/t-x448.c (test_cv_hl): Expect the operation to fail in FIPS
mode.
(test_cv_x448, test_cv): Ditto.
(main) Detect FIPS mode.
--
The ed25519, ed448, cv25519 and cv448 curves are not available in FIPS
mode. Some of the tests already skipped these, but it is always better
to make sure thy are failing, rather than just skipping these.
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
---
tests/t-cv25519.c | 37 +++++++++++++++++++++++++++++++++++--
tests/t-ed25519.c | 18 ++++++++++++++----
tests/t-ed448.c | 18 ++++++++++++++----
tests/t-x448.c | 41 +++++++++++++++++++++++++++++++++++++----
4 files changed, 100 insertions(+), 14 deletions(-)
diff --git a/tests/t-cv25519.c b/tests/t-cv25519.c
index 0de50a02..b4126f4c 100644
--- a/tests/t-cv25519.c
+++ b/tests/t-cv25519.c
@@ -33,6 +33,7 @@
#include "t-common.h"
#define N_TESTS 18
+static int in_fips_mode = 0;
static void
print_mpi (const char *text, gcry_mpi_t a)
@@ -188,7 +189,17 @@ test_cv_hl (int testno, const char *k_str, const char *u_str,
xfree (buffer);
buffer = NULL;
- if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk)))
+ err = gcry_pk_encrypt (&s_result, s_data, s_pk);
+ if (in_fips_mode)
+ {
+ if (!err)
+ fail ("gcry_pk_encrypt is not expected to work in FIPS mode for test %d",
+ testno);
+ if (verbose > 1)
+ info ("not executed in FIPS mode\n");
+ goto leave;
+ }
+ if (err)
fail ("gcry_pk_encrypt failed for test %d: %s", testno,
gpg_strerror (err));
@@ -281,7 +292,17 @@ test_cv_x25519 (int testno, const char *k_str, const char *u_str,
goto leave;
}
- if ((err = gcry_ecc_mul_point (algo, result, scalar, point)))
+ err = gcry_ecc_mul_point (algo, result, scalar, point);
+ if (in_fips_mode)
+ {
+ if (!err)
+ fail ("gcry_ecc_mul_point is not expected to work in FIPS mode for test %d",
+ testno);
+ if (verbose > 1)
+ info ("not executed in FIPS mode\n");
+ goto leave;
+ }
+ if (err)
fail ("gcry_ecc_mul_point failed for test %d: %s", testno,
gpg_strerror (err));
@@ -335,6 +356,15 @@ test_it (int testno, const char *k_str, int iter, const char *result_str)
info ("Running test %d: iteration=%d\n", testno, iter);
gcry_mpi_ec_new (&ctx, NULL, "Curve25519");
+ if (in_fips_mode)
+ {
+ if (ctx)
+ fail ("gcry_mpi_ec_new should fail in FIPS mode for test %d",
+ testno);
+ if (verbose > 1)
+ info ("not executed in FIPS mode\n");
+ return;
+ }
Q = gcry_mpi_point_new (0);
if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32)
@@ -640,6 +670,9 @@ main (int argc, char **argv)
xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+ if (gcry_fips_mode_active ())
+ in_fips_mode = 1;
+
start_timer ();
check_cv25519 ();
stop_timer ();
diff --git a/tests/t-ed25519.c b/tests/t-ed25519.c
index a5271c25..567bc797 100644
--- a/tests/t-ed25519.c
+++ b/tests/t-ed25519.c
@@ -36,6 +36,7 @@
static int sign_with_pk;
static int no_verify;
static int custom_data_file;
+static int in_fips_mode = 0;
static void
@@ -271,7 +272,17 @@ one_test (int testno, const char *sk, const char *pk,
goto leave;
}
- if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk)))
+ err = gcry_pk_sign (&s_sig, s_msg, s_sk);
+ if (in_fips_mode)
+ {
+ if (!err)
+ fail ("gcry_pk_sign is not expected to work in FIPS mode for test %d",
+ testno);
+ if (verbose > 1)
+ info ("not executed in FIPS mode\n");
+ goto leave;
+ }
+ if (err)
fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err));
if (debug)
show_sexp ("sig=", s_sig);
@@ -481,9 +492,8 @@ main (int argc, char **argv)
xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
- /* Ed25519 isn't supported in fips mode */
- if (gcry_fips_mode_active())
- return 77;
+ if (gcry_fips_mode_active ())
+ in_fips_mode = 1;
start_timer ();
check_ed25519 (fname);
diff --git a/tests/t-ed448.c b/tests/t-ed448.c
index 1f445ffc..f38cd10c 100644
--- a/tests/t-ed448.c
+++ b/tests/t-ed448.c
@@ -36,6 +36,7 @@
static int sign_with_pk;
static int no_verify;
static int custom_data_file;
+static int in_fips_mode = 0;
static void
@@ -302,7 +303,17 @@ one_test (int testno, int ph, const char *sk, const char *pk,
}
}
- if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk)))
+ err = gcry_pk_sign (&s_sig, s_msg, s_sk);
+ if (in_fips_mode)
+ {
+ if (!err)
+ fail ("gcry_pk_sign is not expected to work in FIPS mode for test %d",
+ testno);
+ if (verbose > 1)
+ info ("not executed in FIPS mode\n");
+ goto leave;
+ }
+ if (err)
fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err));
if (debug)
show_sexp ("sig=", s_sig);
@@ -521,9 +532,8 @@ main (int argc, char **argv)
xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
- /* Ed448 isn't supported in fips mode */
- if (gcry_fips_mode_active())
- return 77;
+ if (gcry_fips_mode_active ())
+ in_fips_mode = 1;
start_timer ();
check_ed448 (fname);
diff --git a/tests/t-x448.c b/tests/t-x448.c
index 5c3cbeb9..cc4b10fc 100644
--- a/tests/t-x448.c
+++ b/tests/t-x448.c
@@ -34,6 +34,7 @@
#include "t-common.h"
#define N_TESTS 9
+static int in_fips_mode = 0;
static void
print_mpi (const char *text, gcry_mpi_t a)
@@ -179,8 +180,18 @@ test_cv_hl (int testno, const char *k_str, const char *u_str,
xfree (buffer);
buffer = NULL;
- if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk)))
- fail ("gcry_pk_encrypt failed for test %d: %s", testno,
+ err = gcry_pk_encrypt (&s_result, s_data, s_pk);
+ if (in_fips_mode)
+ {
+ if (!err)
+ fail ("gcry_pk_encrypt is not expected to work in FIPS mode for test %d",
+ testno);
+ if (verbose > 1)
+ info ("not executed in FIPS mode\n");
+ goto leave;
+ }
+ if (err)
+ fail ("gcry_pk_encrypt goto leavefailed for test %d: %s", testno,
gpg_strerror (err));
s_tmp = gcry_sexp_find_token (s_result, "s", 0);
@@ -257,7 +268,17 @@ test_cv_x448 (int testno, const char *k_str, const char *u_str,
goto leave;
}
- if ((err = gcry_ecc_mul_point (GCRY_ECC_CURVE448, result, scalar, point)))
+ err = gcry_ecc_mul_point (GCRY_ECC_CURVE448, result, scalar, point);
+ if (in_fips_mode)
+ {
+ if (err != GPG_ERR_NOT_SUPPORTED)
+ fail ("gcry_ecc_mul_point is not expected to work in FIPS mode for test %d: %s",
+ testno, gpg_strerror (err));
+ if (verbose > 1)
+ info ("not executed in FIPS mode\n");
+ goto leave;
+ }
+ if (err)
fail ("gcry_ecc_mul_point failed for test %d: %s", testno,
gpg_strerror (err));
@@ -296,7 +317,7 @@ test_cv (int testno, const char *k_str, const char *u_str,
static void
test_it (int testno, const char *k_str, int iter, const char *result_str)
{
- gcry_ctx_t ctx;
+ gcry_ctx_t ctx = NULL;
gpg_error_t err;
void *buffer = NULL;
size_t buflen;
@@ -311,6 +332,15 @@ test_it (int testno, const char *k_str, int iter, const char *result_str)
info ("Running test %d: iteration=%d\n", testno, iter);
gcry_mpi_ec_new (&ctx, NULL, "X448");
+ if (in_fips_mode)
+ {
+ if (ctx)
+ fail ("gcry_mpi_ec_new should fail in FIPS mode for test %d",
+ testno);
+ if (verbose > 1)
+ info ("not executed in FIPS mode\n");
+ return;
+ }
Q = gcry_mpi_point_new (0);
if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 56)
@@ -583,6 +613,9 @@ main (int argc, char **argv)
xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+ if (gcry_fips_mode_active ())
+ in_fips_mode = 1;
+
start_timer ();
check_x448 ();
stop_timer ();
--
2.31.1
From d3a603cd4a0ff2a8df35f5bb39efd64c52b2b2c5 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 13 Jul 2021 10:11:42 +0200
Subject: [PATCH 5/8] tests: Expect the 192b ECDSA tests to fail in fips mode
* tests/dsa-rfc6979.c (check_dsa_rfc6979): Expect ECDSA 192b keys to
fail in FIPS mode.
(main): Detect FIPS mode.
--
The 192b ECDSA curve is not FIPS approved so it does not work. This adds
a flag to the list of the keys to mark if it is expected to work in FIPS
mode.
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
---
tests/dsa-rfc6979.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/tests/dsa-rfc6979.c b/tests/dsa-rfc6979.c
index 7d3d2080..0f124575 100644
--- a/tests/dsa-rfc6979.c
+++ b/tests/dsa-rfc6979.c
@@ -33,6 +33,7 @@
#define PGM "dsa-rfc6979"
#include "t-common.h"
+static int in_fips_mode = 0;
static void
show_sexp (const char *prefix, gcry_sexp_t a)
@@ -111,6 +112,7 @@ check_dsa_rfc6979 (void)
static struct {
const char *name;
const char *key;
+ int fips;
} keys[] = {
{
"DSA, 1024 bits",
@@ -130,7 +132,7 @@ check_dsa_rfc6979 (void)
" 92195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D"
" 4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E6"
" 82F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B#)"
- " ))"
+ " ))", 1
},
{
"DSA, 2048 bits",
@@ -162,7 +164,7 @@ check_dsa_rfc6979 (void)
" 687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D1"
" 23AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA"
" 74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF#)"
- " ))"
+ " ))", 1
},
{
"ECDSA, 192 bits (prime field)",
@@ -172,7 +174,7 @@ check_dsa_rfc6979 (void)
" (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56"
" 3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)"
" (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)"
- " ))"
+ " ))", 0
},
{
"ECDSA, 224 bits (prime field)",
@@ -183,7 +185,7 @@ check_dsa_rfc6979 (void)
" 00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C"
" EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A#)"
" (d #F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1#)"
- " ))"
+ " ))", 1
},
{
"ECDSA, 256 bits (prime field)",
@@ -194,7 +196,7 @@ check_dsa_rfc6979 (void)
" 60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"
" 7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)"
" (d #C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721#)"
- " ))"
+ " ))", 1
},
{
"ECDSA, 384 bits (prime field)",
@@ -208,7 +210,7 @@ check_dsa_rfc6979 (void)
" 288B231C3AE0D4FE7344FD2533264720#)"
" (d #6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D8"
" 96D5724E4C70A825F872C9EA60D2EDF5#)"
- " ))"
+ " ))", 1
},
{
"ECDSA, 521 bits (prime field)",
@@ -225,7 +227,7 @@ check_dsa_rfc6979 (void)
" (d #FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75"
" CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B8"
" 3538#)"
- " ))"
+ " ))", 1
},
{ NULL }
};
@@ -937,6 +939,12 @@ check_dsa_rfc6979 (void)
die ("building data sexp failed: %s\n", gpg_strerror (err));
err = gcry_pk_sign (&sig, data, seckey);
+ if (in_fips_mode && !keys[i].fips)
+ {
+ if (!err)
+ fail ("signing should not work in FIPS mode: %s\n", gpg_strerror (err));
+ continue;
+ }
if (err)
fail ("signing failed: %s\n", gpg_strerror (err));
@@ -972,6 +980,8 @@ main (int argc, char **argv)
die ("version mismatch; pgm=%s, library=%s\n",
GCRYPT_VERSION,gcry_check_version (NULL));
xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+ if (gcry_fips_mode_active ())
+ in_fips_mode = 1;
if (debug)
xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
/* No valuable keys are create, so we can speed up our RNG. */
--
2.31.1
From d4a52861e7d0d1871f4c1d32bc0815f0824eb9ab Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 13 Jul 2021 10:32:33 +0200
Subject: [PATCH 6/8] tests: Skip secmem overflow test in FIPS mode
* tests/t-secmem.c (main): Skip overflow tests in FIPS mode because they
are fatal and there is no way to override the outofcore handler.
--
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
---
tests/t-secmem.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tests/t-secmem.c b/tests/t-secmem.c
index 2b769134..692c0f1a 100644
--- a/tests/t-secmem.c
+++ b/tests/t-secmem.c
@@ -37,6 +37,7 @@
#define MINIMUM_POOL_SIZE 16384
static size_t pool_size;
static size_t chunk_size;
+static int in_fips_mode = 0;
static void
test_secmem (void)
@@ -182,8 +183,11 @@ main (int argc, char **argv)
xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0));
xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
xgcry_control ((GCRYCTL_INIT_SECMEM, pool_size, 0));
+ /* This is ignored in FIPS Mode */
gcry_set_outofcore_handler (outofcore_handler, NULL);
xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+ if (gcry_fips_mode_active ())
+ in_fips_mode = 1;
/* Libgcrypt prints a warning when the first overflow is allocated;
* we do not want to see that. */
@@ -192,7 +196,8 @@ main (int argc, char **argv)
test_secmem ();
- test_secmem_overflow ();
+ if (!in_fips_mode)
+ test_secmem_overflow ();
/* FIXME: We need to improve the tests, for example by registering
* our own log handler and comparing the output of
* PRIV_CTL_DUMP_SECMEM_STATS to expected pattern. */
--
2.31.1
From fc6de9c7b48ab45deb8ea84d1c768e4f056edb08 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 13 Jul 2021 10:52:00 +0200
Subject: [PATCH 7/8] tests: Transient DSA keys work in FIPS mode
* tests/pubkey.c (check_run): Enable tests with DSA transient keys which
work in FIPS.
--
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
---
tests/pubkey.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/tests/pubkey.c b/tests/pubkey.c
index 754952ee..cd51e0a2 100644
--- a/tests/pubkey.c
+++ b/tests/pubkey.c
@@ -680,15 +680,12 @@ check_run (void)
gcry_sexp_release (pkey);
gcry_sexp_release (skey);
- if (!gcry_fips_mode_active ())
- {
- if (verbose)
- fprintf (stderr, "Generating transient DSA key.\n");
- get_dsa_key_new (&pkey, &skey, 1);
- /* Fixme: Add a check function for DSA keys. */
- gcry_sexp_release (pkey);
- gcry_sexp_release (skey);
- }
+ if (verbose)
+ fprintf (stderr, "Generating transient DSA key.\n");
+ get_dsa_key_new (&pkey, &skey, 1);
+ /* Fixme: Add a check function for DSA keys. */
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
if (verbose)
fprintf (stderr, "Generating DSA key (FIPS 186).\n");
--
2.31.1
From e68b538008063938b9b054f18e56e9f27bb3a720 Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Tue, 13 Jul 2021 10:53:13 +0200
Subject: [PATCH 8/8] tests: Generating DSA from domain should fail in FIPS
mode
* tests/pubkey.c (get_dsa_key_with_domain_new): Expect failure in FIPS
mode
(check_x931_derived_key): Simplify testing for FIPS mode.
(main): Check for fips mode.
--
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
---
tests/pubkey.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/tests/pubkey.c b/tests/pubkey.c
index cd51e0a2..7209f44e 100644
--- a/tests/pubkey.c
+++ b/tests/pubkey.c
@@ -29,6 +29,7 @@
#define PGM "pubkey"
#include "t-common.h"
+static int in_fips_mode;
/* Sample RSA keys, taken from basic.c. */
@@ -518,6 +519,14 @@ get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
die ("error creating S-expression: %s\n", gcry_strerror (rc));
rc = gcry_pk_genkey (&key, key_spec);
gcry_sexp_release (key_spec);
+ if (in_fips_mode)
+ {
+ if (!rc)
+ die ("generating DSA key should fail in FIPS mode: %s\n", gcry_strerror (rc));
+ *pkey = NULL;
+ *skey = NULL;
+ return;
+ }
if (rc)
die ("error generating DSA key: %s\n", gcry_strerror (rc));
@@ -899,7 +908,7 @@ check_x931_derived_key (int what)
err = _gcry_pk_util_get_nbits(key_spec, &nbits);
if (err)
die ("nbits not found\n");
- if (gcry_fips_mode_active() && nbits < 2048)
+ if (in_fips_mode && nbits < 2048)
{
info("RSA key test with %d bits skipped in fips mode\n", nbits);
goto leave;
@@ -1186,6 +1195,9 @@ main (int argc, char **argv)
/* No valuable keys are create, so we can speed up our RNG. */
xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ if (gcry_fips_mode_active ())
+ in_fips_mode = 1;
+
for (i=0; i < 2; i++)
check_run ();
@@ -1193,7 +1205,7 @@ main (int argc, char **argv)
check_x931_derived_key (i);
check_ecc_sample_key ();
- if (!gcry_fips_mode_active ())
+ if (!in_fips_mode)
check_ed25519ecdsa_sample_key ();
return !!error_count;
--
2.31.1
commit 61c87070abc4baeb9d847db015e6a3031f349483
Author: NIIBE Yutaka <gniibe@fsij.org>
Date: Wed Jul 7 15:52:06 2021 +0900
tests: Skip unavailable ciphers in FIPS mode.
* tests/basic.c (_check_poly1305_cipher):
(check_ocb_cipher_largebuf_split): Skip unavailable ciphers when
IN_FIPS_MODE.
(check_ocb_cipher_checksum, check_gost28147_cipher_basic): Likewise.
--
GnuPG-bug-id: 5520
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
diff --git a/tests/basic.c b/tests/basic.c
index 0a1e8293..43ef122e 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -5026,6 +5026,14 @@ _check_poly1305_cipher (unsigned int step)
for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
{
+ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ tv[i].algo);
+ continue;
+ }
+
if (verbose)
fprintf (stderr, " checking POLY1305 mode for %s [%i]\n",
gcry_cipher_algo_name (tv[i].algo),
@@ -6643,6 +6651,14 @@ check_ocb_cipher_largebuf_split (int algo, int keylen, const char *tagexpect,
memcpy(inbuf + i, hash, 16);
}
+ if (gcry_cipher_test_algo (algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ algo);
+ goto out_free;
+ }
+
err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0);
if (!err)
err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0);
@@ -6841,6 +6857,14 @@ check_ocb_cipher_checksum (int algo, int keylen)
blk[byteidx] |= 1 << bitpos;
}
+ if (gcry_cipher_test_algo (algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ algo);
+ goto out_free;
+ }
+
err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0);
if (!err)
err = gcry_cipher_open (&hde2, algo, GCRY_CIPHER_MODE_OCB, 0);
@@ -7651,6 +7675,15 @@ check_gost28147_cipher_basic (enum gcry_cipher_algos algo)
if (verbose)
fprintf (stderr, " Starting GOST28147 cipher checks.\n");
+
+ if (gcry_cipher_test_algo (algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ algo);
+ return;
+ }
+
keylen = gcry_cipher_get_algo_keylen(algo);
if (!keylen)
{
commit b98ca3f798abd17696f52163665204c4e83d9092
Author: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Date: Wed Jul 7 18:21:27 2021 +0300
tests/basic: use SHA256 instead of RMD160 for SHAKE extract testing
* tests/basic.c (check_one_md): Use GCRY_MD_SHA256 as 'crcalgo' for
SHAKE128/SHAKE256 testing.
--
RMD160 was used to calculate output checksum from two SHAKE extract
streams, which are run with different extract buffer size but for
same total length and with same input. Patch switches to use SHA256
for checksumming for FIPS support.
GnuPG-bug-id: 5520
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
diff --git a/tests/basic.c b/tests/basic.c
index bc34bb99..eb6d1514 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -10395,7 +10395,7 @@ check_one_md (int algo, const char *data, int len, const char *expect, int elen,
if (*data == '!' && !data[1])
{
- int crcalgo = GCRY_MD_RMD160;
+ int crcalgo = GCRY_MD_SHA256;
gcry_md_hd_t crc1, crc2;
size_t startlen;
size_t piecelen;
commit ccb076e8aabb9c49e7026258b3a36a8422f6bbe4
Author: NIIBE Yutaka <gniibe@fsij.org>
Date: Wed Jul 7 16:29:48 2021 +0900
tests: Fix tests/basic.c for FIPS mode.
* tests/basic.c (main): Use bare gcry_control for
GCRYCTL_FORCE_FIPS_MODE.
--
GnuPG-bug-id: 5520
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
diff --git a/tests/basic.c b/tests/basic.c
index 43ef122e..bc34bb99 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -14610,7 +14610,7 @@ main (int argc, char **argv)
gcry_md_hd_t md;
/* First trigger a self-test. */
- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0));
+ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0))
fail ("not in operational state after self-test\n");
@@ -14639,7 +14639,7 @@ main (int argc, char **argv)
{
/* Now run a self-test and to get back into
operational state. */
- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0));
+ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0))
fail ("did not reach operational after error "
"and self-test\n");