summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2021-09-16 15:06:27 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2021-09-16 15:06:27 +0900
commit117f5c3f8028efc18a0b20d854b6b2b8babcb1d6 (patch)
tree9e41cb405657f4838337eb1db9c3df051239e129
parent722604169704dd4c5d322eaef6dfd165ddd50fd0 (diff)
downloadlibgcrypt-117f5c3f8028efc18a0b20d854b6b2b8babcb1d6.tar.gz
experiment-pk_hash_sign/verify: Implement pk_hash_sign/verify.
-- GnuPG-bug-id: 4894 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
-rw-r--r--cipher/pubkey.c104
-rw-r--r--src/gcrypt-int.h4
-rw-r--r--src/gcrypt.h.in31
-rw-r--r--src/visibility.c16
4 files changed, 142 insertions, 13 deletions
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index 3ca09932..fcc9fb29 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -438,6 +438,59 @@ _gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
}
+gcry_err_code_t
+_gcry_pk_sign_md (gcry_sexp_t *r_sig, const char *tmpl, gcry_md_hd_t hd_orig,
+ gcry_sexp_t s_skey)
+{
+ gcry_err_code_t rc;
+ gcry_pk_spec_t *spec;
+ gcry_sexp_t keyparms = NULL;
+ gcry_sexp_t s_hash = NULL;
+ int algo;
+ const unsigned char *digest;
+ gcry_error_t err;
+ gcry_md_hd_t hd;
+
+ *r_sig = NULL;
+
+ err = _gcry_md_copy (&hd, hd_orig);
+ if (err)
+ return gpg_err_code (err);
+
+ algo = _gcry_md_get_algo (hd);
+
+ digest = _gcry_md_read (hd, 0);
+ if (!digest)
+ {
+ _gcry_md_close (hd);
+ return GPG_ERR_DIGEST_ALGO;
+ }
+
+ rc = _gcry_sexp_build (&s_hash, NULL, tmpl,
+ _gcry_md_algo_name (algo),
+ (int) _gcry_md_get_algo_dlen (algo),
+ digest);
+
+ _gcry_md_close (hd);
+ if (rc)
+ goto leave;
+
+ rc = spec_from_sexp (s_skey, 1, &spec, &keyparms);
+ if (rc)
+ goto leave;
+
+ if (spec->sign)
+ rc = spec->sign (r_sig, s_hash, keyparms);
+ else
+ rc = GPG_ERR_NOT_IMPLEMENTED;
+
+ leave:
+ sexp_release (s_hash);
+ sexp_release (keyparms);
+ return rc;
+}
+
+
/*
Verify a signature.
@@ -467,6 +520,57 @@ _gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
}
+gcry_err_code_t
+_gcry_pk_verify_md (gcry_sexp_t s_sig, const char *tmpl, gcry_md_hd_t hd_orig,
+ gcry_sexp_t s_pkey)
+{
+ gcry_err_code_t rc;
+ gcry_pk_spec_t *spec;
+ gcry_sexp_t keyparms = NULL;
+ gcry_sexp_t s_hash = NULL;
+ int algo;
+ const unsigned char *digest;
+ gcry_error_t err;
+ gcry_md_hd_t hd;
+
+ err = _gcry_md_copy (&hd, hd_orig);
+ if (err)
+ return gpg_err_code (err);
+
+ algo = _gcry_md_get_algo (hd);
+
+ digest = _gcry_md_read (hd, 0);
+ if (!digest)
+ {
+ _gcry_md_close (hd);
+ return GPG_ERR_DIGEST_ALGO;
+ }
+
+ rc = _gcry_sexp_build (&s_hash, NULL, tmpl,
+ _gcry_md_algo_name (algo),
+ (int) _gcry_md_get_algo_dlen (algo),
+ digest);
+
+ _gcry_md_close (hd);
+ if (rc)
+ goto leave;
+
+ rc = spec_from_sexp (s_pkey, 1, &spec, &keyparms);
+ if (rc)
+ goto leave;
+
+ if (spec->verify)
+ rc = spec->verify (s_sig, s_hash, keyparms);
+ else
+ rc = GPG_ERR_NOT_IMPLEMENTED;
+
+ leave:
+ sexp_release (s_hash);
+ sexp_release (keyparms);
+ return rc;
+}
+
+
/*
Test a key.
diff --git a/src/gcrypt-int.h b/src/gcrypt-int.h
index 5bfa9a81..6829a427 100644
--- a/src/gcrypt-int.h
+++ b/src/gcrypt-int.h
@@ -113,6 +113,10 @@ unsigned int _gcry_ecc_get_algo_keylen (int algo);
gpg_error_t _gcry_ecc_mul_point (int algo, unsigned char *result,
const unsigned char *scalar,
const unsigned char *point);
+gcry_err_code_t _gcry_pk_sign_md (gcry_sexp_t *r_sig, const char *tmpl,
+ gcry_md_hd_t hd, gcry_sexp_t s_skey);
+gcry_err_code_t _gcry_pk_verify_md (gcry_sexp_t s_sig, const char *tmpl,
+ gcry_md_hd_t hd, gcry_sexp_t s_pkey);
gcry_error_t _gcry_pkey_vopen (gcry_pkey_hd_t *h, int algo, unsigned int flags,
va_list arg_ptr);
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
index 11225031..5eafed91 100644
--- a/src/gcrypt.h.in
+++ b/src/gcrypt.h.in
@@ -1160,19 +1160,6 @@ gcry_error_t gcry_pk_decrypt (gcry_sexp_t *result,
gcry_error_t gcry_pk_sign (gcry_sexp_t *result,
gcry_sexp_t data, gcry_sexp_t skey);
-/* Variant of gcry_pk_sign which takes as additional parameter a HASH
- * handle and an optional context. The hash algorithm used by the
- * handle needs to have the algorithm given by the DATA parameter
- * enabled. The hash handle must not yet been finalized; the function
- * takes a copy of the state and does a finalize on the copy. This
- * function shall be used if a policy requires that hashing and signing
- * is done by the same function. CTX is currently not used and should
- * be passed as NULL. */
-gcry_error_t gcry_pk_hash_sign (gcry_sexp_t *result,
- gcry_sexp_t data, gcry_sexp_t skey,
- gcry_md_hd_t hash,
- gcry_ctx_t ctx);
-
/* Check the signature SIGVAL on DATA using the public key PKEY. */
gcry_error_t gcry_pk_verify (gcry_sexp_t sigval,
gcry_sexp_t data, gcry_sexp_t pkey);
@@ -1904,6 +1891,24 @@ int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE;
/* Return true if Libgcrypt is in FIPS mode. */
#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0)
+/* Variant of gcry_pk_sign which takes as additional parameter a HD
+ * handle for hash and an optional context. The hash algorithm used by the
+ * handle needs to be enabled and input needs to be supplied beforehand.
+ * DATA-TMPL specifies a template to compose an S-expression to be signed.
+ * The hash handle must not yet been finalized; the function
+ * takes a copy of the state and does a finalize on the copy. This
+ * function shall be used if a policy requires that hashing and signing
+ * is done by the same function. CTX is currently not used and should
+ * be passed as NULL. */
+gcry_error_t gcry_pk_hash_sign (gcry_sexp_t *result,
+ const char *data_tmpl, gcry_sexp_t skey,
+ gcry_md_hd_t hd, gcry_ctx_t ctx);
+
+/* Variant of gcry_pk_verify which takes as additional parameter a HD
+ * handle for hash and an optional context. Similar to gcry_pk_hash_sign. */
+gcry_error_t gcry_pk_hash_verify (gcry_sexp_t sigval,
+ const char *data_tmpl, gcry_sexp_t pkey,
+ gcry_md_hd_t hd, gcry_ctx_t ctx);
#if 0 /* (Keep Emacsens' auto-indent happy.) */
{
diff --git a/src/visibility.c b/src/visibility.c
index 86ec3786..3f0514f7 100644
--- a/src/visibility.c
+++ b/src/visibility.c
@@ -1028,6 +1028,14 @@ gcry_pk_sign (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey)
}
gcry_error_t
+gcry_pk_hash_sign (gcry_sexp_t *result, const char *data_tmpl, gcry_sexp_t skey,
+ gcry_md_hd_t hd, gcry_ctx_t ctx)
+{
+ (void)ctx;
+ return gpg_error (_gcry_pk_sign_md (result, data_tmpl, hd, skey));
+}
+
+gcry_error_t
gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey)
{
if (!fips_is_operational ())
@@ -1036,6 +1044,14 @@ gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey)
}
gcry_error_t
+gcry_pk_hash_verify (gcry_sexp_t sigval, const char *data_tmpl, gcry_sexp_t pkey,
+ gcry_md_hd_t hd, gcry_ctx_t ctx)
+{
+ (void)ctx;
+ return gpg_error (_gcry_pk_verify_md (sigval, data_tmpl, hd, pkey));
+}
+
+gcry_error_t
gcry_pk_testkey (gcry_sexp_t key)
{
if (!fips_is_operational ())