[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/5] libgcrypt: Implement the 'evp' interface


* include/libssh/libgcrypt.h (EVPCTX): Fix type.
(NID_gcrypt_nistp{256,384,521}): New constants.
* src/libgcrypt.c (nid_to_md_algo): New function mapping curves to
digest algorithms.
(evp{,_init,_update,_final}): New functions.

Signed-off-by: Justus Winter <justus@xxxxxxxxxxx>
---
 include/libssh/libgcrypt.h |  7 +++++-
 src/libgcrypt.c            | 53 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/include/libssh/libgcrypt.h b/include/libssh/libgcrypt.h
index 7556aca..ec35391 100644
--- a/include/libssh/libgcrypt.h
+++ b/include/libssh/libgcrypt.h
@@ -32,7 +32,7 @@ typedef gcry_md_hd_t SHA384CTX;
 typedef gcry_md_hd_t SHA512CTX;
 typedef gcry_md_hd_t MD5CTX;
 typedef gcry_md_hd_t HMACCTX;
-typedef void *EVPCTX;
+typedef gcry_md_hd_t EVPCTX;
 #define SHA_DIGEST_LENGTH 20
 #define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
 #define MD5_DIGEST_LEN 16
@@ -51,6 +51,11 @@ typedef void *EVPCTX;
 
 typedef gcry_mpi_t bignum;
 
+/* Constants for curves.  */
+#define NID_gcrypt_nistp256 0
+#define NID_gcrypt_nistp384 1
+#define NID_gcrypt_nistp521 2
+
 /* missing gcrypt functions */
 int ssh_gcry_dec2bn(bignum *bn, const char *data);
 char *ssh_gcry_bn2dec(bignum bn);
diff --git a/src/libgcrypt.c b/src/libgcrypt.c
index 60f6536..0e85d5d 100644
--- a/src/libgcrypt.c
+++ b/src/libgcrypt.c
@@ -71,6 +71,59 @@ void sha1(unsigned char *digest, int len, unsigned char *hash) {
   gcry_md_hash_buffer(GCRY_MD_SHA1, hash, digest, len);
 }
 
+#ifdef HAVE_GCRYPT_ECC
+static int nid_to_md_algo(int nid)
+{
+    switch (nid) {
+    case NID_gcrypt_nistp256:
+        return GCRY_MD_SHA256;
+    case NID_gcrypt_nistp384:
+        return GCRY_MD_SHA384;
+    case NID_gcrypt_nistp521:
+        return GCRY_MD_SHA512;
+    }
+    return GCRY_MD_NONE;
+}
+
+void evp(int nid, unsigned char *digest, int len,
+         unsigned char *hash, unsigned int *hlen)
+{
+    int algo = nid_to_md_algo(nid);
+
+    /* Note: What gcrypt calls 'hash' is called 'digest' here and
+       vice-versa.  */
+    gcry_md_hash_buffer(algo, hash, digest, len);
+    *hlen = gcry_md_get_algo_dlen(algo);
+}
+
+EVPCTX evp_init(int nid)
+{
+    gcry_error_t err;
+    int algo = nid_to_md_algo(nid);
+    EVPCTX ctx;
+
+    err = gcry_md_open(&ctx, algo, 0);
+    if (err) {
+        return NULL;
+    }
+
+    return ctx;
+}
+
+void evp_update(EVPCTX ctx, const void *data, unsigned long len)
+{
+    gcry_md_write(ctx, data, len);
+}
+
+void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
+{
+    int algo = gcry_md_get_algo(ctx);
+    *mdlen = gcry_md_get_algo_dlen(algo);
+    memcpy(md, gcry_md_read(ctx, algo), *mdlen);
+    gcry_md_close(ctx);
+}
+#endif
+
 SHA256CTX sha256_init(void) {
   SHA256CTX ctx = NULL;
   gcry_md_open(&ctx, GCRY_MD_SHA256, 0);
-- 
2.8.1


References:
Re: [PATCH 2/3] pki_gcrypt: Handle ECDSA keys and signaturesAndreas Schneider <asn@xxxxxxxxxxxxxx>
[PATCH 1/5] curve25519: Small libgcrypt bignum fixJustus Winter <justus@xxxxxxxxxxx>
Archive administrator: postmaster@lists.cynapses.org