support gcrypt library
authorEugene Crosser <crosser@average.org>
Sat, 9 Nov 2013 12:36:28 +0000 (16:36 +0400)
committerEugene Crosser <crosser@average.org>
Sat, 9 Nov 2013 12:36:28 +0000 (16:36 +0400)
Makefile.am
configure.ac
crypto.c
gnu_crypto.c [new file with mode: 0644]

index a91944df5e3d079ddf03fb72740812f596e1aa0d..ec874ec55ed505e881f9b1f616ad10ea1009d32a 100644 (file)
@@ -7,7 +7,7 @@ noinst_HEADERS = pcsc_cr.h token.h crypto_if.h crypto.h serial.h authobj.h
 
 EXTRA_LTLIBRARIES = libpcsc_cr.la
 libpcsc_cr_la_SOURCES = authobj.c serial.c crypto.c pcsc_cr.c ykneo.c
-EXTRA_libpcsc_cr_la_SOURCES = ossl_crypto.c tom_crypto.c
+EXTRA_libpcsc_cr_la_SOURCES = ossl_crypto.c tom_crypto.c gnu_crypto.c
 libpcsc_cr_la_LIBADD = @CRYPTO_OBJS@
 libpcsc_cr_la_DEPENDENCIES = @CRYPTO_OBJS@
 
index 4a9453d3126a62d7d791a95250141dbb4155a532..17b40dda9711a63f8e5145c65e5437da20a1380e 100644 (file)
@@ -67,8 +67,29 @@ AS_IF([test "x$TOMCRYPT_CFLAGS" != "x" -o "x$TOMCRYPT_LIBS" != "x" ], [
 CPPFLAGS="$TOMCRYPT_CFLAGS $CPPFLAGS"
 LIBS="$TOMCRYPT_LIBS $LIBS"
 
-AS_IF([test "x$use_openssl" != "xyes" -a "x$use_tomcrypt" != "xyes"], [
-  AC_MSG_ERROR([[Neither openssl nor tomcrypt libraries present]])
+AC_ARG_ENABLE(gcrypt,
+       [  --enable-gcrypt         use libgcrypt even when openssl present])
+
+AS_IF([test "x$use_openssl" != "xyes" && test "x$use_tomcrypt" != "xyes" || \
+       test "x$enable_tomcrypt" = "xyes"], [
+  AM_PATH_LIBGCRYPT()
+])
+AC_ARG_WITH(libgcrypt-include-path,
+       [  --with-libgcrypt-include-path=PATH path to libgcrypt includes],
+       [LIBGCRYPT_CFLAGS="-I $withval"],
+       [])
+AC_ARG_WITH(libgcrypt-lib-path,
+       [  --with-libgcrypt-lib-path=PATH path to libgcrypt libs],
+       [LIBGCRYPT_LIBS="-L $withval -lgcrypt"],
+       [])
+AS_IF([test "x$LIBGCRYPT_CFLAGS" != "x" -o "x$LIBGCRYPT_LIBS" != "x" ], [
+  use_gcrypt=yes
+])
+CPPFLAGS="$LIBGCRYPT_CFLAGS $CPPFLAGS"
+LIBS="$LIBGCRYPT_LIBS $LIBS"
+
+AS_IF([test "x$use_openssl" != "xyes" -a "x$use_tomcrypt" != "xyes" -a "x$use_gcrypt" != "xyes"], [
+  AC_MSG_ERROR([[Neither openssl, tomcrypt or gcrypt libraries present]])
 ])
 
 AS_IF([test "x$use_openssl" = "xyes"], [
@@ -79,6 +100,10 @@ AS_IF([test "x$use_tomcrypt" = "xyes"], [
   CRYPTO_OBJS+=" tom_crypto.lo"
   AC_DEFINE([HAVE_TOMCRYPT], [1], [Use libtomcrypt])
 ])
+AS_IF([test "x$use_gcrypt" = "xyes"], [
+  CRYPTO_OBJS+=" gnu_crypto.lo"
+  AC_DEFINE([HAVE_GCRYPT], [1], [Use libgcrypt])
+])
 AC_SUBST(CRYPTO_OBJS)
 
 dnl Checks for header files.
index 6456932aaea06d7533775db27ff642be85588e44..105db4e727cf43220bfe4d341ed138230cc2480a 100644 (file)
--- a/crypto.c
+++ b/crypto.c
@@ -7,6 +7,7 @@
 
 extern struct crypto_interface ossl_crypto_if;
 extern struct crypto_interface tom_crypto_if;
+extern struct crypto_interface gnu_crypto_if;
 
 static struct crypto_interface *ifs[] = {
 #ifdef HAVE_OPENSSL
@@ -14,6 +15,9 @@ static struct crypto_interface *ifs[] = {
 #endif
 #ifdef HAVE_TOMCRYPT
        &tom_crypto_if,
+#endif
+#ifdef HAVE_GCRYPT
+       &gnu_crypto_if,
 #endif
        (void*)0,
 };
diff --git a/gnu_crypto.c b/gnu_crypto.c
new file mode 100644 (file)
index 0000000..190e9e1
--- /dev/null
@@ -0,0 +1,108 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <errno.h>
+#include <gcrypt.h>
+#include "crypto_if.h"
+
+static const char *gnu_init(void)
+{
+       (void)gcry_check_version(GCRYPT_VERSION);
+       gcry_control(GCRYCTL_SUSPEND_SECMEM_WARN);
+       gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
+       return "gcrypt";
+}
+
+static unsigned long gnu_encrypt(void *key, int keylen, void *iv,
+                       void *pt, void *ct, int tlen)
+{
+       gcry_error_t err;
+       gcry_cipher_hd_t hd;
+
+       if ((err = gcry_cipher_open(&hd, GCRY_CIPHER_AES128,
+                                       GCRY_CIPHER_MODE_CBC, 0)))
+               return (unsigned long)err;
+       if ((err = gcry_cipher_setkey(hd, key, keylen)))
+               return (unsigned long)err;
+       if ((err = gcry_cipher_setiv(hd, iv, keylen)))
+               return (unsigned long)err;
+       if ((err = gcry_cipher_encrypt(hd, ct, tlen, pt, tlen)))
+               return (unsigned long)err;
+       if ((err = gcry_cipher_reset(hd)))
+               return (unsigned long)err;
+       return 0UL;
+}
+
+static unsigned long gnu_decrypt(void *key, int keylen, void *iv,
+                       void *ct, void *pt, int tlen)
+{
+       gcry_error_t err;
+       gcry_cipher_hd_t hd;
+
+       if ((err = gcry_cipher_open(&hd, GCRY_CIPHER_AES128,
+                                       GCRY_CIPHER_MODE_CBC, 0)))
+               return (unsigned long)err;
+       if ((err = gcry_cipher_setkey(hd, key, keylen)))
+               return (unsigned long)err;
+       if ((err = gcry_cipher_setiv(hd, iv, keylen)))
+               return (unsigned long)err;
+       if ((err = gcry_cipher_decrypt(hd, pt, tlen, ct, tlen)))
+               return (unsigned long)err;
+       if ((err = gcry_cipher_reset(hd)))
+               return (unsigned long)err;
+       return 0UL;
+}
+
+static unsigned long gnu_hash(void *pt, int tlen, void *tag, int *taglen)
+{
+       gcry_error_t err;
+       gcry_md_hd_t hd;
+
+       unsigned int dlen = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
+       if (*taglen < dlen)
+               return (unsigned long)gcry_error_from_errno(ENOMEM);
+       if ((err = gcry_md_open(&hd, GCRY_MD_SHA1, GCRY_MD_FLAG_SECURE)))
+               return (unsigned long)err;
+       gcry_md_write(hd, pt, tlen);
+       gcry_md_final(hd);
+       memcpy(tag, gcry_md_read(hd, GCRY_MD_SHA1), dlen);
+       gcry_md_close(hd);
+       *taglen = dlen;
+       return 0UL;
+}
+
+static unsigned long gnu_hmac(void *key, int keylen, void *pt, int tlen,
+                       void *tag, int *taglen)
+{
+       gcry_error_t err;
+       gcry_md_hd_t hd;
+
+       unsigned int dlen = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
+       if (*taglen < dlen)
+               return (unsigned long)gcry_error_from_errno(ENOMEM);
+       if ((err = gcry_md_open(&hd, GCRY_MD_SHA1, GCRY_MD_FLAG_SECURE |
+                                                       GCRY_MD_FLAG_HMAC)))
+               return (unsigned long)err;
+       if ((err = gcry_md_setkey(hd, key, keylen)))
+               return (unsigned long)err;
+       gcry_md_write(hd, pt, tlen);
+       gcry_md_final(hd);
+       memcpy(tag, gcry_md_read(hd, GCRY_MD_SHA1), dlen);
+       gcry_md_close(hd);
+       *taglen = dlen;
+       return 0UL;
+}
+
+static const char *gnu_errstr(unsigned long err)
+{
+       return gcry_strerror((gcry_error_t)err);
+}
+
+struct crypto_interface gnu_crypto_if = {
+       .init           = gnu_init,
+       .encrypt        = gnu_encrypt,
+       .decrypt        = gnu_decrypt,
+       .hash           = gnu_hash,
+       .hmac           = gnu_hmac,
+       .errstr         = gnu_errstr,
+};