From 9cfb078547dfafdb01cfd87c05acffdbc07255ee Mon Sep 17 00:00:00 2001 From: Eugene Crosser Date: Sat, 9 Nov 2013 16:36:28 +0400 Subject: [PATCH] support gcrypt library --- Makefile.am | 2 +- configure.ac | 29 +++++++++++++- crypto.c | 4 ++ gnu_crypto.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 gnu_crypto.c diff --git a/Makefile.am b/Makefile.am index a91944d..ec874ec 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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@ diff --git a/configure.ac b/configure.ac index 4a9453d..17b40dd 100644 --- a/configure.ac +++ b/configure.ac @@ -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. diff --git a/crypto.c b/crypto.c index 6456932..105db4e 100644 --- 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 index 0000000..190e9e1 --- /dev/null +++ b/gnu_crypto.c @@ -0,0 +1,108 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#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, +}; -- 2.39.2