More changes - first successful handshake.
authorWerner Koch <wk@gnupg.org>
Mon, 29 Sep 2014 15:34:28 +0000 (17:34 +0200)
committerWerner Koch <wk@gnupg.org>
Wed, 1 Oct 2014 15:44:18 +0000 (17:44 +0200)
* src/dhm.c: New.
* src/pkglue.c: New.
* src/util.c: New.

19 files changed:
configure.ac
src/Makefile.am
src/ciphersuites.c
src/ciphersuites.h
src/context.h
src/debug.c
src/dhm.c [new file with mode: 0644]
src/libntbtls.vers
src/ntbtls-cli.c
src/ntbtls-int.h
src/ntbtls.h.in
src/pkglue.c [new file with mode: 0644]
src/protocol-cli.c
src/protocol.c
src/util.c [new file with mode: 0644]
src/util.h
src/visibility.c
src/visibility.h
src/x509.c

index 9993710..e2bfe5c 100644 (file)
@@ -26,7 +26,7 @@ min_automake_version="1.11"
 # another commit and push so that the git magic is able to work.
 m4_define([mym4_package],[ntbtls])
 m4_define([mym4_major], [0])
-m4_define([mym4_minor], [0])
+m4_define([mym4_minor], [1])
 m4_define([mym4_micro], [0])
 
 # To start a new development series, i.e a new major or minor number
@@ -605,8 +605,16 @@ BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'`
 changequote([,])dnl
 BUILD_FILEVERSION="${BUILD_FILEVERSION}mym4_revision_dec"
 AC_SUBST(BUILD_FILEVERSION)
-
-BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date`
+AC_ARG_ENABLE([build-timestamp],
+              AC_HELP_STRING([--enable-build-timestamp],
+                [set an explicit build timestamp for reproducibility.
+                 (default is the current time in ISO-8601 format)]),
+                [if test "$enableval" = "no"; then
+                    BUILD_TIMESTAMP="<none>"
+                 else
+                    BUILD_TIMESTAMP="$enableval"
+                 fi],
+        [BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date`])
 AC_SUBST(BUILD_TIMESTAMP)
 AC_DEFINE_UNQUOTED(BUILD_TIMESTAMP, "$BUILD_TIMESTAMP",
                    [The time this package was configured for a build])
index a693b28..a314ca0 100644 (file)
@@ -80,11 +80,12 @@ libntbtls_la_LIBADD = $(ntbtls_res) @LTLIBOBJS@ @GPG_ERROR_LIBS@
 libntbtls_la_SOURCES = \
        ntbtls.h \
         visibility.c visibility.h \
-       context.h ntbtls-int.h util.h wipemem.h \
+       context.h ntbtls-int.h wipemem.h \
+       util.c util.h \
        protocol.c \
        protocol-cli.c \
        ciphersuites.c ciphersuites.h \
-       x509.c \
+       pkglue.c x509.c dhm.c \
        debug.c
 
 # protocol-srv.c
index ebc2d40..45deb13 100644 (file)
@@ -39,7 +39,7 @@ struct _ntbtls_ciphersuite_s
   const char *name;
   cipher_algo_t cipher;
   cipher_mode_t ciphermode;
-  md_algo_t mac;
+  mac_algo_t mac;
   key_exchange_type_t key_exchange;
   unsigned char flags;
   unsigned char min_major_ver;
@@ -235,7 +235,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
    "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_ECDHE_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -243,7 +243,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
    "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_ECDHE_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -251,7 +251,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
    "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDHE_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -259,7 +259,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
    "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDHE_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -267,7 +267,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
    "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDHE_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -275,7 +275,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
    "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDHE_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -283,7 +283,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
    "TLS-ECDHE-ECDSA-WITH-AES-256-CCM",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDHE_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -291,7 +291,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
    "TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDHE_ECDSA,
    CIPHERSUITE_FLAG_SHORT_TAG,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -299,7 +299,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
    "TLS-ECDHE-ECDSA-WITH-AES-128-CCM",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDHE_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -307,7 +307,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
    "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDHE_ECDSA,
    CIPHERSUITE_FLAG_SHORT_TAG,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -315,7 +315,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
    "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDHE_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -323,7 +323,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
    "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDHE_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -331,7 +331,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
    "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDHE_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -339,7 +339,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
    "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDHE_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -347,7 +347,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
    "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA",
-   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_ECDHE_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -355,7 +355,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
    "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_ECDHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -363,7 +363,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
    "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_ECDHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -371,7 +371,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
    "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -379,7 +379,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
    "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -387,7 +387,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
    "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -395,7 +395,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
    "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -403,7 +403,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
    "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -411,7 +411,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
    "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -419,7 +419,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
    "TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -427,7 +427,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
    "TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -435,7 +435,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
    "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA",
-   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_ECDHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -443,7 +443,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
    "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -451,7 +451,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
    "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -459,7 +459,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
    "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -467,7 +467,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
    "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -475,7 +475,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
    "TLS-DHE-RSA-WITH-AES-128-CBC-SHA",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -483,7 +483,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
    "TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -491,7 +491,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_AES_256_CCM,
    "TLS-DHE-RSA-WITH-AES-256-CCM",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -499,7 +499,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_AES_256_CCM_8,
    "TLS-DHE-RSA-WITH-AES-256-CCM-8",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_RSA,
    CIPHERSUITE_FLAG_SHORT_TAG,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -507,7 +507,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_AES_128_CCM,
    "TLS-DHE-RSA-WITH-AES-128-CCM",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -515,7 +515,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_AES_128_CCM_8,
    "TLS-DHE-RSA-WITH-AES-128-CCM-8",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_RSA,
    CIPHERSUITE_FLAG_SHORT_TAG,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -523,7 +523,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
    "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -531,7 +531,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
    "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -539,7 +539,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
    "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -547,7 +547,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
    "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -555,7 +555,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
    "TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -563,7 +563,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
    "TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -571,7 +571,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
    "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA",
-   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_DHE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -579,7 +579,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_AES_256_GCM_SHA384,
    "TLS-RSA-WITH-AES-256-GCM-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -587,7 +587,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_AES_128_GCM_SHA256,
    "TLS-RSA-WITH-AES-128-GCM-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -595,7 +595,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_AES_128_CBC_SHA256,
    "TLS-RSA-WITH-AES-128-CBC-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -603,7 +603,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_AES_256_CBC_SHA256,
    "TLS-RSA-WITH-AES-256-CBC-SHA256",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -611,7 +611,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_AES_128_CBC_SHA,
    "TLS-RSA-WITH-AES-128-CBC-SHA",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -619,7 +619,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_AES_256_CBC_SHA,
    "TLS-RSA-WITH-AES-256-CBC-SHA",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -627,7 +627,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_AES_256_CCM,
    "TLS-RSA-WITH-AES-256-CCM",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -635,7 +635,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_AES_256_CCM_8,
    "TLS-RSA-WITH-AES-256-CCM-8",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_RSA,
    CIPHERSUITE_FLAG_SHORT_TAG,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -643,7 +643,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_AES_128_CCM,
    "TLS-RSA-WITH-AES-128-CCM",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -651,7 +651,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_AES_128_CCM_8,
    "TLS-RSA-WITH-AES-128-CCM-8",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_RSA,
    CIPHERSUITE_FLAG_SHORT_TAG,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -659,7 +659,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
    "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -667,7 +667,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
     "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256",
-    GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+    GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
     KEY_EXCHANGE_RSA,
     0,
     TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -675,7 +675,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
    "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -683,7 +683,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
    "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -691,7 +691,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,
    "TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -699,7 +699,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,
    "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -707,7 +707,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_WITH_3DES_EDE_CBC_SHA,
    "TLS-RSA-WITH-3DES-EDE-CBC-SHA",
-   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -715,7 +715,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
    "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_ECDH_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -723,7 +723,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
    "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_ECDH_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -731,7 +731,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
    "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDH_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -739,7 +739,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
    "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDH_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -747,7 +747,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
    "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDH_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -755,7 +755,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
    "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDH_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -763,7 +763,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
    "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDH_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -771,7 +771,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384,
    "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDH_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -779,7 +779,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
    "TLS-ECDH-RSA-WITH-CAMELLIA-128-GCM-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDH_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -787,7 +787,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
    "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDH_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -795,7 +795,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
    "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA",
-   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_ECDH_RSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -803,7 +803,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
    {TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
    "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_ECDH_ECDSA,
     0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -811,7 +811,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
    {TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
     "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA",
-    GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+    GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
     KEY_EXCHANGE_ECDH_ECDSA,
     0,
     TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -819,7 +819,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
    {TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
    "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDH_ECDSA,
     0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -827,7 +827,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
    "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDH_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -835,7 +835,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
    "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDH_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -843,7 +843,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
    "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDH_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -852,7 +852,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
    "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDH_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -860,7 +860,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
    "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDH_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -868,7 +868,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
    "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDH_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -876,7 +876,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
    "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDH_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -884,7 +884,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
    "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA",
-   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_ECDH_ECDSA,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -892,7 +892,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_AES_128_GCM_SHA256,
    "TLS-PSK-WITH-AES-128-GCM-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -900,7 +900,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_AES_256_GCM_SHA384,
    "TLS-PSK-WITH-AES-256-GCM-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -908,7 +908,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_AES_128_CBC_SHA256,
    "TLS-PSK-WITH-AES-128-CBC-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -916,7 +916,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_AES_256_CBC_SHA384,
    "TLS-PSK-WITH-AES-256-CBC-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -924,7 +924,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_AES_128_CBC_SHA,
    "TLS-PSK-WITH-AES-128-CBC-SHA",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -932,7 +932,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_AES_256_CBC_SHA,
    "TLS-PSK-WITH-AES-256-CBC-SHA",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -940,7 +940,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_AES_256_CCM,
    "TLS-PSK-WITH-AES-256-CCM",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -948,7 +948,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_AES_256_CCM_8,
    "TLS-PSK-WITH-AES-256-CCM-8",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_PSK,
    CIPHERSUITE_FLAG_SHORT_TAG,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -956,7 +956,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_AES_128_CCM,
    "TLS-PSK-WITH-AES-128-CCM",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -964,7 +964,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_AES_128_CCM_8,
    "TLS-PSK-WITH-AES-128-CCM-8",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_PSK,
    CIPHERSUITE_FLAG_SHORT_TAG,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -972,7 +972,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
    "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -980,7 +980,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
    "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -988,7 +988,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,
    "TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -996,7 +996,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,
    "TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -1004,7 +1004,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_PSK_WITH_3DES_EDE_CBC_SHA,
    "TLS-PSK-WITH-3DES-EDE-CBC-SHA",
-   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1012,7 +1012,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
    "TLS-DHE-PSK-WITH-AES-128-GCM-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -1020,7 +1020,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
    "TLS-DHE-PSK-WITH-AES-256-GCM-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_DHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -1028,7 +1028,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
    "TLS-DHE-PSK-WITH-AES-128-CBC-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1036,7 +1036,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
    "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_DHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1044,7 +1044,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
    "TLS-DHE-PSK-WITH-AES-128-CBC-SHA",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_DHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1052,7 +1052,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
    "TLS-DHE-PSK-WITH-AES-256-CBC-SHA",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_DHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1060,7 +1060,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_AES_256_CCM,
    "TLS-DHE-PSK-WITH-AES-256-CCM",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -1068,7 +1068,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_AES_256_CCM_8,
    "TLS-DHE-PSK-WITH-AES-256-CCM-8",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_PSK,
    CIPHERSUITE_FLAG_SHORT_TAG,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -1076,7 +1076,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_AES_128_CCM,
    "TLS-DHE-PSK-WITH-AES-128-CCM",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -1084,7 +1084,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_AES_128_CCM_8,
    "TLS-DHE-PSK-WITH-AES-128-CCM-8",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_PSK,
    CIPHERSUITE_FLAG_SHORT_TAG,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -1092,7 +1092,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
    "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1100,7 +1100,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
    "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_DHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1108,7 +1108,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256,
    "TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_DHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -1116,7 +1116,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384,
    "TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_DHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -1124,7 +1124,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
    "TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA",
-   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_DHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1132,7 +1132,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
    "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -1140,7 +1140,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
    "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -1148,7 +1148,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
    "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_ECDHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -1156,7 +1156,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
    "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_ECDHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -1164,7 +1164,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
    "TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_ECDHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -1172,7 +1172,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
    "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_ECDHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -1180,7 +1180,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
    "TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA",
-   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_ECDHE_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_1,
@@ -1188,7 +1188,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
    "TLS-RSA-PSK-WITH-AES-128-GCM-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_RSA_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -1196,7 +1196,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
    "TLS-RSA-PSK-WITH-AES-256-GCM-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_RSA_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -1204,7 +1204,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
    "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_RSA_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1212,7 +1212,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
    "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_RSA_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1220,7 +1220,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
    "TLS-RSA-PSK-WITH-AES-128-CBC-SHA",
-   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_RSA_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1228,7 +1228,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
    "TLS-RSA-PSK-WITH-AES-256-CBC-SHA",
-   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_RSA_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1236,7 +1236,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
    "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_RSA_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1244,7 +1244,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
    "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_RSA_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1252,7 +1252,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,
    "TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256",
-   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA256,
+   GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA256,
    KEY_EXCHANGE_RSA_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -1260,7 +1260,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,
    "TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384",
-   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MD_SHA384,
+   GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_GCM, GCRY_MAC_HMAC_SHA384,
    KEY_EXCHANGE_RSA_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_3,
@@ -1268,7 +1268,7 @@ static const struct _ntbtls_ciphersuite_s ciphersuite_definitions[] = {
 
   {TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
    "TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA",
-   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MD_SHA1,
+   GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_MAC_HMAC_SHA1,
    KEY_EXCHANGE_RSA_PSK,
    0,
    TLS_MAJOR_VERSION_3, TLS_MINOR_VERSION_0,
@@ -1294,13 +1294,19 @@ _ntbtls_ciphersuite_list (void)
   //       and we need to protect this with a mutex.
   if (!supported_init)
     {
+      ciphersuite_t suite;
       int i, j;
 
       for (i=j=0; (ciphersuite_preference[i]
                    && j < DIM(ciphersuite_definitions)-1); i++)
         {
-          if (_ntbtls_ciphersuite_from_id (ciphersuite_preference[i]))
-            supported_ciphersuites[j++] = ciphersuite_preference[i];
+          if ((suite = _ntbtls_ciphersuite_from_id (ciphersuite_preference[i])))
+            {
+              /*FIXME: GCM and CCM are not yet ready for us - disable.  */
+              if (suite->ciphermode != GCRY_CIPHER_MODE_GCM
+                 && suite->ciphermode != GCRY_CIPHER_MODE_CCM)
+                supported_ciphersuites[j++] = ciphersuite_preference[i];
+            }
         }
       supported_ciphersuites[j] = 0;
 
@@ -1333,7 +1339,18 @@ _ntbtls_ciphersuite_get_name (int suite_id)
   return suite? suite->name : "unknown";
 }
 
-md_algo_t
+
+cipher_algo_t
+_ntbtls_ciphersuite_get_cipher (ciphersuite_t suite, cipher_mode_t *r_mode)
+{
+  if (!suite)
+    return 0;
+  *r_mode = suite->ciphermode;
+  return suite->cipher;
+}
+
+
+mac_algo_t
 _ntbtls_ciphersuite_get_mac (ciphersuite_t suite)
 {
   return suite? suite->mac : 0;
@@ -1347,6 +1364,13 @@ _ntbtls_ciphersuite_get_kex (ciphersuite_t suite)
 }
 
 
+unsigned int
+_ntbtls_ciphersuite_get_flags (ciphersuite_t suite)
+{
+  return suite? suite->flags : 0;
+}
+
+
 pk_algo_t
 _ntbtls_ciphersuite_get_sig_pk_alg (ciphersuite_t suite)
 {
index f47b91a..8adae48 100644 (file)
@@ -202,8 +202,11 @@ ciphersuite_t _ntbtls_ciphersuite_from_id (int suite_id);
 
 const char *_ntbtls_ciphersuite_get_name (int suite_id);
 
-md_algo_t _ntbtls_ciphersuite_get_mac (ciphersuite_t suite);
+cipher_algo_t _ntbtls_ciphersuite_get_cipher (ciphersuite_t suite,
+                                              cipher_mode_t *r_mode);
+mac_algo_t _ntbtls_ciphersuite_get_mac (ciphersuite_t suite);
 key_exchange_type_t _ntbtls_ciphersuite_get_kex (ciphersuite_t suite);
+unsigned int _ntbtls_ciphersuite_get_flags (ciphersuite_t suite);
 pk_algo_t _ntbtls_ciphersuite_get_sig_pk_alg (ciphersuite_t suite);
 int _ntbtls_ciphersuite_version_ok (ciphersuite_t suite,
                                     int min_minor_ver, int max_minor_ver);
index 9fe53ed..daf1103 100644 (file)
 #ifndef NTBTLS_CONTEXT_H
 #define NTBTLS_CONTEXT_H
 
-#include <gcrypt.h>
 #include <zlib.h>
 
 
 typedef enum gcry_md_algos md_algo_t;
+typedef enum gcry_mac_algos mac_algo_t;
 typedef enum gcry_cipher_algos cipher_algo_t;
 typedef enum gcry_cipher_modes cipher_mode_t;
 typedef enum gcry_pk_algos pk_algo_t;
@@ -114,6 +114,13 @@ typedef struct x509_crl_s *x509_crl_t;
 
 
 /*
+ * Object to hold an DHM context.
+ */
+struct dhm_context_s;
+typedef struct dhm_context_s *dhm_context_t;
+
+
+/*
  * This structure is used for storing current session data.
  */
 struct _ntbtls_session_s
@@ -161,16 +168,18 @@ struct _ntbtls_transform_s
   size_t minlen;                /*!<  min. ciphertext length  */
   size_t ivlen;                 /*!<  IV length               */
   size_t fixed_ivlen;           /*!<  Fixed part of IV (AEAD) */
-  size_t maclen;                /*!<  MAC length              */
+  size_t maclen;                /* MAC length in bytes        */
 
   unsigned char iv_enc[16];     /*!<  IV (encryption)         */
   unsigned char iv_dec[16];     /*!<  IV (decryption)         */
 
-  gcry_md_hd_t md_ctx_enc;      /*!<  MAC (encryption)        */
-  gcry_md_hd_t md_ctx_dec;      /*!<  MAC (decryption)        */
+  gcry_mac_hd_t mac_ctx_enc;    /* MAC (encryption)           */
+  gcry_mac_hd_t mac_ctx_dec;    /* MAC (decryption)           */
 
-  gcry_cipher_hd_t cipher_ctx_enc; /*!<  encryption context      */
-  gcry_cipher_hd_t cipher_ctx_dec; /*!<  decryption context      */
+  gcry_cipher_hd_t cipher_ctx_enc; /* Encryption context.     */
+  cipher_mode_t    cipher_mode_enc;/* Mode for encryption.    */
+  gcry_cipher_hd_t cipher_ctx_dec; /* Decryption context.     */
+  cipher_mode_t    cipher_mode_dec;/* Mode for encryption.    */
 
   /*
    * Session specific compression layer
@@ -206,7 +215,7 @@ struct _ntbtls_handshake_params_s
   int sig_alg;                  /*!<  Hash algorithm for signature   */
   int cert_type;                /*!<  Requested cert type            */
   int verify_sig_alg;           /*!<  Signature algorithm for verify */
-  /*dhm_context*/void* dhm_ctx;          /*!<  DHM key exchange        */
+  dhm_context_t dhm_ctx;        /* DHM key exchange info.   */
   /*ecdh_context*/void* ecdh_ctx;        /*!<  ECDH key exchange       */
   const /*ecp_curve_info*/void **curves;/*!<  Supported elliptic curves */
   /**
@@ -222,14 +231,15 @@ struct _ntbtls_handshake_params_s
   /*
    * Checksum contexts
    */
-  gcry_md_hd_t fin_sha256;
-  gcry_md_hd_t fin_sha512;
+  gcry_md_hd_t fin_sha256;     /* Checksum of all handshake messages.  */
+  gcry_md_hd_t fin_sha512;     /* Ditto.  */
 
   void (*update_checksum) (ntbtls_t, const unsigned char *, size_t);
   void (*calc_verify) (ntbtls_t, unsigned char *);
   void (*calc_finished) (ntbtls_t, unsigned char *, int);
-  int (*tls_prf) (const unsigned char *, size_t, const char *,
-                  const unsigned char *, size_t, unsigned char *, size_t);
+  gpg_error_t (*tls_prf) (const unsigned char *, size_t, const char *,
+                          const unsigned char *, size_t, unsigned char *,
+                          size_t);
 
   size_t pmslen;                /*!<  premaster length        */
 
index 56466af..e5fc2b0 100644 (file)
 
 #include "ntbtls-int.h"
 
+static int debug_level;
+static const char *debug_prefix;
+static estream_t debug_stream;
+
+
+void
+_ntbtls_set_debug (int level, const char *prefix, gpgrt_stream_t stream)
+{
+  static char *debug_prefix_buffer;
+
+  debug_prefix = "ntbtls";
+  if (prefix)
+    {
+      free (debug_prefix_buffer);
+      debug_prefix_buffer = malloc (strlen (prefix));
+      if (debug_prefix_buffer)
+        debug_prefix = debug_prefix_buffer;
+    }
+
+  debug_stream = stream? stream : es_stderr;
+
+  debug_level = level > 0? level : 0;
+}
+
+
 
 /* FIXME: For now we print to stderr.  */
 void
@@ -32,7 +57,8 @@ _ntbtls_debug_msg (int level, const char *format, ...)
   va_list arg_ptr;
   int saved_errno;
 
-  (void)level;
+  if (!debug_level || level > debug_level)
+    return;
 
   saved_errno = errno;
   va_start (arg_ptr, format);
@@ -50,6 +76,9 @@ _ntbtls_debug_bug (const char *file, int line)
 {
   const char *s;
 
+  if (!debug_level)
+    return;
+
   s = strrchr (file, '/');
   if (s)
     file = s + 1;
@@ -60,19 +89,42 @@ _ntbtls_debug_bug (const char *file, int line)
 void
 _ntbtls_debug_ret (int level, const char *name, gpg_error_t err)
 {
+  if (!debug_level || level > debug_level)
+    return;
+
   if (err)
-    _ntbtls_debug_msg (level, "%s returned %s <%s>\n",
+    _ntbtls_debug_msg (level, "%s returned: %s <%s>\n",
                        name, gpg_strerror (err), gpg_strsource (err));
   else
-    _ntbtls_debug_msg (level, "%s returned success\n", name);
+    _ntbtls_debug_msg (level, "%s returned: success\n", name);
 }
 
 
 void
 _ntbtls_debug_buf (int level, const char *text, const void *buf, size_t len)
 {
-  (void)level;
+  if (!debug_level || level > debug_level)
+    return;
 
-  gpgrt_fputs ("ntbtls: ", es_stderr);
   gcry_log_debughex (text, buf, len);
 }
+
+
+void
+_ntbtls_debug_mpi (int level, const char *text, gcry_mpi_t a)
+{
+  if (!debug_level || level > debug_level)
+    return;
+
+  gcry_log_debugmpi (text, a);
+}
+
+
+void
+_ntbtls_debug_sxp (int level, const char *text, gcry_sexp_t a)
+{
+  if (!debug_level || level > debug_level)
+    return;
+
+  gcry_log_debugsxp (text, a);
+}
diff --git a/src/dhm.c b/src/dhm.c
new file mode 100644 (file)
index 0000000..28feb9f
--- /dev/null
+++ b/src/dhm.c
@@ -0,0 +1,303 @@
+/* dhm.c - Diffie-Hellman-Merkle key exchange
+ * Copyright (C) 2014 g10 Code GmbH
+ *
+ * This file is part of NTBTLS
+ *
+ * NTBTLS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NTBTLS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ksba.h>
+
+#include "ntbtls-int.h"
+
+
+/* While running the validation function we need to keep track of the
+   certificates and the validation outcome of each.  We use this type
+   for it.  */
+struct dhm_context_s
+{
+  gcry_mpi_t dh_p;  /* The prime modulus used for the DH operation.  */
+  gcry_mpi_t dh_g;  /* The generator used for the DH operation.      */
+  gcry_mpi_t dh_Gy; /* The peer's DH public value (g^y mod p).  The
+                       value has been checked to fulfill the size
+                       requirements.                                 */
+  gcry_mpi_t dh_x;  /* Our secret.                                   */
+  gcry_mpi_t dh_Gx; /* Our own DH public value (g^x mod p).          */
+};
+
+
+
+/* Create a new DHM context.  */
+gpg_error_t
+_ntbtls_dhm_new (dhm_context_t *r_dhm)
+{
+  dhm_context_t dhm;
+
+  *r_dhm = NULL;
+
+  dhm = calloc (1, sizeof *dhm);
+  if (!dhm)
+    return gpg_error_from_syserror ();
+
+  *r_dhm = dhm;
+
+  return 0;
+}
+
+
+/* Release a DHM context.  */
+void
+_ntbtls_dhm_release (dhm_context_t dhm)
+{
+  if (!dhm)
+    return;
+  gcry_mpi_release (dhm->dh_p);
+  gcry_mpi_release (dhm->dh_g);
+  gcry_mpi_release (dhm->dh_Gy);
+  gcry_mpi_release (dhm->dh_x);
+  gcry_mpi_release (dhm->dh_Gx);
+  free (dhm);
+}
+
+
+static gpg_error_t
+read_mpi (const unsigned char *data, size_t datalen,
+          gcry_mpi_t *r_mpi, size_t *r_nscanned)
+{
+  size_t n;
+
+  if (datalen < 2)
+    return gpg_error (GPG_ERR_TOO_SHORT);
+  n = ((data[0] << 8) | data[1]);
+  data += 2;
+  datalen -= 2;
+  if (n > datalen)
+    return gpg_error (GPG_ERR_TOO_LARGE);
+  *r_nscanned = 2 + n;
+  return gcry_mpi_scan (r_mpi, GCRYMPI_FMT_USG, data, n, NULL);
+}
+
+
+
+/* Parse the TLS ServerDHParams and store it in DHM.  DER is the
+ * buffer with the params of length DERLEN.  The number of actual
+ * parsed bytes is stored at R_NPARSED.  */
+gpg_error_t
+_ntbtls_dhm_read_params (dhm_context_t dhm, const void *_der, size_t derlen,
+                         size_t *r_nparsed)
+{
+  gpg_error_t err;
+  const unsigned char *der = _der;
+  size_t n;
+  gcry_mpi_t a = NULL;
+
+  if (r_nparsed)
+    *r_nparsed = 0;
+
+  if (!dhm || !der)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  gcry_mpi_release (dhm->dh_p);  dhm->dh_p = NULL;
+  gcry_mpi_release (dhm->dh_g);  dhm->dh_g = NULL;
+  gcry_mpi_release (dhm->dh_Gy); dhm->dh_Gy = NULL;
+
+  /*   struct {
+   *       opaque dh_p<1..2^16-1>;
+   *       opaque dh_g<1..2^16-1>;
+   *       opaque dh_Ys<1..2^16-1>;
+   *   } ServerDHParams;
+   */
+  err = read_mpi (der, derlen, &dhm->dh_p, &n);
+  if (err)
+    goto leave;
+  debug_mpi (3, "DHM  p", dhm->dh_p);
+  if (r_nparsed)
+    *r_nparsed += n;
+  der += n;
+  derlen -= n;
+
+  err = read_mpi (der, derlen, &dhm->dh_g, &n);
+  if (err)
+    goto leave;
+  debug_mpi (3, "DHM  g", dhm->dh_g);
+  if (r_nparsed)
+    *r_nparsed += n;
+  der += n;
+  derlen -= n;
+
+  err = read_mpi (der, derlen, &dhm->dh_Gy, &n);
+  if (err)
+    goto leave;
+  debug_mpi (3, "DHM Ys", dhm->dh_Gy);
+  if (r_nparsed)
+    *r_nparsed += n;
+
+  /* Check for: 2 <= Ys <= P - 2.  */
+  if (gcry_mpi_cmp_ui (dhm->dh_Gy, 2) < 0)
+    {
+      err = gpg_error (GPG_ERR_INV_VALUE);
+      goto leave;
+    }
+  a = gcry_mpi_new (0);
+  gcry_mpi_sub_ui (a, dhm->dh_p, 2);
+  if (gcry_mpi_cmp (dhm->dh_Gy, a) > 0)
+    {
+      err = gpg_error (GPG_ERR_INV_VALUE);
+      goto leave;
+    }
+
+  err = 0;
+
+ leave:
+  gcry_mpi_release (a);
+  if (err)
+    {
+      gcry_mpi_release (dhm->dh_p);  dhm->dh_p = NULL;
+      gcry_mpi_release (dhm->dh_g);  dhm->dh_g = NULL;
+      gcry_mpi_release (dhm->dh_Gy); dhm->dh_Gy = NULL;
+    }
+
+  return err;
+}
+
+
+/* Return the size of the prime modulus in bits.  */
+unsigned int
+_ntbtls_dhm_get_nbits (dhm_context_t dhm)
+{
+  if (!dhm || !dhm->dh_p)
+    return 0;
+  return gcry_mpi_get_nbits (dhm->dh_p);
+}
+
+
+
+
+/* Create our own private value X and store G^X in OUTBUF.  OUTBUFSIZE
+   is the available length of OUTBUF.  On success the actual length of
+   OUTBUF is stored at R_OUTBUFLEN.  */
+gpg_error_t
+_ntbtls_dhm_make_public (dhm_context_t dhm,
+                         unsigned char *outbuf, size_t outbufsize,
+                         size_t *r_outbuflen)
+{
+  gpg_error_t err;
+  unsigned int nbits, nbytes;
+  size_t n;
+  gcry_mpi_t dh_pm2;
+
+  if (!dhm || !outbuf || !r_outbuflen)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  if (!dhm->dh_p)
+    return gpg_error (GPG_ERR_NOT_INITIALIZED);
+
+  nbits = gcry_mpi_get_nbits (dhm->dh_p);
+  if (nbits < 512)
+    return gpg_error (GPG_ERR_INTERNAL);  /* Ooops.  */
+  nbytes = (nbits +7)/8;
+
+  if (outbufsize < 2 + nbytes)
+    return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
+
+  if (!dhm->dh_Gx)
+    dhm->dh_Gx = gcry_mpi_new (nbits);
+
+  /* Create the random value X and make sure that 2 <= X <= P-2.
+     Because we truncate X to NBITS-1, it is highly unlikely that this
+     will ever loop for creating X.  Computing Gx is also checked that
+     it fits into the range and it is also unlikely to loop agains.
+     Thus we simply allocate a new random value if we ever need to
+     loop.  */
+  dh_pm2 = gcry_mpi_new (nbits);
+  gcry_mpi_sub_ui (dh_pm2, dhm->dh_p, 2);
+
+  if (!dhm->dh_x)
+    dhm->dh_x = gcry_mpi_snew (nbits);
+  do
+    {
+      do
+        {
+          gcry_mpi_randomize (dhm->dh_x, nbits-1, GCRY_STRONG_RANDOM);
+          gcry_mpi_clear_highbit (dhm->dh_x, nbits);
+        }
+      while (gcry_mpi_cmp_ui (dhm->dh_x, 2) < 0
+             || gcry_mpi_cmp (dhm->dh_x, dh_pm2) > 0);
+
+      gcry_mpi_powm (dhm->dh_Gx, dhm->dh_g, dhm->dh_x, dhm->dh_p);
+    }
+  while (gcry_mpi_cmp_ui (dhm->dh_Gx, 2) < 0
+         || gcry_mpi_cmp (dhm->dh_Gx, dh_pm2) > 0);
+
+  gcry_mpi_release (dh_pm2);
+
+  debug_mpi (4, "DHM  x", dhm->dh_x);
+  debug_mpi (3, "DHM Gx", dhm->dh_Gx);
+
+  outbuf[0] = nbytes >> 8;
+  outbuf[1] = nbytes;
+  err = gcry_mpi_print (GCRYMPI_FMT_USG, outbuf+2,outbufsize-2, &n, dhm->dh_Gx);
+  if (err)
+    return err;
+
+  *r_outbuflen = 2 + n;
+  return 0;
+}
+
+
+/* Derive the shared secret (G^Y)^X mod P and store it in OUTBUF.
+   OUTBUFSIZE is the available length of OUTBUF.  On success the
+   actual length of OUTBUF is stored at R_OUTBUFLEN.   */
+gpg_error_t
+_ntbtls_dhm_calc_secret (dhm_context_t dhm,
+                         unsigned char *outbuf, size_t outbufsize,
+                         size_t *r_outbuflen)
+{
+  gpg_error_t err;
+  unsigned int nbits, nbytes;
+  size_t n;
+  gcry_mpi_t dh_Gyx;
+
+  if (!dhm || !outbuf || !r_outbuflen)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  if (!dhm->dh_p || !dhm->dh_x)
+    return gpg_error (GPG_ERR_NOT_INITIALIZED);
+
+  nbits = gcry_mpi_get_nbits (dhm->dh_p);
+  if (nbits < 512)
+    return gpg_error (GPG_ERR_INTERNAL);  /* Ooops.  */
+  nbytes = (nbits +7)/8;
+
+  if (outbufsize < nbytes)
+    return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
+
+  //FIXME: Add blinding
+  dh_Gyx = gcry_mpi_new (nbits);
+  gcry_mpi_powm (dh_Gyx, dhm->dh_Gy, dhm->dh_x, dhm->dh_p);
+
+  debug_mpi (3, "DHMGyx", dh_Gyx);
+
+  err = gcry_mpi_print (GCRYMPI_FMT_USG, outbuf, outbufsize, &n, dh_Gyx);
+  gcry_mpi_release (dh_Gyx);
+  if (err)
+    return err;
+
+  *r_outbuflen = n;
+  return 0;
+}
index 44163ef..e97f20c 100644 (file)
@@ -21,6 +21,9 @@
 
 NTBTLS_1.0 {
   global:
+    ntbtls_check_version;
+    ntbtls_set_debug;
+
     ntbtls_new;
     ntbtls_release;
     ntbtls_set_transport;
index 34e72c3..147366f 100644 (file)
 #include <string.h>
 #include <stdarg.h>
 
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
 #include "ntbtls.h"
 
 #define PGMNAME "ntbtls-cli"
@@ -102,20 +109,98 @@ info (const char *format, ...)
 }
 
 
+\f
+static int
+connect_server (const char *server, unsigned short port)
+{
+  gpg_error_t err;
+  int sock = -1;
+  struct sockaddr_in addr;
+  struct hostent *host;
+
+  addr.sin_family = AF_INET;
+  addr.sin_port = htons (port);
+  host = gethostbyname ((char*)server);
+  if (!host)
+    {
+      err = gpg_error_from_syserror ();
+      fail ("host '%s' not found: %s\n", server, gpg_strerror (err));
+      return -1;
+    }
+
+  addr.sin_addr = *(struct in_addr*)host->h_addr;
+
+  sock = socket (AF_INET, SOCK_STREAM, 0);
+  if (sock == -1)
+    {
+      err = gpg_error_from_syserror ();
+      die ("error creating socket: %s\n", gpg_strerror (err));
+      return -1;
+    }
+
+  if (connect (sock, (struct sockaddr *)&addr, sizeof addr) == -1)
+    {
+      err = gpg_error_from_syserror ();
+      fail ("error connecting '%s': %s\n", server, gpg_strerror (err));
+      close (sock);
+      return -1;
+    }
+
+  return sock;
+}
+
+
+static int
+connect_estreams (const char *server, estream_t *r_in, estream_t *r_out)
+{
+  gpg_error_t err;
+  int sock;
+
+  *r_in = *r_out = NULL;
+
+  sock = connect_server (server, 8443);
+  if (!sock == -1)
+    return gpg_error (GPG_ERR_GENERAL);
+  *r_in = es_fdopen_nc (sock, "rb");
+  if (!*r_in)
+    {
+      err = gpg_error_from_syserror ();
+      close (sock);
+      return err;
+    }
+  *r_out = es_fdopen (sock, "wb");
+  if (!*r_out)
+    {
+      err = gpg_error_from_syserror ();
+      es_fclose (*r_in);
+      *r_in = NULL;
+      close (sock);
+      return err;
+    }
+
+  return 0;
+}
+
 
 \f
 static void
-simple_client (void)
+simple_client (const char *server)
 {
   gpg_error_t err;
   ntbtls_t tls;
+  estream_t inbound, outbound;
 
   err = ntbtls_new (&tls, NTBTLS_CLIENT);
   if (err)
     die ("ntbtls_init failed: %s <%s>\n",
          gpg_strerror (err), gpg_strsource (err));
 
-  err = ntbtls_set_transport (tls, es_stdin, es_stdout);
+  err = connect_estreams (server, &inbound, &outbound);
+  if (err)
+    die ("error connecting server: %s <%s>\n",
+         gpg_strerror (err), gpg_strsource (err));
+
+  err = ntbtls_set_transport (tls, inbound, outbound);
   if (err)
     die ("ntbtls_set_transport failed: %s <%s>\n",
          gpg_strerror (err), gpg_strsource (err));
@@ -134,6 +219,8 @@ simple_client (void)
   info ("handshake done");
 
   ntbtls_release (tls);
+  es_fclose (inbound);
+  es_fclose (outbound);
 }
 
 
@@ -142,6 +229,7 @@ int
 main (int argc, char **argv)
 {
   int last_argc = -1;
+  int debug_level = 0;
 
   if (argc)
     { argc--; argv++; }
@@ -153,15 +241,41 @@ main (int argc, char **argv)
           argc--; argv++;
           break;
         }
+      else if (!strcmp (*argv, "--version"))
+        {
+          printf ("%s\n", ntbtls_check_version (NULL));
+          if (verbose)
+            printf ("%s", ntbtls_check_version ("\001\001"));
+          return 0;
+        }
       else if (!strcmp (*argv, "--verbose"))
         {
           verbose = 1;
           argc--; argv++;
         }
-      else if (strncmp (*argv, "--", 2))
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose = 1;
+          argc--; argv++;
+          if (argc)
+            {
+              debug_level = atoi (*argv);
+              argc--; argv++;
+            }
+          else
+            debug_level = 1;
+        }
+      else if (!strncmp (*argv, "--", 2) && (*argv)[2])
         die ("Invalid option '%s'\n", *argv);
     }
 
-  simple_client ();
+  if (!ntbtls_check_version (PACKAGE_VERSION))
+    die ("NTBTLS library too old (need %s, have %s)\n",
+         PACKAGE_VERSION, ntbtls_check_version (NULL));
+
+  if (debug_level)
+    ntbtls_set_debug (debug_level, NULL, NULL);
+
+  simple_client (argc? *argv : "localhost");
   return 0;
 }
index a95fab9..2184ae9 100644 (file)
@@ -24,6 +24,8 @@
 #error ntbtls.h already included
 #endif
 
+#include <gcrypt.h>
+
 #include "ntbtls.h"
 #include "util.h"
 
@@ -73,6 +75,8 @@
 /* Lifetime of session tickets in seconds.  */
 #define TLS_DEFAULT_TICKET_LIFETIME  86400
 
+/* Maximum size of a MAC.  */
+#define TLS_MAX_MAC_SIZE   48
 
 
 /*
@@ -274,6 +278,9 @@ tls_own_cert (ntbtls_t tls)
  * Prototypes
  */
 
+/*-- util.c --*/
+const char *_ntbtls_check_version (const char *req_version);
+
 /*-- protocol.c --*/
 gpg_error_t _ntbtls_fetch_input (ntbtls_t tls, size_t nb_want);
 gpg_error_t _ntbtls_flush_output (ntbtls_t tls);
@@ -321,6 +328,14 @@ gpg_error_t _ntbtls_handshake_server_step (ntbtls_t tls);
 /*-- protocol-cli.c --*/
 gpg_error_t _ntbtls_handshake_client_step (ntbtls_t tls);
 
+
+/*-- pkglue.c --*/
+gpg_error_t _ntbtls_pk_verify (x509_cert_t chain,
+                               pk_algo_t pk_alg, md_algo_t md_alg,
+                               const unsigned char *hash, size_t hashlen,
+                               const unsigned char *sig, size_t siglen);
+
+
 /*-- x509.c --*/
 
 /*
@@ -345,6 +360,7 @@ gpg_error_t _ntbtls_x509_append_cert (x509_cert_t cert,
                                       const void *der, size_t derlen);
 const unsigned char *_ntbtls_x509_get_cert (x509_cert_t cert, int idx,
                                             size_t *r_derlen);
+gpg_error_t _ntbtls_x509_get_pk (x509_cert_t cert, int idx, gcry_sexp_t *r_pk);
 
 
 gpg_error_t _ntbtls_x509_verify (x509_cert_t cert, x509_cert_t trust_ca,
@@ -354,5 +370,21 @@ gpg_error_t _ntbtls_x509_verify (x509_cert_t cert, x509_cert_t trust_ca,
 int _ntbtls_x509_can_do (x509_privkey_t privkey, pk_algo_t pkalgo);
 
 
+/*-- dhm.c --*/
+gpg_error_t _ntbtls_dhm_new (dhm_context_t *r_dhm);
+void _ntbtls_dhm_release (dhm_context_t dhm);
+gpg_error_t _ntbtls_dhm_read_params (dhm_context_t dhm,
+                                     const void *der, size_t derlen,
+                                     size_t *r_nparsed);
+unsigned int _ntbtls_dhm_get_nbits (dhm_context_t dhm);
+gpg_error_t _ntbtls_dhm_make_public (dhm_context_t dhm,
+                                     unsigned char *outbuf, size_t outbufsize,
+                                     size_t *r_outbuflen);
+gpg_error_t _ntbtls_dhm_calc_secret (dhm_context_t dhm,
+                                     unsigned char *outbuf, size_t outbufsize,
+                                     size_t *r_outbuflen);
+
+
+
 
 #endif /*NTBTLS_NTBTLS_INT_H*/
index 1b07333..ecd84b3 100644 (file)
@@ -53,9 +53,12 @@ struct _ntbtls_context_s;
 typedef struct _ntbtls_context_s *ntbtls_t;
 
 
+/* Check that the library fulfills the version requirement.  */
+const char *ntbtls_check_version (const char *req_version);
 
 /* Create a new TLS context.  */
 gpg_error_t ntbtls_new (ntbtls_t *r_tls, unsigned int flags);
+
 void        ntbtls_release (ntbtls_t tls);
 
 gpg_error_t ntbtls_set_transport (ntbtls_t tls,
@@ -70,6 +73,17 @@ gpg_error_t ntbtls_handshake (ntbtls_t tls);
 
 
 
+/*
+ * Support functions
+ */
+
+/* Enable debugging at LEVEL (> 0) using an optional PREFIX (default:
+   "ntbtls") and an optional debug stream STREAM (default: es_stderr).
+   This function is not thread-safe and shall thus be called only once
+   before any extra threads have been started.  */
+void ntbtls_set_debug (int level, const char *prefix, gpgrt_stream_t stream);
+
+
 #if 0 /* (Keep Emacsens' auto-indent happy.) */
 {
 #endif
diff --git a/src/pkglue.c b/src/pkglue.c
new file mode 100644 (file)
index 0000000..a6910db
--- /dev/null
@@ -0,0 +1,160 @@
+/* pkglue.c - Public key fucntions
+ * Copyright (C) 2014 g10 Code GmbH
+ *
+ * This file is part of NTBTLS
+ *
+ * NTBTLS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NTBTLS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ksba.h>
+
+#include "ntbtls-int.h"
+
+
+static const char *
+md_alg_string (md_algo_t md_alg)
+{
+  switch (md_alg)
+    {
+    case GCRY_MD_SHA1:   return "sha1";
+    case GCRY_MD_SHA224: return "sha224";
+    case GCRY_MD_SHA256: return "sha256";
+    case GCRY_MD_SHA384: return "sha384";
+    case GCRY_MD_SHA512: return "sha512";
+    case GCRY_MD_RMD160: return "rmd160";
+    default: return NULL;
+    }
+}
+
+
+/* Return the public key algorithm id from the S-expression PKEY.
+   FIXME: libgcrypt should provide such a function.  Note that this
+   implementation uses the names as used by libksba.  */
+static pk_algo_t
+pk_algo_from_sexp (gcry_sexp_t pkey)
+{
+  gcry_sexp_t l1, l2;
+  const char *name;
+  size_t n;
+  pk_algo_t algo;
+
+  l1 = gcry_sexp_find_token (pkey, "public-key", 0);
+  if (!l1)
+    return 0; /* Not found.  */
+  l2 = gcry_sexp_cadr (l1);
+  gcry_sexp_release (l1);
+
+  name = gcry_sexp_nth_data (l2, 0, &n);
+  if (!name)
+    algo = 0; /* Not found. */
+  else if (n==3 && !memcmp (name, "rsa", 3))
+    algo = GCRY_PK_RSA;
+  else if (n==3 && !memcmp (name, "dsa", 3))
+    algo = GCRY_PK_DSA;
+  else if (n==3 && !memcmp (name, "ecc", 3))
+    algo = GCRY_PK_ECC;
+  else if (n==13 && !memcmp (name, "ambiguous-rsa", 13))
+    algo = GCRY_PK_RSA;
+  else
+    algo = 0;
+  gcry_sexp_release (l2);
+  return algo;
+}
+
+
+gpg_error_t
+_ntbtls_pk_verify (x509_cert_t chain, pk_algo_t pk_alg, md_algo_t md_alg,
+                   const unsigned char *hash, size_t hashlen,
+                   const unsigned char *sig, size_t siglen)
+{
+  gpg_error_t err;
+  gcry_sexp_t s_pk = NULL;
+  gcry_sexp_t s_hash = NULL;
+  gcry_sexp_t s_sig = NULL;
+  const char *md_alg_str;
+
+  if (!chain ||!md_alg || !hashlen || !sig || !siglen)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  md_alg_str = md_alg_string (md_alg);
+  if (!md_alg_str)
+    return gpg_error (GPG_ERR_DIGEST_ALGO);
+
+  /* Get the public key from the first certificate.  */
+  err = _ntbtls_x509_get_pk (chain, 0, &s_pk);
+  if (err)
+    goto leave;
+
+  /* Check the Public key algorithm.  */
+  {
+    pk_algo_t alg;
+
+    alg = pk_algo_from_sexp (s_pk);
+    if (!alg)
+      err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+    else if (alg != pk_alg)
+      err = gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);  /* Does not match. */
+
+    if (err)
+      goto leave;
+  }
+
+  /* Put the hash into an s-expression.  */
+  err = gcry_sexp_build (&s_hash, NULL, "(data(flags pkcs1)(hash %s %b))",
+                         md_alg_str, (int)hashlen, hash);
+  if (err)
+    goto leave;
+
+  /* Put the signature into an s-expression. */
+  switch (pk_alg)
+    {
+    case GCRY_PK_RSA:
+      err = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%b)))",
+                             (int)siglen, sig);
+      break;
+
+    /* case GCRY_PK_DSA: */
+    /*   err = gcry_sexp_build (&s_sig, NULL, "(sig-val(dsa(r%m)(s%m)))", */
+    /*                          data[0], data[1]); */
+    /*   break; */
+
+    /* case PUBKEY_PK_ECC: */
+    /*   err = gcry_sexp_build (&s_sig, NULL, "(sig-val(ecdsa(r%m)(s%m)))", */
+    /*                          data[0], data[1]); */
+    /*   break; */
+
+    default:
+      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      break;
+    }
+  if (err)
+    goto leave;
+
+  debug_sxp (4, "sig ", s_sig);
+  debug_sxp (4, "hash", s_hash);
+  debug_sxp (4, "pk  ", s_pk);
+
+  err = gcry_pk_verify (s_sig, s_hash, s_pk);
+
+
+ leave:
+  gcry_sexp_release (s_pk);
+  gcry_sexp_release (s_hash);
+  gcry_sexp_release (s_sig);
+  return err;
+}
index eedc82c..2931e92 100644 (file)
@@ -471,7 +471,7 @@ write_client_hello (ntbtls_t tls)
   debug_msg (3, "client hello, session id len.: %d", n);
   debug_buf (3, "client hello, session id", buf + 39, n);
 
-  //FIXME: We do not have a way to set tye ciphersuites.  Thus
+  //FIXME: We do not have a way to set the ciphersuites.  Thus
   // consider to replace this with simpler code.
   ciphersuites = tls->ciphersuite_list[tls->minor_ver];
   n = 0;
@@ -1057,10 +1057,12 @@ parse_server_hello (ntbtls_t tls)
 }
 
 
-static int
-parse_server_dh_params (ntbtls_t ssl, unsigned char **p, unsigned char *end)
+static gpg_error_t
+parse_server_dh_params (ntbtls_t tls, unsigned char **p, unsigned char *end)
 {
-  int ret = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+  gpg_error_t err;
+  unsigned int nbits;
+  size_t n;
 
   /*
    * Ephemeral DH parameters:
@@ -1071,24 +1073,22 @@ parse_server_dh_params (ntbtls_t ssl, unsigned char **p, unsigned char *end)
    *     opaque dh_Ys<1..2^16-1>;
    * } ServerDHParams;
    */
-  //FIXME:
-  /* if ((ret = dhm_read_params (&ssl->handshake->dhm_ctx, p, end)) != 0) */
-  /*   { */
-  /*     debug_ret (2, "dhm_read_params", ret); */
-  /*     return (ret); */
-  /*   } */
 
-  /* if (ssl->handshake->dhm_ctx.len < 64 || ssl->handshake->dhm_ctx.len > 512) */
-  /*   { */
-  /*     debug_msg (1, "bad server key exchange message (DHM length)"); */
-  /*     return gpg_error (GPG_ERR_BAD_HS_SERVER_KEX); */
-  /*   } */
-
-  /* SSL_DEBUG_MPI (3, "DHM: P ", &ssl->handshake->dhm_ctx.P); */
-  /* SSL_DEBUG_MPI (3, "DHM: G ", &ssl->handshake->dhm_ctx.G); */
-  /* SSL_DEBUG_MPI (3, "DHM: GY", &ssl->handshake->dhm_ctx.GY); */
+  err = _ntbtls_dhm_read_params (tls->handshake->dhm_ctx, *p, end - *p, &n);
+  if (err)
+    {
+      debug_ret (2, "dhm_read_params", err);
+      return err;
+    }
+  *p += n;
+  nbits = _ntbtls_dhm_get_nbits (tls->handshake->dhm_ctx);
+  if (nbits < 512 || nbits > 4096)
+    {
+      debug_msg (1, "bad server key exchange message (DHM length: %u)", nbits);
+      return gpg_error (GPG_ERR_BAD_HS_SERVER_KEX);
+    }
 
-  return (ret);
+  return 0;
 }
 
 
@@ -1511,23 +1511,15 @@ parse_server_key_exchange (ntbtls_t tls)
       debug_buf (3, "parameters hash", hash, hashlen);
 
 
-      //FIXME:
       /*
        * Verify signature
        */
-      /* Check that the indicated PK algorithm matches the provided key.  */
-      /* if (!pk_can_do (&tls->session_negotiate->peer_chain->pk, pk_alg)) */
-      /*   { */
-      /*     debug_msg (1, "bad server key exchange message"); */
-      /*     return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); */
-      /*   } */
 
-      /* if ((ret = pk_verify (&tls->session_negotiate->peer_chain->pk, */
-      /*                       md_alg, hash, hashlen, p, sig_len)) != 0) */
-      /*   { */
-      /*     debug_ret (1, "pk_verify", ret); */
-      /*     return (ret); */
-      /*   } */
+      err = _ntbtls_pk_verify (tls->session_negotiate->peer_chain,
+                               pk_alg, md_alg, hash, hashlen, p, sig_len);
+      debug_ret (1, "pk_verify", err);
+      if (err)
+        return err;
     }
 
  leave:
@@ -1689,6 +1681,7 @@ parse_server_hello_done (ntbtls_t tls)
   if (!tls->record_read)
     {
       err = _ntbtls_read_record (tls);
+      if (err)
         {
           debug_ret (1, "read_record", err);
           return err;
@@ -1730,39 +1723,27 @@ write_client_key_exchange (ntbtls_t tls)
     {
       /*
        * DHM key exchange -- send G^X mod P
-       */
-      n = 0; //FIXME: tls->handshake->dhm_ctx.len;
-
-      tls->out_msg[4] = (unsigned char) (n >> 8);
-      tls->out_msg[5] = (unsigned char) (n);
-      i = 6;
-
-      /* err = dhm_make_public (&tls->handshake->dhm_ctx, */
-      /*                        (int) mpi_size (&tls->handshake->dhm_ctx.P), */
-      /*                        &tls->out_msg[i], n, tls->f_rng, tls->p_rng); */
-      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+       *
+       * We don't have the remaining size of the buffer available,
+       * thus we use a value which will always fit into our buffer. */
+      i = 4;
+      err = _ntbtls_dhm_make_public (tls->handshake->dhm_ctx,
+                                     tls->out_msg + i, 514, &n);
       if (err)
         {
           debug_ret (1, "dhm_make_public", err);
           return err;
         }
 
-      /* SSL_DEBUG_MPI (3, "DHM: X ", &ssl->handshake->dhm_ctx.X); */
-      /* SSL_DEBUG_MPI (3, "DHM: GX", &tls->handshake->dhm_ctx.GX); */
-
-      tls->handshake->pmslen = TLS_PREMASTER_SIZE;
-
-      /* err = dhm_calc_secret (&tls->handshake->dhm_ctx, */
-      /*                        tls->handshake->premaster, */
-      /*                        &tls->handshake->pmslen); */
-      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      err = _ntbtls_dhm_calc_secret (tls->handshake->dhm_ctx,
+                                     tls->handshake->premaster,
+                                     TLS_PREMASTER_SIZE,
+                                     &tls->handshake->pmslen);
       if (err)
         {
           debug_ret (1, "dhm_calc_secret", err);
           return err;
         }
-
-      /* SSL_DEBUG_MPI (3, "DHM: K ", &tls->handshake->dhm_ctx.K); */
     }
   else if (kex == KEY_EXCHANGE_ECDHE_RSA
            || kex == KEY_EXCHANGE_ECDHE_ECDSA
index 6627557..1754f30 100644 (file)
 #include "ntbtls-int.h"
 #include "ciphersuites.h"
 
+
+
 static void transform_deinit (transform_t transform);
 static void session_deinit (session_t session);
 static void handshake_params_deinit (handshake_params_t handshake);
 static void ticket_keys_deinit (ticket_keys_t tkeys);
 
 static void update_checksum_sha256 (ntbtls_t, const unsigned char *, size_t);
+static void calc_verify_tls_sha256 (ntbtls_t, unsigned char *);
 static void calc_finished_tls_sha256 (ntbtls_t, unsigned char *, int);
 static void calc_verify_tls_sha384 (ntbtls_t, unsigned char *);
 static void calc_finished_tls_sha384 (ntbtls_t, unsigned char *, int);
@@ -145,443 +148,415 @@ sha_hmac (const unsigned char *key, size_t keylen,
  * Key material generation
  */
 
-static int
-tls_prf_sha256 (const unsigned char *secret, size_t slen,
-                const char *label,
-                const unsigned char *random, size_t rlen,
-                unsigned char *dstbuf, size_t dlen)
+static gpg_error_t
+do_tls_prf (const unsigned char *secret, size_t slen,
+            const char *label,
+            const unsigned char *random, size_t rlen,
+            unsigned char *dstbuf, size_t dlen,
+            size_t hashlen)
 {
   gpg_error_t err;
   size_t nb;
   size_t i, j, k;
   unsigned char tmp[128];
-  unsigned char h_i[32];
+  unsigned char h_i[64];
 
-  if (sizeof (tmp) < 32 + strlen (label) + rlen)
+  if (sizeof (tmp) < hashlen + strlen (label) + rlen)
     return gpg_error (GPG_ERR_INV_ARG);
 
   nb = strlen (label);
-  memcpy (tmp + 32, label, nb);
-  memcpy (tmp + 32 + nb, random, rlen);
+  memcpy (tmp + hashlen, label, nb);
+  memcpy (tmp + hashlen + nb, random, rlen);
   nb += rlen;
 
   /*
    * Compute P_<hash>(secret, label + random)[0..dlen]
    */
-  err = sha_hmac (secret, slen, tmp + 32, nb, tmp, 32);
+  err = sha_hmac (secret, slen, tmp + hashlen, nb, tmp, hashlen);
   if (err)
     return err;
 
-  for (i = 0; i < dlen; i += 32)
+  for (i = 0; i < dlen; i += hashlen)
     {
-      err = sha_hmac (secret, slen, tmp, 32 + nb, h_i, 32);
+      err = sha_hmac (secret, slen, tmp, hashlen + nb, h_i, hashlen);
       if (err)
         return err;
-      err = sha_hmac (secret, slen, tmp, 32, tmp, 32);
+      err = sha_hmac (secret, slen, tmp, hashlen, tmp, hashlen);
       if (err)
         return err;
 
-      k = (i + 32 > dlen) ? dlen % 32 : 32;
+      k = (i + hashlen > dlen) ? dlen % hashlen : hashlen;
 
       for (j = 0; j < k; j++)
         dstbuf[i + j] = h_i[j];
     }
 
   wipememory (tmp, sizeof (tmp));
-  wipememory (h_i, sizeof (h_i));
+  wipememory (h_i, hashlen);
 
   return 0;
 }
 
 
-static int
+static gpg_error_t
+tls_prf_sha256 (const unsigned char *secret, size_t slen,
+                const char *label,
+                const unsigned char *random, size_t rlen,
+                unsigned char *dstbuf, size_t dlen)
+{
+  return do_tls_prf (secret, slen, label, random, rlen, dstbuf, dlen, 32);
+}
+
+
+static gpg_error_t
 tls_prf_sha384 (const unsigned char *secret, size_t slen,
                 const char *label,
                 const unsigned char *random, size_t rlen,
                 unsigned char *dstbuf, size_t dlen)
 {
+  return do_tls_prf (secret, slen, label, random, rlen, dstbuf, dlen, 48);
+}
+
+
+gpg_error_t
+_ntbtls_derive_keys (ntbtls_t tls)
+{
   gpg_error_t err;
-  size_t nb;
-  size_t i, j, k;
-  unsigned char tmp[128];
-  unsigned char h_i[48];
+  unsigned char tmp[64];
+  unsigned char keyblk[256];
+  unsigned char *key1;
+  unsigned char *key2;
+  unsigned char *mac_enc;
+  unsigned char *mac_dec;
+  size_t iv_copy_len;
+  cipher_algo_t cipher;
+  cipher_mode_t ciphermode;
+  mac_algo_t mac;
+  session_t session = tls->session_negotiate;
+  transform_t transform = tls->transform_negotiate;
+  handshake_params_t handshake = tls->handshake;
+
+  debug_msg (2, "=> derive keys");
+
+  if (tls->minor_ver != TLS_MINOR_VERSION_3)
+    {
+      debug_bug ();
+      return gpg_error (GPG_ERR_INTERNAL);
+    }
 
-  if (sizeof (tmp) < 48 + strlen (label) + rlen)
-    return gpg_error (GPG_ERR_INV_ARG);
+  cipher = _ntbtls_ciphersuite_get_cipher (transform->ciphersuite,
+                                           &ciphermode);
+  if (!cipher || !ciphermode)
+    {
+      debug_msg (1, "cipher algo not found");
+      return gpg_error (GPG_ERR_INV_ARG);
+    }
 
-  nb = strlen (label);
-  memcpy (tmp + 48, label, nb);
-  memcpy (tmp + 48 + nb, random, rlen);
-  nb += rlen;
+  mac = _ntbtls_ciphersuite_get_mac (transform->ciphersuite);
+  if (!mac)
+    {
+      debug_msg (1, "mac algo not found");
+      return gpg_error (GPG_ERR_INV_ARG);
+    }
 
   /*
-   * Compute P_<hash>(secret, label + random)[0..dlen]
+   * Set appropriate PRF function and other TLS functions
    */
-  err = sha_hmac (secret, slen, tmp + 48, nb, tmp, 48);
-  if (err)
-    return err;
+  if (mac == GCRY_MAC_HMAC_SHA384)
+    {
+      handshake->tls_prf = tls_prf_sha384;
+      handshake->calc_verify = calc_verify_tls_sha384;
+      handshake->calc_finished = calc_finished_tls_sha384;
+    }
+  else
+    {
+      handshake->tls_prf = tls_prf_sha256;
+      handshake->calc_verify = calc_verify_tls_sha256;
+      handshake->calc_finished = calc_finished_tls_sha256;
+    }
 
-  for (i = 0; i < dlen; i += 48)
+  /*
+   * TLSv1+:
+   *   master = PRF( premaster, "master secret", randbytes )[0..47]
+   */
+  if (!handshake->resume)
     {
-      err = sha_hmac (secret, slen, tmp, 48 + nb, h_i, 48);
-      if (err)
-        return err;
-      err = sha_hmac (secret, slen, tmp, 48, tmp, 48);
-      if (err)
-        return err;
+      debug_buf (3, "premaster secret",
+                 handshake->premaster, handshake->pmslen);
 
-      k = (i + 48 > dlen) ? dlen % 48 : 48;
+      handshake->tls_prf (handshake->premaster, handshake->pmslen,
+                          "master secret",
+                          handshake->randbytes, 64, session->master, 48);
 
-      for (j = 0; j < k; j++)
-        dstbuf[i + j] = h_i[j];
+      wipememory (handshake->premaster, sizeof (handshake->premaster));
     }
+  else
+    debug_msg (3, "no premaster (session resumed)");
 
+  /*
+   * Swap the client and server random values.
+   */
+  memcpy (tmp, handshake->randbytes, 64);
+  memcpy (handshake->randbytes, tmp + 32, 32);
+  memcpy (handshake->randbytes + 32, tmp, 32);
   wipememory (tmp, sizeof (tmp));
-  wipememory (h_i, sizeof (h_i));
 
-  return (0);
-}
+  /*
+   *  TLSv1:
+   *    key block = PRF( master, "key expansion", randbytes )
+   */
+  handshake->tls_prf (session->master, 48,
+                      "key expansion",
+                      handshake->randbytes, 64, keyblk, 256);
 
+  debug_msg (3, "ciphersuite = %s",
+             _ntbtls_ciphersuite_get_name (session->ciphersuite));
+  debug_buf (3, "master secret", session->master, 48);
+  debug_buf (4, "random bytes", handshake->randbytes, 64);
+  debug_buf (4, "key block", keyblk, 256);
 
-gpg_error_t
-_ntbtls_derive_keys (ntbtls_t ssl)
-{
-  //FIXME:
-  /* int ret = 0; */
-  /* unsigned char tmp[64]; */
-  /* unsigned char keyblk[256]; */
-  /* unsigned char *key1; */
-  /* unsigned char *key2; */
-  /* unsigned char *mac_enc; */
-  /* unsigned char *mac_dec; */
-  /* size_t iv_copy_len; */
-  /* const cipher_info_t *cipher_info; */
-  /* const md_info_t *md_info; */
-
-  /* session_t session = ssl->session_negotiate; */
-  /* ssl_transform *transform = ssl->transform_negotiate; */
-  /* ssl_handshake_params *handshake = ssl->handshake; */
-
-  /* debug_msg (2, "=> derive keys"); */
-
-  /* cipher_info = cipher_info_from_type (transform->ciphersuite->cipher); */
-  /* if (cipher_info == NULL) */
-  /*   { */
-  /*     debug_msg (1, "cipher info for %d not found", */
-  /*                transform->ciphersuite->cipher); */
-  /*     return gpg_error (GPG_ERR_INV_ARG); */
-  /*   } */
+  wipememory (handshake->randbytes, sizeof (handshake->randbytes));
 
-  /* md_info = md_info_from_type (transform->ciphersuite->mac); */
-  /* if (md_info == NULL) */
-  /*   { */
-  /*     debug_msg (1, "md info for %d not found", */
-  /*                transform->ciphersuite->mac); */
-  /*     return gpg_error (GPG_ERR_INV_ARG); */
-  /*   } */
+  /*
+   * Determine the appropriate key, IV and MAC length.
+   */
 
-  /* /\* */
-  /*  * Set appropriate PRF function and other TLS functions */
-  /*  *\/ */
-  /* if (ssl->minor_ver == TLS_MINOR_VERSION_3 && */
-  /*     transform->ciphersuite->mac == GCRY_MD_SHA384) */
-  /*   { */
-  /*     handshake->tls_prf = tls_prf_sha384; */
-  /*     handshake->calc_verify = calc_verify_tls_sha384; */
-  /*     handshake->calc_finished = calc_finished_tls_sha384; */
-  /*   } */
-  /* else if (ssl->minor_ver == TLS_MINOR_VERSION_3) */
-  /*   { */
-  /*     handshake->tls_prf = tls_prf_sha256; */
-  /*     handshake->calc_verify = calc_verify_tls_sha256; */
-  /*     handshake->calc_finished = calc_finished_tls_sha256; */
-  /*   } */
-  /* else */
-  /*   { */
-  /*     debug_bug (); */
-  /*     return gpg_error (GPG_ERR_INTERNAL); */
-  /*   } */
+  transform->keylen = gcry_cipher_get_algo_keylen (cipher);
+  /* FIXME: Check that KEYLEN has an upper bound.  */
 
-  /* /\* */
-  /*  * TLSv1+: */
-  /*  *   master = PRF( premaster, "master secret", randbytes )[0..47] */
-  /*  *\/ */
-  /* if (handshake->resume == 0) */
-  /*   { */
-  /*     debug_buf (3, "premaster secret", handshake->premaster,handshake->pmslen); */
+  if (ciphermode == GCRY_CIPHER_MODE_GCM || ciphermode == GCRY_CIPHER_MODE_CCM)
+    {
+      transform->maclen = 0;
 
-  /*     handshake->tls_prf (handshake->premaster, handshake->pmslen, */
-  /*                         "master secret", */
-  /*                         handshake->randbytes, 64, session->master, 48); */
+      transform->ivlen = 12;
+      transform->fixed_ivlen = 4;
 
-  /*     wipememory (handshake->premaster, sizeof (handshake->premaster)); */
-  /*   } */
-  /* else */
-  /*   debug_msg (3, "no premaster (session resumed)"); */
-
-  /* /\* */
-  /*  * Swap the client and server random values. */
-  /*  *\/ */
-  /* memcpy (tmp, handshake->randbytes, 64); */
-  /* memcpy (handshake->randbytes, tmp + 32, 32); */
-  /* memcpy (handshake->randbytes + 32, tmp, 32); */
-  /* wipememory (tmp, sizeof (tmp)); */
-
-  /* /\* */
-  /*  *  TLSv1: */
-  /*  *    key block = PRF( master, "key expansion", randbytes ) */
-  /*  *\/ */
-  /* handshake->tls_prf (session->master, 48, "key expansion", */
-  /*                     handshake->randbytes, 64, keyblk, 256); */
-
-  /* debug_msg (3, "ciphersuite = %s", */
-  /*            ssl_get_ciphersuite_name (session->ciphersuite)); */
-  /* debug_buf (3, "master secret", session->master, 48); */
-  /* debug_buf (4, "random bytes", handshake->randbytes, 64); */
-  /* debug_buf (4, "key block", keyblk, 256); */
-
-  /* wipememory (handshake->randbytes, sizeof (handshake->randbytes)); */
-
-  /* /\* */
-  /*  * Determine the appropriate key, IV and MAC length. */
-  /*  *\/ */
-
-  /* transform->keylen = cipher_info->key_length / 8; */
-
-  /* if (cipher_info->mode == POLARSSL_MODE_GCM || */
-  /*     cipher_info->mode == POLARSSL_MODE_CCM) */
-  /*   { */
-  /*     transform->maclen = 0; */
+      /* Minimum length is expicit IV + tag */
+      transform->minlen =
+        (transform->ivlen
+         - transform->fixed_ivlen
+         + ((_ntbtls_ciphersuite_get_flags (transform->ciphersuite)
+             & CIPHERSUITE_FLAG_SHORT_TAG)? 8 : 16));
+    }
+  else
+    {
+      size_t blklen = gcry_cipher_get_algo_blklen (cipher);
 
-  /*     transform->ivlen = 12; */
-  /*     transform->fixed_ivlen = 4; */
+      /* Initialize HMAC contexts */
+      /* Fixme: Check whether the context may really be open.  */
+      gcry_mac_close (transform->mac_ctx_enc);
+      err = gcry_mac_open (&transform->mac_ctx_enc, mac, 0, NULL);
+      if (!err)
+        {
+          gcry_mac_close (transform->mac_ctx_dec);
+          err = gcry_mac_open (&transform->mac_ctx_dec, mac, 0, NULL);
+        }
+      if (err)
+        {
+          debug_ret (1, "gcry_mac_open", err);
+          return err;
+        }
 
-  /*     /\* Minimum length is expicit IV + tag *\/ */
-  /*     transform->minlen = transform->ivlen - transform->fixed_ivlen */
-  /*       + (transform->ciphersuite->flags & */
-  /*          POLARSSL_CIPHERSUITE_SHORT_TAG ? 8 : 16); */
-  /*   } */
-  /* else */
-  /*   { */
-  /*     int ret; */
-
-  /*     /\* Initialize HMAC contexts *\/ */
-  /*     if ((ret = md_init_ctx (&transform->md_ctx_enc, md_info)) != 0 || */
-  /*         (ret = md_init_ctx (&transform->md_ctx_dec, md_info)) != 0) */
-  /*       { */
-  /*         debug_ret (1, "md_init_ctx", ret); */
-  /*         return (ret); */
-  /*       } */
-
-  /*     /\* Get MAC length *\/ */
-  /*     transform->maclen = md_get_size (md_info); */
-
-  /*     /\* */
-  /*      * If HMAC is to be truncated, we shall keep the leftmost bytes, */
-  /*      * (rfc 6066 page 13 or rfc 2104 section 4), */
-  /*      * so we only need to adjust the length here. */
-  /*      *\/ */
-  /*     if (session->use_trunc_hmac) */
-  /*       transform->maclen = TLS_TRUNCATED_HMAC_LEN; */
-
-  /*     /\* IV length *\/ */
-  /*     transform->ivlen = cipher_info->iv_size; */
-
-  /*     /\* Minimum length *\/ */
-  /*     if (cipher_info->mode == POLARSSL_MODE_STREAM) */
-  /*       transform->minlen = transform->maclen; */
-  /*     else */
-  /*       { */
-  /*         /\* */
-  /*          * GenericBlockCipher: */
-  /*          * first multiple of blocklen greater than maclen */
-  /*          * + IV except for SSL3 and TLS 1.0 */
-  /*          *\/ */
-  /*         transform->minlen = (transform->maclen */
-  /*                              + cipher_info->block_size */
-  /*                              - transform->maclen % cipher_info->block_size); */
-
-  /*         if (ssl->minor_ver == TLS_MINOR_VERSION_2 */
-  /*             || ssl->minor_ver == TLS_MINOR_VERSION_3) */
-  /*           { */
-  /*             transform->minlen += transform->ivlen; */
-  /*           } */
-  /*         else */
-  /*           { */
-  /*             debug_bug (); */
-  /*             return gpg_error (GPG_ERR_INTERNAL); */
-  /*           } */
-  /*       } */
-  /*   } */
+      /* Get MAC length */
+      transform->maclen = gcry_mac_get_algo_maclen (mac);
+      if (transform->maclen < TLS_TRUNCATED_HMAC_LEN)
+        {
+          debug_bug ();
+          return gpg_error (GPG_ERR_BUG);
+        }
 
-  /* debug_msg (3, "keylen: %d, minlen: %d, ivlen: %d, maclen: %d", */
-  /*            transform->keylen, transform->minlen, transform->ivlen, */
-  /*            transform->maclen); */
+      /*
+       * If HMAC is to be truncated, we shall keep the leftmost bytes,
+       * (rfc 6066 page 13 or rfc 2104 section 4),
+       * so we only need to adjust the length here.
+       */
+      if (session->use_trunc_hmac)
+        transform->maclen = TLS_TRUNCATED_HMAC_LEN;
 
-  /* /\* */
-  /*  * Finally setup the cipher contexts, IVs and MAC secrets. */
-  /*  *\/ */
-  /* if (tls->is_client) */
-  /*   { */
-  /*     key1 = keyblk + transform->maclen * 2; */
-  /*     key2 = keyblk + transform->maclen * 2 + transform->keylen; */
-
-  /*     mac_enc = keyblk; */
-  /*     mac_dec = keyblk + transform->maclen; */
-
-  /*     /\* */
-  /*      * This is not used in TLS v1.1. */
-  /*      *\/ */
-  /*     iv_copy_len = (transform->fixed_ivlen) ? */
-  /*       transform->fixed_ivlen : transform->ivlen; */
-  /*     memcpy (transform->iv_enc, key2 + transform->keylen, iv_copy_len); */
-  /*     memcpy (transform->iv_dec, key2 + transform->keylen + iv_copy_len, */
-  /*             iv_copy_len); */
-  /*   } */
-  /* else */
-  /*   { */
-  /*     key1 = keyblk + transform->maclen * 2 + transform->keylen; */
-  /*     key2 = keyblk + transform->maclen * 2; */
-
-  /*     mac_enc = keyblk + transform->maclen; */
-  /*     mac_dec = keyblk; */
-
-  /*     /\* */
-  /*      * This is not used in TLS v1.1. */
-  /*      *\/ */
-  /*     iv_copy_len = (transform->fixed_ivlen) ? */
-  /*       transform->fixed_ivlen : transform->ivlen; */
-  /*     memcpy (transform->iv_dec, key1 + transform->keylen, iv_copy_len); */
-  /*     memcpy (transform->iv_enc, key1 + transform->keylen + iv_copy_len, */
-  /*             iv_copy_len); */
-  /*   } */
+      /* IV length.  According to RFC-5246, Appendix C, we shall use
+         the block length of the IV length.  */
+      transform->ivlen = blklen;
 
-  /* if (ssl->minor_ver >= TLS_MINOR_VERSION_1) */
-  /*   { */
-  /*     md_hmac_starts (&transform->md_ctx_enc, mac_enc, transform->maclen); */
-  /*     md_hmac_starts (&transform->md_ctx_dec, mac_dec, transform->maclen); */
-  /*   } */
-  /* else */
-  /*   { */
-  /*     debug_bug (); */
-  /*     return gpg_error (GPG_ERR_INTERNAL); */
-  /*   } */
+      /* Minimum length */
+      if (ciphermode == GCRY_CIPHER_MODE_STREAM)
+        transform->minlen = transform->maclen;
+      else
+        {
+          /*
+           * GenericBlockCipher:
+           * First multiple of blocklen greater than maclen
+           * + IV.
+           */
+          transform->minlen = (transform->maclen
+                               + blklen
+                               - (transform->maclen % blklen)
+                               + transform->ivlen);
+        }
+    }
 
-  /* if ((ret = cipher_init_ctx (&transform->cipher_ctx_enc, cipher_info)) != 0) */
-  /*   { */
-  /*     debug_ret (1, "cipher_init_ctx", ret); */
-  /*     return (ret); */
-  /*   } */
+  debug_msg (3, "keylen: %d, minlen: %d, ivlen: %d, maclen: %d",
+             transform->keylen, transform->minlen, transform->ivlen,
+             transform->maclen);
 
-  /* if ((ret = cipher_init_ctx (&transform->cipher_ctx_dec, cipher_info)) != 0) */
-  /*   { */
-  /*     debug_ret (1, "cipher_init_ctx", ret); */
-  /*     return (ret); */
-  /*   } */
+  /*
+   * Finally setup the cipher contexts, IVs and MAC secrets.
+   */
+  if (tls->is_client)
+    {
+      key1 = keyblk + transform->maclen * 2;
+      key2 = keyblk + transform->maclen * 2 + transform->keylen;
 
-  /* if ((ret = cipher_setkey (&transform->cipher_ctx_enc, key1, */
-  /*                           cipher_info->key_length, POLARSSL_ENCRYPT)) != 0) */
-  /*   { */
-  /*     debug_ret (1, "cipher_setkey", ret); */
-  /*     return (ret); */
-  /*   } */
+      mac_enc = keyblk;
+      mac_dec = keyblk + transform->maclen;
 
-  /* if ((ret = cipher_setkey (&transform->cipher_ctx_dec, key2, */
-  /*                           cipher_info->key_length, POLARSSL_DECRYPT)) != 0) */
-  /*   { */
-  /*     debug_ret (1, "cipher_setkey", ret); */
-  /*     return (ret); */
-  /*   } */
+      /*
+       * This is not used in TLS v1.1.  FIXME: Check and remove.
+       */
+      iv_copy_len = (transform->fixed_ivlen ?
+                     transform->fixed_ivlen : transform->ivlen);
+      memcpy (transform->iv_enc, key2 + transform->keylen, iv_copy_len);
+      memcpy (transform->iv_dec, key2 + transform->keylen + iv_copy_len,
+              iv_copy_len);
+    }
+  else
+    {
+      key1 = keyblk + transform->maclen * 2 + transform->keylen;
+      key2 = keyblk + transform->maclen * 2;
 
-  /* if (cipher_info->mode == POLARSSL_MODE_CBC) */
-  /*   { */
-  /*     if ((ret = cipher_set_padding_mode (&transform->cipher_ctx_enc, */
-  /*                                         POLARSSL_PADDING_NONE)) != 0) */
-  /*       { */
-  /*         debug_ret (1, "cipher_set_padding_mode", ret); */
-  /*         return (ret); */
-  /*       } */
-
-  /*     if ((ret = cipher_set_padding_mode (&transform->cipher_ctx_dec, */
-  /*                                         POLARSSL_PADDING_NONE)) != 0) */
-  /*       { */
-  /*         debug_ret (1, "cipher_set_padding_mode", ret); */
-  /*         return (ret); */
-  /*       } */
-  /*   } */
+      mac_enc = keyblk + transform->maclen;
+      mac_dec = keyblk;
 
-  /* wipememory (keyblk, sizeof (keyblk)); */
+      /*
+       * This is not used in TLS v1.1.  FIXME: Check and remove
+       */
+      iv_copy_len = (transform->fixed_ivlen ?
+                     transform->fixed_ivlen : transform->ivlen);
+      memcpy (transform->iv_dec, key1 + transform->keylen, iv_copy_len);
+      memcpy (transform->iv_enc, key1 + transform->keylen + iv_copy_len,
+              iv_copy_len);
+    }
 
-  /* /\* Initialize compression.  *\/ */
-  /* if (session->compression == SSL_COMPRESS_DEFLATE) */
-  /*   { */
-  /*     if (ssl->compress_buf == NULL) */
-  /*       { */
-  /*         debug_msg (3, "Allocating compression buffer"); */
-  /*         ssl->compress_buf = malloc (SSL_BUFFER_LEN); */
-  /*         if (!ssl->compress_buf) */
-  /*           { */
-  /*             err = gpg_error_from_syserror (); */
-  /*             debug_msg (1, "malloc(%d bytes) failed", SSL_BUFFER_LEN); */
-  /*             return err; */
-  /*           } */
-  /*       } */
-
-  /*     debug_msg (3, "Initializing zlib states"); */
-
-  /*     memset (&transform->ctx_deflate, 0, sizeof (transform->ctx_deflate)); */
-  /*     memset (&transform->ctx_inflate, 0, sizeof (transform->ctx_inflate)); */
-
-  /*     if (deflateInit (&transform->ctx_deflate, */
-  /*                      Z_DEFAULT_COMPRESSION) != Z_OK || */
-  /*         inflateInit (&transform->ctx_inflate) != Z_OK) */
-  /*       { */
-  /*         debug_msg (1, "Failed to initialize compression"); */
-  /*         return gpg_error (GPG_ERR_COMPR_FAILED); */
-  /*       } */
-  /*   } */
 
-  /* debug_msg (2, "<= derive keys"); */
+  if (ciphermode != GCRY_CIPHER_MODE_GCM && ciphermode != GCRY_CIPHER_MODE_CCM)
+    {
+      err = gcry_mac_setkey (transform->mac_ctx_enc,
+                             mac_enc, transform->maclen);
+      if (!err)
+        err = gcry_mac_setkey (transform->mac_ctx_dec,
+                               mac_dec, transform->maclen);
+      if (err)
+        {
+          debug_ret (1, "gcry_mac_setkey", err);
+          return err;
+        }
+    }
 
-  return (0);
-}
+  gcry_cipher_close (transform->cipher_ctx_enc);
+  err = gcry_cipher_open (&transform->cipher_ctx_enc, cipher, ciphermode, 0);
+  if (!err)
+    {
+      gcry_cipher_close (transform->cipher_ctx_dec);
+      err = gcry_cipher_open (&transform->cipher_ctx_dec, cipher, ciphermode,0);
+    }
+  if (err)
+    {
+      debug_ret (1, "gcry_cipher_open", err);
+      return err;
+    }
+  transform->cipher_mode_enc = ciphermode;
+  transform->cipher_mode_dec = ciphermode;
 
+  err = gcry_cipher_setkey (transform->cipher_ctx_enc,
+                            key1, transform->keylen);
+  if (!err)
+    err = gcry_cipher_setkey (transform->cipher_ctx_dec,
+                              key2, transform->keylen);
+  if (err)
+    {
+      debug_ret (1, "cipher_setkey", err);
+      return err;
+    }
 
-static void
-calc_verify_tls_sha256 (ntbtls_t ssl, unsigned char hash[32])
-{
-  /* sha256_context sha256; */
+  wipememory (keyblk, sizeof (keyblk));
+
+  /* Initialize compression.  */
+  if (session->compression == TLS_COMPRESS_DEFLATE)
+    {
+      /* if (tls->compress_buf == NULL) */
+      /*   { */
+      /*     deboug_msg (3, "Allocating compression buffer"); */
+      /*     ssl->compress_buf = malloc (SSL_BUFFER_LEN); */
+      /*     if (!ssl->compress_buf) */
+      /*       { */
+      /*         err = gpg_error_from_syserror (); */
+      /*         debug_msg (1, "malloc(%d bytes) failed", SSL_BUFFER_LEN); */
+      /*         return err; */
+      /*       } */
+      /*   } */
 
-  /* debug_msg (2, "=> calc verify sha256"); */
+      /* debug_msg (3, "Initializing zlib states"); */
 
-  /* memcpy (&sha256, &ssl->handshake->fin_sha256, sizeof (sha256_context)); */
-  /* sha256_finish (&sha256, hash); */
+      /* memset (&transform->ctx_deflate, 0, sizeof (transform->ctx_deflate));*/
+      /* memset (&transform->ctx_inflate, 0, sizeof (transform->ctx_inflate));*/
 
-  /* debug_buf (3, "calculated verify result", hash, 32); */
-  /* debug_msg (2, "<= calc verify"); */
+      /* if (deflateInit (&transform->ctx_deflate, */
+      /*                  Z_DEFAULT_COMPRESSION) != Z_OK || */
+      /*     inflateInit (&transform->ctx_inflate) != Z_OK) */
+        {
+          debug_msg (1, "Failed to initialize compression");
+          return gpg_error (GPG_ERR_COMPR_FAILED);
+        }
+    }
 
-  /* sha256_free (&sha256); */
+  debug_msg (2, "<= derive keys");
 
-  /* return; */
+  return 0;
 }
 
 
 static void
-calc_verify_tls_sha384 (ntbtls_t ssl, unsigned char hash[48])
+calc_verify_tls (gcry_md_hd_t md_input, md_algo_t md_alg,
+                 unsigned char *hash, size_t hashlen)
 {
-  /* sha512_context sha512; */
+  gpg_error_t err;
+  gcry_md_hd_t md;
+  char *p;
 
-  /* debug_msg (2, "=> calc verify sha384"); */
+  debug_msg (2, "=> calc verify tls sha%d", hashlen*8);
 
-  /* memcpy (&sha512, &ssl->handshake->fin_sha512, sizeof (sha512_context)); */
-  /* sha512_finish (&sha512, hash); */
+  err = gcry_md_copy (&md, md_input);
+  if (err)
+    {
+      debug_ret (1, "calc_verify_tls", err);
+      memset (hash, 0, hashlen);
+      return;
+    }
+  p = gcry_md_read (md, md_alg);
+  if (!p)
+    {
+      debug_bug ();
+      memset (hash, 0, hashlen);
+      gcry_md_close (md);
+      return;
+    }
+  memcpy (hash, p, hashlen);
+  gcry_md_close (md);
 
-  /* debug_buf (3, "calculated verify result", hash, 48); */
-  /* debug_msg (2, "<= calc verify"); */
+  debug_buf (3, "calculated verify result", hash, hashlen);
+  debug_msg (2, "<= calc verify tls sha%d", hashlen*8);
+}
 
-  /* sha512_free (&sha512); */
 
-  /* return; */
+static void
+calc_verify_tls_sha256 (ntbtls_t tls, unsigned char hash[32])
+{
+  calc_verify_tls (tls->handshake->fin_sha256, GCRY_MD_SHA256, hash, 32);
+}
+
+static void
+calc_verify_tls_sha384 (ntbtls_t tls, unsigned char hash[48])
+{
+  calc_verify_tls (tls->handshake->fin_sha512, GCRY_MD_SHA384, hash, 48);
 }
 
 
@@ -679,581 +654,572 @@ _ntbtls_psk_derive_premaster (ntbtls_t tls, key_exchange_type_t kex)
 /*
  * Encryption/decryption functions
  */
-static int
-ssl_encrypt_buf (ntbtls_t ssl)
+static gpg_error_t
+encrypt_buf (ntbtls_t tls)
 {
-  //FIXME:
-  /* size_t i; */
-  /* const cipher_mode_t mode = */
-  /*   cipher_get_cipher_mode (&ssl->transform_out->cipher_ctx_enc); */
+  gpg_error_t err;
+  size_t tmplen, i;
+  cipher_mode_t mode = tls->transform_out->cipher_mode_enc;
 
-  /* debug_msg (2, "=> encrypt buf"); */
+  debug_msg (2, "=> encrypt buf");
 
-  /* /\* */
-  /*  * Add MAC before encrypt, except for AEAD modes */
-  /*  *\/ */
-  /* if (mode != POLARSSL_MODE_GCM && mode != POLARSSL_MODE_CCM) */
-  /*   { */
-  /*     if (ssl->minor_ver >= TLS_MINOR_VERSION_1) */
-  /*       { */
-  /*         md_hmac_update (&ssl->transform_out->md_ctx_enc, ssl->out_ctr, 13); */
-  /*         md_hmac_update (&ssl->transform_out->md_ctx_enc, */
-  /*                         ssl->out_msg, ssl->out_msglen); */
-  /*         md_hmac_finish (&ssl->transform_out->md_ctx_enc, */
-  /*                         ssl->out_msg + ssl->out_msglen); */
-  /*         md_hmac_reset (&ssl->transform_out->md_ctx_enc); */
-  /*       } */
-  /*     else */
-  /*       { */
-  /*         debug_bug (); */
-  /*         return gpg_error (GPG_ERR_INTERNAL); */
-  /*       } */
-
-  /*     debug_buf (4, "computed mac", */
-  /*                ssl->out_msg + ssl->out_msglen, */
-  /*                ssl->transform_out->maclen); */
-
-  /*     ssl->out_msglen += ssl->transform_out->maclen; */
-  /*   } */
+  if (tls->minor_ver < TLS_MINOR_VERSION_3)
+    {
+      debug_bug ();
+      return gpg_error (GPG_ERR_BUG);
+    }
 
-  /* /\* */
-  /*  * Encrypt */
-  /*  *\/ */
-  /* if (mode == POLARSSL_MODE_STREAM) */
-  /*   { */
-  /*     int ret; */
-  /*     size_t olen = 0; */
-
-  /*     debug_msg (3, "before encrypt: msglen = %d, " */
-  /*                "including %d bytes of padding", */
-  /*                ssl->out_msglen, 0); */
-
-  /*     debug_buf (4, "before encrypt: output payload", */
-  /*                ssl->out_msg, ssl->out_msglen); */
-
-  /*     if ((ret = cipher_crypt (&ssl->transform_out->cipher_ctx_enc, */
-  /*                              ssl->transform_out->iv_enc, */
-  /*                              ssl->transform_out->ivlen, */
-  /*                              ssl->out_msg, ssl->out_msglen, */
-  /*                              ssl->out_msg, &olen)) != 0) */
-  /*       { */
-  /*         debug_ret (1, "cipher_crypt", ret); */
-  /*         return (ret); */
-  /*       } */
-
-  /*     if (ssl->out_msglen != olen) */
-  /*       { */
-  /*         debug_bug (); */
-  /*         return gpg_error (GPG_ERR_INTERNAL); */
-  /*       } */
-  /*   } */
-  /* else if (mode == POLARSSL_MODE_GCM || mode == POLARSSL_MODE_CCM) */
-  /*   { */
-  /*     int ret; */
-  /*     size_t enc_msglen, olen; */
-  /*     unsigned char *enc_msg; */
-  /*     unsigned char add_data[13]; */
-  /*     unsigned char taglen = ssl->transform_out->ciphersuite->flags & */
-  /*       POLARSSL_CIPHERSUITE_SHORT_TAG ? 8 : 16; */
-
-  /*     memcpy (add_data, ssl->out_ctr, 8); */
-  /*     add_data[8] = ssl->out_msgtype; */
-  /*     add_data[9] = ssl->major_ver; */
-  /*     add_data[10] = ssl->minor_ver; */
-  /*     add_data[11] = (ssl->out_msglen >> 8) & 0xFF; */
-  /*     add_data[12] = ssl->out_msglen & 0xFF; */
-
-  /*     debug_buf (4, "additional data used for AEAD", add_data, 13); */
-
-  /*     /\* */
-  /*      * Generate IV */
-  /*      *\/ */
-  /*     ret = ssl->f_rng (ssl->p_rng, */
-  /*                       ssl->transform_out->iv_enc + */
-  /*                       ssl->transform_out->fixed_ivlen, */
-  /*                       ssl->transform_out->ivlen - */
-  /*                       ssl->transform_out->fixed_ivlen); */
-  /*     if (ret != 0) */
-  /*       return (ret); */
-
-  /*     memcpy (ssl->out_iv, */
-  /*             ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen, */
-  /*             ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen); */
-
-  /*     debug_buf (4, "IV used", ssl->out_iv, */
-  /*                ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen); */
-
-  /*     /\* */
-  /*      * Fix pointer positions and message length with added IV */
-  /*      *\/ */
-  /*     enc_msg = ssl->out_msg; */
-  /*     enc_msglen = ssl->out_msglen; */
-  /*     ssl->out_msglen += ssl->transform_out->ivlen - */
-  /*       ssl->transform_out->fixed_ivlen; */
-
-  /*     debug_msg (3, "before encrypt: msglen = %d, " */
-  /*                "including %d bytes of padding", ssl->out_msglen, 0); */
-
-  /*     debug_buf (4, "before encrypt: output payload", */
-  /*                ssl->out_msg, ssl->out_msglen); */
-
-  /*     /\* */
-  /*      * Encrypt and authenticate */
-  /*      *\/ */
-  /*     if ((ret = cipher_auth_encrypt (&ssl->transform_out->cipher_ctx_enc, */
-  /*                                     ssl->transform_out->iv_enc, */
-  /*                                     ssl->transform_out->ivlen, */
-  /*                                     add_data, 13, */
-  /*                                     enc_msg, enc_msglen, */
-  /*                                     enc_msg, &olen, */
-  /*                                     enc_msg + enc_msglen, taglen)) != 0) */
-  /*       { */
-  /*         debug_ret (1, "cipher_auth_encrypt", ret); */
-  /*         return (ret); */
-  /*       } */
-
-  /*     if (olen != enc_msglen) */
-  /*       { */
-  /*         debug_bug (); */
-  /*         return gpg_error (GPG_ERR_INTERNAL); */
-  /*       } */
-
-  /*     ssl->out_msglen += taglen; */
-
-  /*     debug_buf (4, "after encrypt: tag", enc_msg + enc_msglen, taglen); */
-  /*   } */
-  /* else if (mode == POLARSSL_MODE_CBC) */
-  /*   { */
-  /*     int ret; */
-  /*     unsigned char *enc_msg; */
-  /*     size_t enc_msglen, padlen, olen = 0; */
-
-  /*     padlen = ssl->transform_out->ivlen - (ssl->out_msglen + 1) % */
-  /*       ssl->transform_out->ivlen; */
-  /*     if (padlen == ssl->transform_out->ivlen) */
-  /*       padlen = 0; */
-
-  /*     for (i = 0; i <= padlen; i++) */
-  /*       ssl->out_msg[ssl->out_msglen + i] = (unsigned char) padlen; */
-
-  /*     ssl->out_msglen += padlen + 1; */
-
-  /*     enc_msglen = ssl->out_msglen; */
-  /*     enc_msg = ssl->out_msg; */
-
-  /*     /\* */
-  /*      * Prepend per-record IV for block cipher in TLS v1.1 and up as per */
-  /*      * Method 1 (6.2.3.2. in RFC4346 and RFC5246) */
-  /*      *\/ */
-  /*     if (ssl->minor_ver >= TLS_MINOR_VERSION_2) */
-  /*       { */
-  /*         /\* */
-  /*          * Generate IV */
-  /*          *\/ */
-  /*         int ret = ssl->f_rng (ssl->p_rng, ssl->transform_out->iv_enc, */
-  /*                               ssl->transform_out->ivlen); */
-  /*         if (ret != 0) */
-  /*           return (ret); */
-
-  /*         memcpy (ssl->out_iv, ssl->transform_out->iv_enc, */
-  /*                 ssl->transform_out->ivlen); */
-
-  /*         /\* */
-  /*          * Fix pointer positions and message length with added IV */
-  /*          *\/ */
-  /*         enc_msg = ssl->out_msg; */
-  /*         enc_msglen = ssl->out_msglen; */
-  /*         ssl->out_msglen += ssl->transform_out->ivlen; */
-  /*       } */
-
-  /*     debug_msg (3, "before encrypt: msglen = %d, " */
-  /*                "including %d bytes of IV and %d bytes of padding", */
-  /*                ssl->out_msglen, ssl->transform_out->ivlen, */
-  /*                padlen + 1); */
-
-  /*     debug_buf (4, "before encrypt: output payload", */
-  /*                ssl->out_iv, ssl->out_msglen); */
-
-  /*     if ((ret = cipher_crypt (&ssl->transform_out->cipher_ctx_enc, */
-  /*                              ssl->transform_out->iv_enc, */
-  /*                              ssl->transform_out->ivlen, */
-  /*                              enc_msg, enc_msglen, enc_msg, &olen)) != 0) */
-  /*       { */
-  /*         debug_ret (1, "cipher_crypt", ret); */
-  /*         return (ret); */
-  /*       } */
-
-  /*     if (enc_msglen != olen) */
-  /*       { */
-  /*         debug_bug (); */
-  /*         return gpg_error (GPG_ERR_INTERNAL); */
-  /*       } */
 
-  /*   } */
-  /* else */
-  /*   { */
-  /*     debug_bug (); */
-  /*     return gpg_error (GPG_ERR_INTERNAL); */
-  /*   } */
+  /*
+   * Add MAC before encrypt, except for AEAD modes
+   */
+  if (mode != GCRY_CIPHER_MODE_GCM && mode != GCRY_CIPHER_MODE_CCM)
+    {
+      /* fixme: Add error checking.  */
+      gcry_mac_write (tls->transform_out->mac_ctx_enc, tls->out_ctr, 13);
+      gcry_mac_write (tls->transform_out->mac_ctx_enc,
+                      tls->out_msg, tls->out_msglen);
+      tmplen = tls->transform_out->maclen;
+      gcry_mac_read (tls->transform_out->mac_ctx_enc,
+                     tls->out_msg + tls->out_msglen, &tmplen);
+      gcry_mac_reset (tls->transform_out->mac_ctx_enc);
 
-  /* for (i = 8; i > 0; i--) */
-  /*   if (++ssl->out_ctr[i - 1] != 0) */
-  /*     break; */
+      debug_buf (4, "computed mac",
+                 tls->out_msg + tls->out_msglen,
+                 tls->transform_out->maclen);
 
-  /* /\* The loops goes to its end iff the counter is wrapping *\/ */
-  /* if (i == 0) */
-  /*   { */
-  /*     debug_msg (1, "outgoing message counter would wrap"); */
-  /*     return gpg_error (GPG_ERR_WOULD_WRAP); */
-  /*   } */
+      tls->out_msglen += tls->transform_out->maclen;
+    }
+
+  /*
+   * Encrypt
+   */
+  if (mode == GCRY_CIPHER_MODE_STREAM)
+    {
+      size_t olen = 0;
+
+      debug_msg (3, "before encrypt: msglen = %d,"
+                 " including %d bytes of padding", tls->out_msglen, 0);
+      debug_buf (4, "before encrypt: output payload",
+                 tls->out_msg, tls->out_msglen);
+
+      /* err = cipher_crypt (&tls->transform_out->cipher_ctx_enc, */
+      /*                     tls->transform_out->iv_enc, */
+      /*                     tls->transform_out->ivlen, */
+      /*                     tls->out_msg, tls->out_msglen, */
+      /*                     tls->out_msg, &olen); */
+      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      if (err)
+        {
+          debug_ret (1, "cipher_crypt", err);
+          return err;
+        }
+
+      if (tls->out_msglen != olen)
+        {
+          debug_bug ();
+          return gpg_error (GPG_ERR_INTERNAL);
+        }
+    }
+  else if (mode == GCRY_CIPHER_MODE_GCM || mode == GCRY_CIPHER_MODE_CCM)
+    {
+      size_t enc_msglen, olen;
+      unsigned char *enc_msg;
+      unsigned char add_data[13];
+      unsigned char taglen;
+
+
+      taglen = (_ntbtls_ciphersuite_get_flags (tls->transform_out->ciphersuite)
+                & CIPHERSUITE_FLAG_SHORT_TAG)? 8 : 16;
+
+      memcpy (add_data, tls->out_ctr, 8);
+      add_data[8] = tls->out_msgtype;
+      add_data[9] = tls->major_ver;
+      add_data[10] = tls->minor_ver;
+      add_data[11] = (tls->out_msglen >> 8) & 0xFF;
+      add_data[12] = tls->out_msglen & 0xFF;
+
+      debug_buf (4, "additional data used for AEAD", add_data, 13);
+
+      /*
+       * Generate IV
+       */
+      gcry_create_nonce (tls->transform_out->iv_enc
+                         + tls->transform_out->fixed_ivlen,
+                         tls->transform_out->ivlen
+                         - tls->transform_out->fixed_ivlen);
+
+      memcpy (tls->out_iv,
+              tls->transform_out->iv_enc + tls->transform_out->fixed_ivlen,
+              tls->transform_out->ivlen - tls->transform_out->fixed_ivlen);
 
-  /* debug_msg (2, "<= encrypt buf"); */
+      debug_buf (4, "IV used", tls->out_iv,
+                 tls->transform_out->ivlen - tls->transform_out->fixed_ivlen);
+
+      /*
+       * Fix pointer positions and message length with added IV
+       */
+      enc_msg = tls->out_msg;
+      enc_msglen = tls->out_msglen;
+      tls->out_msglen += (tls->transform_out->ivlen
+                          - tls->transform_out->fixed_ivlen);
+
+      debug_msg (3, "before encrypt: msglen = %d, "
+                 "including %d bytes of padding", tls->out_msglen, 0);
+      debug_buf (4, "before encrypt: output payload",
+                 tls->out_msg, tls->out_msglen);
+
+      /*
+       * Encrypt and authenticate
+       */
+      /* err = cipher_auth_encrypt (&tls->transform_out->cipher_ctx_enc, */
+      /*                            tls->transform_out->iv_enc, */
+      /*                            tls->transform_out->ivlen, */
+      /*                            add_data, 13, */
+      /*                            enc_msg, enc_msglen, */
+      /*                            enc_msg, &olen, */
+      /*                            enc_msg + enc_msglen, taglen); */
+      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      if (err)
+        {
+          debug_ret (1, "cipher_auth_encrypt", err);
+          return err;
+        }
+
+      if (olen != enc_msglen)
+        {
+          debug_bug ();
+          return gpg_error (GPG_ERR_BUG);
+        }
 
-  /* return (0); */
+      tls->out_msglen += taglen;
+
+      debug_buf (4, "after encrypt: tag", enc_msg + enc_msglen, taglen);
+    }
+  else if (mode == GCRY_CIPHER_MODE_CBC)
+    {
+      unsigned char *enc_msg;
+      size_t enc_msglen, padlen;
+
+      padlen = (tls->transform_out->ivlen
+                - ((tls->out_msglen + 1) % tls->transform_out->ivlen));
+      if (padlen == tls->transform_out->ivlen)
+        padlen = 0;
+
+      for (i = 0; i <= padlen; i++)
+        tls->out_msg[tls->out_msglen + i] = (unsigned char) padlen;
+
+      tls->out_msglen += padlen + 1;
+
+      enc_msglen = tls->out_msglen;
+      enc_msg = tls->out_msg;
+
+      /*
+       * Prepend per-record IV for block cipher in TLS v1.1 and up as per
+       * Method 1 (RFC-5246, 6.2.3.2)
+       */
+
+      /* Generate IV.  */
+      gcry_create_nonce (tls->transform_out->iv_enc, tls->transform_out->ivlen);
+
+      memcpy (tls->out_iv, tls->transform_out->iv_enc,
+              tls->transform_out->ivlen);
+
+      /* Fix pointer positions and message length with added IV.  */
+      enc_msg = tls->out_msg;
+      enc_msglen = tls->out_msglen;
+      tls->out_msglen += tls->transform_out->ivlen;
+
+      debug_msg (3, "before encrypt: msglen = %d, "
+                 "including %d bytes of IV and %d bytes of padding",
+                 tls->out_msglen, tls->transform_out->ivlen, padlen + 1);
+      debug_buf (4, "before encrypt: output payload",
+                 tls->out_iv, tls->out_msglen);
+
+      err = gcry_cipher_reset (tls->transform_out->cipher_ctx_enc);
+      if (err)
+        {
+          debug_ret (1, "cipher_reset", err);
+          return err;
+        }
+      err = gcry_cipher_setiv (tls->transform_out->cipher_ctx_enc,
+                               tls->transform_out->iv_enc,
+                               tls->transform_out->ivlen);
+      if (err)
+        {
+          debug_ret (1, "cipher_setiv", err);
+          return err;
+        }
+
+      err = gcry_cipher_encrypt (tls->transform_out->cipher_ctx_enc,
+                                 enc_msg, enc_msglen, NULL, 0);
+      if (err)
+        {
+          debug_ret (1, "cipher_encrypt", err);
+          return err;
+        }
+    }
+  else
+    {
+      debug_bug ();
+      return gpg_error (GPG_ERR_INTERNAL);
+    }
+
+  for (i = 8; i > 0; i--)
+    if (++tls->out_ctr[i - 1] != 0)
+      break;
+
+  /* The loops goes to its end iff the counter is wrapping */
+  if (!i)
+    {
+      debug_msg (1, "outgoing message counter would wrap");
+      return gpg_error (GPG_ERR_WOULD_WRAP);
+    }
+
+  debug_msg (2, "<= encrypt buf");
+
+  return 0;
 }
 
-#define POLARSSL_SSL_MAX_MAC_SIZE   48
 
 static int
-ssl_decrypt_buf (ntbtls_t ssl)
+decrypt_buf (ntbtls_t tls)
 {
-  //FIXME:
-  /* size_t i; */
-  /* const cipher_mode_t mode = */
-  /*   cipher_get_cipher_mode (&ssl->transform_in->cipher_ctx_dec); */
-  /* size_t padlen = 0, correct = 1; */
+  gpg_error_t err;
+  cipher_mode_t mode = tls->transform_out->cipher_mode_dec;
+  size_t padlen = 0;
+  size_t correct = 1;
+  size_t tmplen, i;
 
-  /* debug_msg (2, "=> decrypt buf"); */
+  debug_msg (2, "=> decrypt buf");
 
-  /* if (ssl->in_msglen < ssl->transform_in->minlen) */
-  /*   { */
-  /*     debug_msg (1, "in_msglen (%d) < minlen (%d)", */
-  /*                ssl->in_msglen, ssl->transform_in->minlen); */
-  /*     return gpg_error (GPG_ERR_INV_MAC)
-  /*   } */
+  if (tls->minor_ver < TLS_MINOR_VERSION_3)
+    {
+      debug_bug ();
+      return gpg_error (GPG_ERR_BUG);
+    }
 
-  /* if (mode == POLARSSL_MODE_STREAM) */
-  /*   { */
-  /*     int ret; */
-  /*     size_t olen = 0; */
-
-  /*     padlen = 0; */
-
-  /*     if ((ret = cipher_crypt (&ssl->transform_in->cipher_ctx_dec, */
-  /*                              ssl->transform_in->iv_dec, */
-  /*                              ssl->transform_in->ivlen, */
-  /*                              ssl->in_msg, ssl->in_msglen, */
-  /*                              ssl->in_msg, &olen)) != 0) */
-  /*       { */
-  /*         debug_ret (1, "cipher_crypt", ret); */
-  /*         return (ret); */
-  /*       } */
-
-  /*     if (ssl->in_msglen != olen) */
-  /*       { */
-  /*         debug_bug (); */
-  /*         return gpg_error (GPG_ERR_INTERNAL); */
-  /*       } */
-  /*   } */
-  /* else if (mode == POLARSSL_MODE_GCM || mode == POLARSSL_MODE_CCM) */
-  /*   { */
-  /*     int ret; */
-  /*     size_t dec_msglen, olen; */
-  /*     unsigned char *dec_msg; */
-  /*     unsigned char *dec_msg_result; */
-  /*     unsigned char add_data[13]; */
-  /*     unsigned char taglen = ssl->transform_in->ciphersuite->flags & */
-  /*       POLARSSL_CIPHERSUITE_SHORT_TAG ? 8 : 16; */
-  /*     unsigned char explicit_iv_len = ssl->transform_in->ivlen - */
-  /*       ssl->transform_in->fixed_ivlen; */
-
-  /*     if (ssl->in_msglen < explicit_iv_len + taglen) */
-  /*       { */
-  /*         debug_msg (1, "msglen (%d) < explicit_iv_len (%d) " */
-  /*                    "+ taglen (%d)", ssl->in_msglen, */
-  /*                    explicit_iv_len, taglen); */
-  /*         return gpg_error (GPG_ERR_INV_MAC);
-  /*       } */
-  /*     dec_msglen = ssl->in_msglen - explicit_iv_len - taglen; */
-
-  /*     dec_msg = ssl->in_msg; */
-  /*     dec_msg_result = ssl->in_msg; */
-  /*     ssl->in_msglen = dec_msglen; */
-
-  /*     memcpy (add_data, ssl->in_ctr, 8); */
-  /*     add_data[8] = ssl->in_msgtype; */
-  /*     add_data[9] = ssl->major_ver; */
-  /*     add_data[10] = ssl->minor_ver; */
-  /*     add_data[11] = (ssl->in_msglen >> 8) & 0xFF; */
-  /*     add_data[12] = ssl->in_msglen & 0xFF; */
-
-  /*     debug_buf (4, "additional data used for AEAD", add_data, 13); */
-
-  /*     memcpy (ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen, */
-  /*             ssl->in_iv, */
-  /*             ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen); */
-
-  /*     debug_buf (4, "IV used", */
-  /*                ssl->transform_in->iv_dec, ssl->transform_in->ivlen); */
-  /*     debug_buf (4, "TAG used", dec_msg + dec_msglen, taglen); */
-
-  /*     /\* */
-  /*      * Decrypt and authenticate */
-  /*      *\/ */
-  /*     if ((ret = cipher_auth_decrypt (&ssl->transform_in->cipher_ctx_dec, */
-  /*                                     ssl->transform_in->iv_dec, */
-  /*                                     ssl->transform_in->ivlen, */
-  /*                                     add_data, 13, */
-  /*                                     dec_msg, dec_msglen, */
-  /*                                     dec_msg_result, &olen, */
-  /*                                     dec_msg + dec_msglen, taglen)) != 0) */
-  /*       { */
-  /*         debug_ret (1, "cipher_auth_decrypt", ret); */
-
-  /*         if (ret == POLARSSL_ERR_CIPHER_AUTH_FAILED) */
-  /*           return gpg_error (GPG_ERR_BAD_MAC); */
-
-  /*         return (ret); */
-  /*       } */
-
-  /*     if (olen != dec_msglen) */
-  /*       { */
-  /*         debug_bug (); */
-  /*         return gpg_error (GPG_ERR_INTERNAL); */
-  /*       } */
-  /*   } */
-  /* else if (mode == POLARSSL_MODE_CBC) */
-  /*   { */
-  /*     /\* */
-  /*      * Decrypt and check the padding */
-  /*      *\/ */
-  /*     int ret; */
-  /*     unsigned char *dec_msg; */
-  /*     unsigned char *dec_msg_result; */
-  /*     size_t dec_msglen; */
-  /*     size_t minlen = 0; */
-  /*     size_t olen = 0; */
-
-  /*     /\* */
-  /*      * Check immediate ciphertext sanity */
-  /*      *\/ */
-  /*     if (ssl->in_msglen % ssl->transform_in->ivlen != 0) */
-  /*       { */
-  /*         debug_msg (1, "msglen (%d) %% ivlen (%d) != 0", */
-  /*                    ssl->in_msglen, ssl->transform_in->ivlen); */
-  /*         return gpg_error (GPG_ERR_INV_MAC); */
-  /*       } */
-
-  /*     if (ssl->minor_ver >= TLS_MINOR_VERSION_2) */
-  /*       minlen += ssl->transform_in->ivlen; */
-
-  /*     if (ssl->in_msglen < minlen + ssl->transform_in->ivlen || */
-  /*         ssl->in_msglen < minlen + ssl->transform_in->maclen + 1) */
-  /*       { */
-  /*         debug_msg (1, "msglen (%d) < max( ivlen(%d), maclen (%d) " */
-  /*                    "+ 1 ) ( + expl IV )", */
-  /*                    ssl->in_msglen, */
-  /*                    ssl->transform_in->ivlen, */
-  /*                    ssl->transform_in->maclen); */
-  /*         return gpg_error (GPG_ERR_INV_MAC); */
-  /*       } */
-
-  /*     dec_msglen = ssl->in_msglen; */
-  /*     dec_msg = ssl->in_msg; */
-  /*     dec_msg_result = ssl->in_msg; */
-
-  /*     /\* */
-  /*      * Initialize for prepended IV for block cipher in TLS v1.1 and up */
-  /*      *\/ */
-  /*     if (ssl->minor_ver >= TLS_MINOR_VERSION_2) */
-  /*       { */
-  /*         dec_msglen -= ssl->transform_in->ivlen; */
-  /*         ssl->in_msglen -= ssl->transform_in->ivlen; */
-
-  /*         for (i = 0; i < ssl->transform_in->ivlen; i++) */
-  /*           ssl->transform_in->iv_dec[i] = ssl->in_iv[i]; */
-  /*       } */
-
-  /*     if ((ret = cipher_crypt (&ssl->transform_in->cipher_ctx_dec, */
-  /*                              ssl->transform_in->iv_dec, */
-  /*                              ssl->transform_in->ivlen, */
-  /*                              dec_msg, dec_msglen, */
-  /*                              dec_msg_result, &olen)) != 0) */
-  /*       { */
-  /*         debug_ret (1, "cipher_crypt", ret); */
-  /*         return (ret); */
-  /*       } */
-
-  /*     if (dec_msglen != olen) */
-  /*       { */
-  /*         debug_bug (); */
-  /*         return gpg_error (GPG_ERR_INTERNAL); */
-  /*       } */
-
-  /*     padlen = 1 + ssl->in_msg[ssl->in_msglen - 1]; */
-
-  /*     if (ssl->in_msglen < ssl->transform_in->maclen + padlen) */
-  /*       { */
-  /*         debug_msg (1, "msglen (%d) < maclen (%d) + padlen (%d)", */
-  /*                    ssl->in_msglen, ssl->transform_in->maclen, padlen); */
-  /*         padlen = 0; */
-  /*         correct = 0; */
-  /*       } */
-
-  /*     if (ssl->minor_ver > TLS_MINOR_VERSION_0) */
-  /*       { */
-  /*         /\* */
-  /*          * TLSv1+: always check the padding up to the first failure */
-  /*          * and fake check up to 256 bytes of padding */
-  /*          *\/ */
-  /*         size_t pad_count = 0, real_count = 1; */
-  /*         size_t padding_idx = ssl->in_msglen - padlen - 1; */
-
-  /*         /\* */
-  /*          * Padding is guaranteed to be incorrect if: */
-  /*          *   1. padlen >= ssl->in_msglen */
-  /*          * */
-  /*          *   2. padding_idx >= TLS_MAX_CONTENT_LEN + */
-  /*          *                     ssl->transform_in->maclen */
-  /*          * */
-  /*          * In both cases we reset padding_idx to a safe value (0) to */
-  /*          * prevent out-of-buffer reads. */
-  /*          *\/ */
-  /*         correct &= (ssl->in_msglen >= padlen + 1); */
-  /*         correct &= (padding_idx < TLS_MAX_CONTENT_LEN + */
-  /*                     ssl->transform_in->maclen); */
-
-  /*         padding_idx *= correct; */
-
-  /*         for (i = 1; i <= 256; i++) */
-  /*           { */
-  /*             real_count &= (i <= padlen); */
-  /*             pad_count += real_count * */
-  /*               (ssl->in_msg[padding_idx + i] == padlen - 1); */
-  /*           } */
-
-  /*         correct &= (pad_count == padlen);     /\* Only 1 on correct padding *\/ */
-
-  /*         if (padlen > 0 && correct == 0) */
-  /*           debug_msg (1, "bad padding byte detected"); */
-
-  /*         padlen &= correct * 0x1FF; */
-  /*       } */
-  /*     else */
-  /*       { */
-  /*         debug_bug (); */
-  /*         return gpg_error (GPG_ERR_INTERNAL); */
-  /*       } */
-  /*   } */
-  /* else */
-  /*   { */
-  /*     debug_bug (); */
-  /*     return gpg_error (GPG_ERR_INTERNAL); */
-  /*   } */
+  if (tls->in_msglen < tls->transform_in->minlen)
+    {
+      debug_msg (1, "in_msglen (%d) < minlen (%d)",
+                 tls->in_msglen, tls->transform_in->minlen);
+      return gpg_error (GPG_ERR_INV_MAC);
+    }
 
-  /* debug_buf (4, "raw buffer after decryption", ssl->in_msg, ssl->in_msglen); */
+  if (mode == GCRY_CIPHER_MODE_STREAM)
+    {
+      size_t olen = 0;
 
-  /* /\* */
-  /*  * Always compute the MAC (RFC4346, CBCTIME), except for AEAD of course */
-  /*  *\/ */
-  /* if (mode != POLARSSL_MODE_GCM && mode != POLARSSL_MODE_CCM) */
-  /*   { */
-  /*     unsigned char tmp[POLARSSL_SSL_MAX_MAC_SIZE]; */
-
-  /*     ssl->in_msglen -= (ssl->transform_in->maclen + padlen); */
-
-  /*     ssl->in_hdr[3] = (unsigned char) (ssl->in_msglen >> 8); */
-  /*     ssl->in_hdr[4] = (unsigned char) (ssl->in_msglen); */
-
-  /*     memcpy (tmp, ssl->in_msg + ssl->in_msglen, ssl->transform_in->maclen); */
-
-  /*     if (ssl->minor_ver > TLS_MINOR_VERSION_0) */
-  /*       { */
-  /*         /\* */
-  /*          * Process MAC and always update for padlen afterwards to make */
-  /*          * total time independent of padlen */
-  /*          * */
-  /*          * extra_run compensates MAC check for padlen */
-  /*          * */
-  /*          * Known timing attacks: */
-  /*          *  - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf) */
-  /*          * */
-  /*          * We use ( ( Lx + 8 ) / 64 ) to handle 'negative Lx' values */
-  /*          * correctly. (We round down instead of up, so -56 is the correct */
-  /*          * value for our calculations instead of -55) */
-  /*          *\/ */
-  /*         size_t j, extra_run = 0; */
-  /*         extra_run = (13 + ssl->in_msglen + padlen + 8) / 64 - */
-  /*           (13 + ssl->in_msglen + 8) / 64; */
-
-  /*         extra_run &= correct * 0xFF; */
-
-  /*         md_hmac_update (&ssl->transform_in->md_ctx_dec, ssl->in_ctr, 13); */
-  /*         md_hmac_update (&ssl->transform_in->md_ctx_dec, ssl->in_msg, */
-  /*                         ssl->in_msglen); */
-  /*         md_hmac_finish (&ssl->transform_in->md_ctx_dec, */
-  /*                         ssl->in_msg + ssl->in_msglen); */
-  /*         for (j = 0; j < extra_run; j++) */
-  /*           md_process (&ssl->transform_in->md_ctx_dec, ssl->in_msg); */
-
-  /*         md_hmac_reset (&ssl->transform_in->md_ctx_dec); */
-  /*       } */
-  /*     else */
-  /*       { */
-  /*         debug_bug (); */
-  /*         return gpg_error (GPG_ERR_INTERNAL); */
-  /*       } */
-
-  /*     debug_buf (4, "message  mac", tmp, ssl->transform_in->maclen); */
-  /*     debug_buf (4, "computed mac", */
-  /*                ssl->in_msg + ssl->in_msglen, ssl->transform_in->maclen); */
-
-  /*     if (memcmpct (tmp, ssl->in_msg + ssl->in_msglen, */
-  /*                       ssl->transform_in->maclen) != 0) */
-  /*       { */
-  /*         debug_msg (1, "message mac does not match"); */
-  /*         correct = 0; */
-  /*       } */
-
-  /*     /\* */
-  /*      * Finally check the correct flag */
-  /*      *\/ */
-  /*     if (correct == 0) */
-  /*       return gpg_error (GPG_ERR_BAD_MAC); */
-  /*   } */
+      padlen = 0;
 
-  /* if (ssl->in_msglen == 0) */
-  /*   { */
-  /*     ssl->nb_zero++; */
-
-  /*     /\* */
-  /*      * Three or more empty messages may be a DoS attack */
-  /*      * (excessive CPU consumption). */
-  /*      *\/ */
-  /*     if (ssl->nb_zero > 3) */
-  /*       { */
-  /*         debug_msg (1, "received four consecutive empty " */
-  /*                    "messages, possible DoS attack"); */
-  /*         return gpg_error (GPG_ERR_INV_MAC); */
-  /*       } */
-  /*   } */
-  /* else */
-  /*   ssl->nb_zero = 0; */
+      /* err = cipher_crypt (tls->transform_in->cipher_ctx_dec, */
+      /*                     tls->transform_in->iv_dec, */
+      /*                     tls->transform_in->ivlen, */
+      /*                     tls->in_msg, tls->in_msglen, */
+      /*                     tls->in_msg, &olen); */
+      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      if (err)
+        {
+          debug_ret (1, "cipher_crypt", err);
+          return err;
+        }
+
+      if (tls->in_msglen != olen)
+        {
+          debug_bug ();
+          return gpg_error (GPG_ERR_INTERNAL);
+        }
+    }
+  else if (mode == GCRY_CIPHER_MODE_GCM || mode == GCRY_CIPHER_MODE_CCM)
+    {
+      size_t dec_msglen, olen;
+      unsigned char *dec_msg;
+      unsigned char add_data[13];
+      unsigned char taglen, explicit_iv_len;
 
-  /* for (i = 8; i > 0; i--) */
-  /*   if (++ssl->in_ctr[i - 1] != 0) */
-  /*     break; */
+      taglen = (_ntbtls_ciphersuite_get_flags (tls->transform_in->ciphersuite)
+                & CIPHERSUITE_FLAG_SHORT_TAG)? 8 : 16;
+      explicit_iv_len = (tls->transform_in->ivlen
+                         - tls->transform_in->fixed_ivlen);
 
-  /* /\* The loops goes to its end iff the counter is wrapping *\/ */
-  /* if (i == 0) */
-  /*   { */
-  /*     debug_msg (1, "incoming message counter would wrap"); */
-  /*     return gpg_error (GPG_ERR_WOULD_WRAP); */
-  /*   } */
+      if (tls->in_msglen < explicit_iv_len + taglen)
+        {
+          debug_msg (1, "msglen (%d) < explicit_iv_len (%d) "
+                     "+ taglen (%d)", tls->in_msglen,
+                     explicit_iv_len, taglen);
+          return gpg_error (GPG_ERR_INV_MAC);
+         }
+      dec_msglen = tls->in_msglen - explicit_iv_len - taglen;
+
+      dec_msg = tls->in_msg;
+      tls->in_msglen = dec_msglen;
+
+      memcpy (add_data, tls->in_ctr, 8);
+      add_data[8] = tls->in_msgtype;
+      add_data[9] = tls->major_ver;
+      add_data[10] = tls->minor_ver;
+      add_data[11] = (tls->in_msglen >> 8) & 0xFF;
+      add_data[12] = tls->in_msglen & 0xFF;
+
+      debug_buf (4, "additional data used for AEAD", add_data, 13);
+
+      memcpy (tls->transform_in->iv_dec + tls->transform_in->fixed_ivlen,
+              tls->in_iv,
+              tls->transform_in->ivlen - tls->transform_in->fixed_ivlen);
+
+      debug_buf (4, "IV used",
+                 tls->transform_in->iv_dec, tls->transform_in->ivlen);
+      debug_buf (4, "TAG used", dec_msg + dec_msglen, taglen);
+
+      /*
+       * Decrypt and authenticate
+       */
+      /* err = cipher_auth_decrypt (tls->transform_in->cipher_ctx_dec, */
+      /*                            tls->transform_in->iv_dec, */
+      /*                            tls->transform_in->ivlen, */
+      /*                            add_data, 13, */
+      /*                            dec_msg, dec_msglen, */
+      /*                            dec_msg_result, &olen, */
+      /*                            dec_msg + dec_msglen, taglen); */
+      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      if (err)
+        {
+          debug_ret (1, "cipher_auth_decrypt", err);
+
+          /* if (gpg_err_code (err) == POLARSSL_ERR_CIPHER_AUTH_FAILED) */
+          /*   err = gpg_error (GPG_ERR_BAD_MAC); */
+
+          return err;
+        }
+
+      if (olen != dec_msglen)
+        {
+          debug_bug ();
+          return gpg_error (GPG_ERR_INTERNAL);
+        }
+    }
+  else if (mode == GCRY_CIPHER_MODE_CBC)
+    {
+      /*
+       * Decrypt and check the padding
+       */
+      unsigned char *dec_msg;
+      size_t pad_count, real_count, padding_idx;
+      size_t dec_msglen;
+      size_t minlen = 0;
+      size_t olen = 0;
+
+      /*
+       * Check immediate ciphertext sanity
+       */
+      if ((tls->in_msglen % tls->transform_in->ivlen))
+        {
+          debug_msg (1, "msglen (%d) %% ivlen (%d) != 0",
+                     tls->in_msglen, tls->transform_in->ivlen);
+          return gpg_error (GPG_ERR_INV_MAC);
+        }
+
+      minlen += tls->transform_in->ivlen;
+
+      if (tls->in_msglen < minlen + tls->transform_in->ivlen
+          || tls->in_msglen < minlen + tls->transform_in->maclen + 1)
+        {
+          debug_msg (1, "msglen (%d) < max( ivlen(%d), maclen (%d) "
+                     "+ 1 ) ( + expl IV )",
+                     tls->in_msglen,
+                     tls->transform_in->ivlen,
+                     tls->transform_in->maclen);
+          return gpg_error (GPG_ERR_INV_MAC);
+        }
+
+      dec_msglen = tls->in_msglen;
+      dec_msg = tls->in_msg;
 
-  /* debug_msg (2, "<= decrypt buf"); */
+      /*
+       * Initialize for prepended IV.
+       */
+      dec_msglen -= tls->transform_in->ivlen;
+      tls->in_msglen -= tls->transform_in->ivlen;
+
+      for (i = 0; i < tls->transform_in->ivlen; i++)
+        tls->transform_in->iv_dec[i] = tls->in_iv[i];
+
+      err = gcry_cipher_reset (tls->transform_out->cipher_ctx_dec);
+      if (err)
+        {
+          debug_ret (1, "cipher_reset", err);
+          return err;
+        }
+      err = gcry_cipher_setiv (tls->transform_out->cipher_ctx_dec,
+                               tls->transform_out->iv_dec,
+                               tls->transform_out->ivlen);
+      if (err)
+        {
+          debug_ret (1, "cipher_setiv", err);
+          return err;
+        }
+
+      err = gcry_cipher_decrypt (tls->transform_out->cipher_ctx_dec,
+                                 dec_msg, dec_msglen, NULL, 0);
+      if (err)
+        {
+          debug_ret (1, "cipher_decrypt", err);
+          return err;
+        }
 
-  /* return (0); */
+      padlen = 1 + tls->in_msg[tls->in_msglen - 1];
+
+      if (tls->in_msglen < tls->transform_in->maclen + padlen)
+        {
+          debug_msg (1, "msglen (%d) < maclen (%d) + padlen (%d)",
+                     tls->in_msglen, tls->transform_in->maclen, padlen);
+          padlen = 0;
+          correct = 0;
+        }
+
+      /*
+       * Always check the padding up to the first failure and fake
+       * check up to 256 bytes of padding
+       */
+      pad_count = 0;
+      real_count = 1;
+      padding_idx = tls->in_msglen - padlen - 1;
+
+      /*
+       * Padding is guaranteed to be incorrect if:
+       *   1. padlen >= tls->in_msglen
+       *
+       *   2. padding_idx >= TLS_MAX_CONTENT_LEN +
+       *                     tls->transform_in->maclen
+       *
+       * In both cases we reset padding_idx to a safe value (0) to
+       * prevent out-of-buffer reads.
+       */
+      correct &= (tls->in_msglen >= padlen + 1);
+      correct &= (padding_idx < TLS_MAX_CONTENT_LEN
+                  + tls->transform_in->maclen);
+      padding_idx *= correct;
+
+      for (i = 1; i <= 256; i++)
+        {
+          real_count &= (i <= padlen);
+          pad_count += real_count * (tls->in_msg[padding_idx + i] == padlen-1);
+        }
+
+      correct &= (pad_count == padlen);     /* Only 1 on correct padding */
+
+      if (padlen > 0 && !correct)
+        debug_msg (1, "bad padding byte detected");
+
+      padlen &= correct * 0x1FF;
+    }
+  else
+    {
+      debug_bug ();
+      return gpg_error (GPG_ERR_INTERNAL);
+    }
+
+  debug_buf (4, "raw buffer after decryption", tls->in_msg, tls->in_msglen);
+
+  /*
+   * Always compute the MAC (RFC4346, CBCTIME), except for AEAD of course
+   */
+  if (mode != GCRY_CIPHER_MODE_GCM && mode != GCRY_CIPHER_MODE_CCM)
+    {
+      unsigned char tmp[TLS_MAX_MAC_SIZE];
+      size_t j, extra_run;
+
+      tls->in_msglen -= (tls->transform_in->maclen + padlen);
+
+      tls->in_hdr[3] = (unsigned char) (tls->in_msglen >> 8);
+      tls->in_hdr[4] = (unsigned char) (tls->in_msglen);
+
+      memcpy (tmp, tls->in_msg + tls->in_msglen, tls->transform_in->maclen);
+
+      /*
+       * Process MAC and always update for padlen afterwards to make
+       * total time independent of padlen
+       *
+       * extra_run compensates MAC check for padlen
+       *
+       * Known timing attacks:
+       *  - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
+       *
+       * We use ( ( Lx + 8 ) / 64 ) to handle 'negative Lx' values
+       * correctly. (We round down instead of up, so -56 is the correct
+       * value for our calculations instead of -55)
+       */
+      extra_run = ((13 + tls->in_msglen + padlen + 8) / 64
+                   - (13 + tls->in_msglen + 8) / 64);
+
+      extra_run &= correct * 0xFF;
+
+      gcry_mac_write (tls->transform_in->mac_ctx_dec, tls->in_ctr, 13);
+      gcry_mac_write (tls->transform_in->mac_ctx_dec, tls->in_msg,
+                      tls->in_msglen);
+      tmplen = tls->transform_in->maclen;
+      gcry_mac_read (tls->transform_in->mac_ctx_dec,
+                     tls->in_msg + tls->in_msglen, &tmplen);
+      //FIXME:
+      //FIXME:  We need to implement our own version of this
+      //FIXME:  Maybe we can use gcry_mac_write after the read but that
+      //        Needs to be checked and a comment must be added to
+      //        Libgcrypt so that we do not accidently optimize this away.
+      /* for (j = 0; j < extra_run; j++) */
+      /*   md_process (&tls->transform_in->md_ctx_dec, tls->in_msg); */
+
+      gcry_mac_reset (tls->transform_in->mac_ctx_dec);
+
+      debug_buf (4, "message  mac", tmp, tls->transform_in->maclen);
+      debug_buf (4, "computed mac",
+                 tls->in_msg + tls->in_msglen, tls->transform_in->maclen);
+
+      if (memcmpct (tmp, tls->in_msg + tls->in_msglen,
+                    tls->transform_in->maclen))
+        {
+          debug_msg (1, "message mac does not match");
+          correct = 0;
+        }
+
+      /*
+       * Finally check the correct flag
+       */
+      if (!correct)
+        return gpg_error (GPG_ERR_BAD_MAC);
+    }
+
+  if (!tls->in_msglen)
+    {
+      tls->nb_zero++;
+
+      /*
+       * Three or more empty messages may be a DoS attack
+       * (excessive CPU consumption).
+       */
+      if (tls->nb_zero > 3)
+        {
+          debug_msg (1, "received four consecutive empty "
+                     "messages, possible DoS attack");
+          return gpg_error (GPG_ERR_INV_MAC);
+        }
+    }
+  else
+    tls->nb_zero = 0;
+
+  for (i = 8; i > 0; i--)
+    if (++tls->in_ctr[i - 1] != 0)
+      break;
+
+  /* The loops goes to its end iff the counter is wrapping */
+  if (!i)
+    {
+      debug_msg (1, "incoming message counter would wrap");
+      return gpg_error (GPG_ERR_WOULD_WRAP);
+    }
+
+  debug_msg (2, "<= decrypt buf");
+
+  return 0;
 }
 
 
@@ -1382,7 +1348,7 @@ _ntbtls_fetch_input (ntbtls_t tls, size_t nb_want)
         err = gpg_error_from_syserror ();
 
       debug_msg (2, "in_left: %d, nb_want: %d", tls->in_left, nb_want);
-      debug_ret (2, "es_read", nread);
+      debug_ret (2, "es_read", err);
 
       if (err || !nread /*ie. EOF*/)
         break;
@@ -1392,7 +1358,7 @@ _ntbtls_fetch_input (ntbtls_t tls, size_t nb_want)
 
   debug_msg (2, "<= fetch input");
 
-  return 0;
+  return err;
 }
 
 
@@ -1480,10 +1446,10 @@ _ntbtls_write_record (ntbtls_t tls)
 
       if (tls->transform_out)
         {
-          err = ssl_encrypt_buf (tls);
+          err = encrypt_buf (tls);
           if (err)
             {
-              debug_ret (1, "ssl_encrypt_buf", err);
+              debug_ret (1, "encrypt_buf", err);
               return err;
             }
 
@@ -1555,7 +1521,7 @@ _ntbtls_read_record (ntbtls_t tls)
       if (tls->state != TLS_HANDSHAKE_OVER)
         tls->handshake->update_checksum (tls, tls->in_msg, tls->in_hslen);
 
-      return (0);
+      return 0;
     }
 
   tls->in_hslen = 0;
@@ -1645,7 +1611,7 @@ _ntbtls_read_record (ntbtls_t tls)
 
   if (!done && tls->transform_in)
     {
-      err = ssl_decrypt_buf (tls);
+      err = decrypt_buf (tls);
       if (err)
         {
           if (gpg_err_code (err) == GPG_ERR_INV_MAC
@@ -2170,9 +2136,9 @@ update_checksum_sha384 (ntbtls_t tls, const unsigned char *buf, size_t len)
 void
 _ntbtls_optimize_checksum (ntbtls_t tls, const ciphersuite_t suite)
 {
-  if (_ntbtls_ciphersuite_get_mac (suite) == GCRY_MD_SHA384)
+  if (_ntbtls_ciphersuite_get_mac (suite) == GCRY_MAC_HMAC_SHA384)
     tls->handshake->update_checksum = update_checksum_sha384;
-  else if (_ntbtls_ciphersuite_get_mac (suite) != GCRY_MD_SHA384)
+  else if (_ntbtls_ciphersuite_get_mac (suite) != GCRY_MAC_HMAC_SHA384)
     tls->handshake->update_checksum = update_checksum_sha256;
   else
     {
@@ -2191,88 +2157,74 @@ update_checksum_start (ntbtls_t tls, const unsigned char *buf, size_t len)
 
 
 
-/* static void */
-/* calc_finished_tls_sha256 (ntbtls_t ssl, unsigned char *buf, int is_client) */
-/* { */
-/*   int len = 12; */
-/*   const char *sender; */
-/*   sha256_context sha256; */
-/*   unsigned char padbuf[32]; */
-
-/*   session_t session = ssl->session_negotiate; */
-/*   if (!session) */
-/*     session = ssl->session; */
-
-/*   debug_msg (2, "=> calc  finished tls sha256"); */
-
-/*   memcpy (&sha256, &ssl->handshake->fin_sha256, sizeof (sha256_context)); */
-
-/*   /\* */
-/*    * TLSv1.2: */
-/*    *   hash = PRF( master, finished_label, */
-/*    *               Hash( handshake ) )[0.11] */
-/*    *\/ */
-
-/* #if !defined(POLARSSL_SHA256_ALT) */
-/*   debug_buf (4, "finished sha2 state", sha256.state, sizeof (sha256.state)); */
-/* #endif */
-
-/*   sender = is_client ? "client finished" : "server finished"; */
-
-/*   sha256_finish (&sha256, padbuf); */
-
-/*   ssl->handshake->tls_prf (session->master, 48, sender, padbuf, 32, buf, len); */
-
-/*   debug_buf (3, "calc finished result", buf, len); */
-
-/*   sha256_free (&sha256); */
-
-/*   wipememory (padbuf, sizeof (padbuf)); */
-
-/*   debug_msg (2, "<= calc  finished"); */
-/* } */
-
-
-/* static void */
-/* calc_finished_tls_sha384 (ntbtls_t ssl, unsigned char *buf, int is_client) */
-/* { */
-/*   int len = 12; */
-/*   const char *sender; */
-/*   sha512_context sha512; */
-/*   unsigned char padbuf[48]; */
-
-/*   session_t session = ssl->session_negotiate; */
-/*   if (!session) */
-/*     session = ssl->session; */
+static void
+calc_finished_tls (ntbtls_t tls, int is_sha384,
+                   unsigned char *buf, int is_client)
+{
+  gpg_error_t err;
+  gcry_md_hd_t md;
+  int len = 12;
+  const char *sender;
+  unsigned char padbuf[48];
+  size_t hashlen = is_sha384? 48 : 32;
+  session_t session;
+  char *p;
+
+  session = tls->session_negotiate;
+  if (!session)
+    session = tls->session;
 
-/*   debug_msg (2, "=> calc  finished tls sha384"); */
+  debug_msg (2, "=> calc finished tls sha%d", is_sha384? 384 : 256);
 
-/*   memcpy (&sha512, &ssl->handshake->fin_sha512, sizeof (sha512_context)); */
+  err = gcry_md_copy (&md, (is_sha384 ? tls->handshake->fin_sha512
+                            /*     */ : tls->handshake->fin_sha256));
+  if (err)
+    {
+      debug_ret (1, "calc_finished_tls", err);
+      memset (buf, 0, len);
+      return;
+    }
 
-/*   /\* */
-/*    * TLSv1.2: */
-/*    *   hash = PRF( master, finished_label, */
-/*    *               Hash( handshake ) )[0.11] */
-/*    *\/ */
+  /*
+   * TLSv1.2:
+   *   hash = PRF( master, finished_label,
+   *               Hash( handshake ) )[0.11]
+   */
+  sender = is_client ? "client finished" : "server finished";
 
-/* #if !defined(POLARSSL_SHA512_ALT) */
-/*   debug_buf (4, "finished sha512 state", sha512.state, sizeof (sha512.state)); */
-/* #endif */
+  p = gcry_md_read (md, is_sha384? GCRY_MD_SHA384 : GCRY_MD_SHA256);
+  if (p)
+    memcpy (padbuf, p, hashlen);
+  gcry_md_close (md);
+  if (!p)
+    {
+      debug_bug ();
+      memset (buf, 0, len);
+      return;
+    }
 
-/*   sender = is_client ? "client finished" : "server finished"; */
+  tls->handshake->tls_prf (session->master, 48, sender,
+                           padbuf, hashlen, buf, len);
 
-/*   sha512_finish (&sha512, padbuf); */
+  debug_buf (3, "calc finished result", buf, len);
 
-/*   ssl->handshake->tls_prf (session->master, 48, sender, padbuf, 48, buf, len); */
+  wipememory (padbuf, hashlen);
 
-/*   debug_buf (3, "calc finished result", buf, len); */
+  debug_msg (2, "<= calc finished tls sha%d", is_sha384? 384 : 256);
+}
 
-/*   sha512_free (&sha512); */
 
-/*   wipememory (padbuf, sizeof (padbuf)); */
+static void
+calc_finished_tls_sha256 (ntbtls_t tls, unsigned char *buf, int is_client)
+{
+  calc_finished_tls (tls, 0, buf, is_client);
+}
 
-/*   debug_msg (2, "<= calc  finished"); */
-/* } */
+static void
+calc_finished_tls_sha384 (ntbtls_t tls, unsigned char *buf, int is_client)
+{
+  calc_finished_tls (tls, 1, buf, is_client);
+}
 
 
 void
@@ -2351,8 +2303,9 @@ _ntbtls_write_finished (ntbtls_t tls)
 
   tls->handshake->calc_finished (tls, tls->out_msg + 4, tls->is_client);
 
-  //FIXME: TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
-  hashlen = (tls->minor_ver == TLS_MINOR_VERSION_0) ? 36 : 12;
+  /* TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
+     but all currently defined cipher suite keep it at 12.  */
+  hashlen = 12;
 
   tls->verify_data_len = hashlen;
   memcpy (tls->own_verify_data, tls->out_msg + 4, hashlen);
@@ -2406,7 +2359,7 @@ _ntbtls_parse_finished (ntbtls_t tls)
 
   debug_msg (2, "=> parse finished");
 
-  tls->handshake->calc_finished (tls, buf, tls->is_client);
+  tls->handshake->calc_finished (tls, buf, !tls->is_client);
 
   /*
    * Switch to our negotiated transform and session parameters for inbound
@@ -2442,8 +2395,8 @@ _ntbtls_parse_finished (ntbtls_t tls)
       return gpg_error (GPG_ERR_UNEXPECTED_MSG);
     }
 
-  //FIXME: TODO TLS/1.2 Hash length is determined by cipher suite (Page 63)
-  hashlen = (tls->minor_ver == TLS_MINOR_VERSION_0) ? 36 : 12;
+  /* TODO TLS/1.2 Hash length is determined by cipher suite (Page 63).  */
+  hashlen = 12;
 
   if (tls->in_msg[0] != TLS_HS_FINISHED || tls->in_hslen != 4 + hashlen)
     {
@@ -2454,6 +2407,8 @@ _ntbtls_parse_finished (ntbtls_t tls)
   if (memcmpct (tls->in_msg + 4, buf, hashlen))
     {
       debug_msg (1, "bad finished message");
+      debug_buf (2, "want", buf, hashlen);
+      debug_buf (2, " got", tls->in_msg+4, hashlen);
       return gpg_error (GPG_ERR_BAD_HS_FINISHED);
     }
 
@@ -2485,8 +2440,8 @@ transform_init (transform_t transform)
   /* cipher_init (&transform->cipher_ctx_enc); */
   /* cipher_init (&transform->cipher_ctx_dec); */
 
-  /* md_init (&transform->md_ctx_enc); */
-  /* md_init (&transform->md_ctx_dec); */
+  /* md_init (&transform->mac_ctx_enc); */
+  /* md_init (&transform->mac_ctx_dec); */
   return err;
 }
 
@@ -2504,8 +2459,8 @@ transform_deinit (transform_t transform)
   /* cipher_free (&transform->cipher_ctx_enc); */
   /* cipher_free (&transform->cipher_ctx_dec); */
 
-  /* md_free (&transform->md_ctx_enc); */
-  /* md_free (&transform->md_ctx_dec); */
+  /* md_free (&transform->mac_ctx_enc); */
+  /* md_free (&transform->mac_ctx_dec); */
 
   wipememory (transform, sizeof *transform);
 }
@@ -2549,11 +2504,21 @@ handshake_params_init (handshake_params_t handshake)
       return err;
     }
 
+  err = _ntbtls_dhm_new (&handshake->dhm_ctx);
+  if (err)
+    {
+      gcry_md_close (handshake->fin_sha256);
+      handshake->fin_sha256 = NULL;
+      gcry_md_close (handshake->fin_sha512);
+      handshake->fin_sha512 = NULL;
+      return err;
+    }
+
   handshake->update_checksum = update_checksum_start;
   handshake->sig_alg = TLS_HASH_SHA1;
 
+
   //*FIXME:
-  /* dhm_init (&handshake->dhm_ctx); */
   /* ecdh_init (&handshake->ecdh_ctx); */
   return 0;
 }
@@ -2565,8 +2530,10 @@ handshake_params_deinit (handshake_params_t handshake)
   if (!handshake)
     return;
 
+  _ntbtls_dhm_release (handshake->dhm_ctx);
+  handshake->dhm_ctx = NULL;
+
   //FIXME:
-  /* dhm_free (&handshake->dhm_ctx); */
   /* ecdh_free (&handshake->ecdh_ctx); */
 
   free (handshake->curves);
@@ -2703,7 +2670,13 @@ _ntbtls_new (ntbtls_t *r_tls, unsigned int flags)
       tls->use_session_tickets = 1;
     }
 
-  /* FIXME: ssl_set_ciphersuites (ssl, ssl_list_ciphersuites ()); */
+  /* We only support TLS 1.2 and thus we set the list for the other
+     TLS versions to NULL.  */
+  tls->ciphersuite_list[TLS_MINOR_VERSION_0] = NULL;
+  tls->ciphersuite_list[TLS_MINOR_VERSION_1] = NULL;
+  tls->ciphersuite_list[TLS_MINOR_VERSION_2] = NULL;
+  tls->ciphersuite_list[TLS_MINOR_VERSION_3] = _ntbtls_ciphersuite_list ();
+
 
   tls->renego_max_records = TLS_RENEGO_MAX_RECORDS_DEFAULT;
 
@@ -2876,6 +2849,13 @@ _ntbtls_set_transport (ntbtls_t tls, estream_t inbound, estream_t outbound)
   if (tls->inbound || tls->outbound)
     return gpg_error (GPG_ERR_CONFLICT);
 
+  /* fixme: Instead of calling a flush we set the stream to nowbug for
+     now.  This makes debugging easier.  */
+  if (es_setvbuf (inbound, NULL, _IONBF, 0))
+    return gpg_error_from_syserror ();
+  if (es_setvbuf (outbound, NULL, _IONBF, 0))
+    return gpg_error_from_syserror ();
+
   tls->inbound = inbound;
   tls->outbound = outbound;
   return 0;
diff --git a/src/util.c b/src/util.c
new file mode 100644 (file)
index 0000000..d36ae79
--- /dev/null
@@ -0,0 +1,140 @@
+/* util.c - Utility functions
+ * Copyright (C) 2014 g10 Code GmbH
+ *
+ * This file is part of NTBTLS
+ *
+ * NTBTLS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NTBTLS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "ntbtls-int.h"
+
+\f
+const char *
+compat_identification (void)
+{
+  /* For a complete list of copyright holders see the file AUTHORS in
+     the source distribution.  */
+  static const char blurb[] =
+    "\n\n"
+    "This is NTBTLS " PACKAGE_VERSION " - Not Too Bad TLS\n"
+    "Copyright (C) 2014 g10 Code GmbH\n"
+    "Copyright (C) 2006-2014 Brainspark B.V.\n"
+    "\n"
+    "(" BUILD_REVISION " " BUILD_TIMESTAMP ")\n"
+    "\n\n";
+  return blurb;
+}
+
+
+/* Version number parsing.  */
+
+/* This function parses the first portion of the version number S and
+   stores it in *NUMBER.  On success, this function returns a pointer
+   into S starting with the first character, which is not part of the
+   initial number portion; on failure, NULL is returned.  */
+static const char*
+parse_version_number (const unsigned char *s, int *number)
+{
+  int val = 0;
+
+  if (*s == '0' && isdigit(s[1]))
+    return NULL; /* Leading zeros are not allowed.  */
+  for ( ; isdigit (*s); s++)
+    {
+      val *= 10;
+      val += *s - '0';
+    }
+  *number = val;
+  return val < 0? NULL : s;
+}
+
+
+/* This function breaks up the complete string representation of the
+   version number S, which is of the following structure:
+
+     <major number>.<minor number>.<micro number><patch level>
+
+   The major, minor and micro number components will be stored in
+   *MAJOR, *MINOR and *MICRO.
+
+   On success, the last component, the patch level, will be returned;
+   in failure, NULL will be returned.  */
+
+static const char *
+parse_version_string (const char *s, int *major, int *minor, int *micro )
+{
+  s = parse_version_number (s, major);
+  if (!s || *s != '.')
+    return NULL;
+  s++;
+  s = parse_version_number (s, minor);
+  if (!s || *s != '.')
+    return NULL;
+  s++;
+  s = parse_version_number (s, micro);
+  return s; /* Patchlevel or NULL on error in MICRO. */
+}
+
+
+/* If REQ_VERSION is non-NULL, check that the version of the library
+   is at minimum the requested one.  Returns the string representation
+   of the library version if the condition is satisfied; return NULL
+   if the requested version is newer than that of the library.
+
+   If a NULL is passed to this function, no check is done, but the
+   string representation of the library version is returned.  */
+const char *
+_ntbtls_check_version (const char *req_version)
+{
+  const char *ver = PACKAGE_VERSION;
+  int my_major, my_minor, my_micro;
+  int rq_major, rq_minor, rq_micro;
+  const char *my_plvl;
+
+  if (req_version && req_version[0] == 1 && req_version[1] == 1)
+    return compat_identification ();
+
+  /* Initialize library.  */
+
+  /* Check whether the caller only want the version number.  */
+  if  (!req_version)
+    return ver;
+
+  /* Parse own version number.  */
+  my_plvl = parse_version_string (ver, &my_major, &my_minor, &my_micro);
+  if  (!my_plvl)
+    return NULL;  /* Can't happen.  */
+
+  /* Parse requested version number.  */
+  if (!parse_version_string (req_version, &rq_major, &rq_minor, &rq_micro))
+    return NULL;  /* Req version string is invalid.  */
+
+  /* Compare version numbers.  */
+  if (my_major > rq_major
+      || (my_major == rq_major && my_minor > rq_minor)
+      || (my_major == rq_major && my_minor == rq_minor                                                  && my_micro > rq_micro)
+      || (my_major == rq_major && my_minor == rq_minor
+          && my_micro == rq_micro))
+    {
+      return ver; /* Okay.  */
+    }
+
+  return NULL; /* Not sufficent.  */
+}
index e9e0e16..1c16b17 100644 (file)
@@ -57,6 +57,7 @@ memcmpct (const void *_a, const void *_b, size_t len)
 
 
 /*-- debug.c --*/
+void _ntbtls_set_debug (int level, const char *prefix, gpgrt_stream_t stream);
 
 /* FIXME: Add a public version of _GPGRT_GCC_A_PRINTF to libgpg-error.
    Use variadic macros is possibel to check the level before calling
@@ -67,11 +68,15 @@ void _ntbtls_debug_buf (int level, const char *text,
                         const void *buf, size_t len);
 void _ntbtls_debug_bug (const char *file, int line);
 void _ntbtls_debug_ret (int level, const char *name, gpg_error_t err);
+void _ntbtls_debug_mpi (int level, const char *text, gcry_mpi_t a);
+void _ntbtls_debug_sxp (int level, const char *text, gcry_sexp_t a);
 
 #define debug_msg          _ntbtls_debug_msg
 #define debug_buf(a,b,c,d) _ntbtls_debug_buf ((a),(b),(c),(d))
 #define debug_bug()        _ntbtls_debug_bug (__FILE__, __LINE__)
 #define debug_ret(l,n,e)   _ntbtls_debug_ret ((l),(n),(e))
+#define debug_mpi(l,t,a)   _ntbtls_debug_mpi ((l),(t),(a))
+#define debug_sxp(l,t,a)   _ntbtls_debug_sxp ((l),(t),(a))
 
 
 
index c7e0800..d25d3e0 100644 (file)
 #include "visibility.h"
 
 
+const char *
+ntbtls_check_version (const char *req_version)
+{
+  return _ntbtls_check_version (req_version);
+}
+
+
+void
+ntbtls_set_debug (int level, const char *prefix, gpgrt_stream_t stream)
+{
+  _ntbtls_set_debug (level, prefix, stream);
+}
+
 
 gpg_error_t
 ntbtls_new (ntbtls_t *r_tls, unsigned int flags)
index d65d08a..e5fe0d5 100644 (file)
@@ -41,6 +41,8 @@
 # define MARK_VISIBLE(name) /* */
 #endif
 
+MARK_VISIBLE (ntbtls_check_version)
+MARK_VISIBLE (ntbtls_set_debug)
 MARK_VISIBLE (ntbtls_new)
 MARK_VISIBLE (ntbtls_release)
 MARK_VISIBLE (ntbtls_set_transport)
@@ -56,7 +58,10 @@ MARK_VISIBLE (ntbtls_handshake)
 /* To avoid accidental use of the public functions inside ntbtls,
    we redefine them to catch such errors.  */
 
-#define ntbtls_init                  _ntbtls_USE_THE_UNDERSCORED_FUNCTION
+#define ntbtls_check_version         _ntbtls_USE_THE_UNDERSCORED_FUNCTION
+#define ntbtls_set_debug             _ntbtls_USE_THE_UNDERSCORED_FUNCTION
+#define ntbtls_new                   _ntbtls_USE_THE_UNDERSCORED_FUNCTION
+#define ntbtls_released              _ntbtls_USE_THE_UNDERSCORED_FUNCTION
 #define ntbtls_set_transport         _ntbtls_USE_THE_UNDERSCORED_FUNCTION
 #define ntbtls_get_stream            _ntbtls_USE_THE_UNDERSCORED_FUNCTION
 #define ntbtls_handshake             _ntbtls_USE_THE_UNDERSCORED_FUNCTION
index cbbc3b2..8c497f9 100644 (file)
@@ -52,7 +52,6 @@ struct x509_privkey_s
 gpg_error_t
 _ntbtls_x509_new (x509_cert_t *r_cert)
 {
-  gpg_error_t err;
   x509_cert_t cert;
 
   *r_cert = NULL;
@@ -61,6 +60,8 @@ _ntbtls_x509_new (x509_cert_t *r_cert)
   if (!cert)
     return gpg_error_from_syserror ();
 
+  *r_cert = cert;
+
   return 0;
 }
 
@@ -85,7 +86,6 @@ gpg_error_t
 _ntbtls_x509_append_cert (x509_cert_t cert, const void *der, size_t derlen)
 {
   gpg_error_t err;
-  ksba_cert_t crt;
 
   if (!cert)
     return gpg_error (GPG_ERR_INV_ARG);
@@ -135,7 +135,7 @@ _ntbtls_x509_append_cert (x509_cert_t cert, const void *der, size_t derlen)
 const unsigned char *
 _ntbtls_x509_get_cert (x509_cert_t cert, int idx, size_t *r_derlen)
 {
-  for (; cert && idx; cert = cert->next, idx--)
+  for (; cert && idx >= 0; cert = cert->next, idx--)
     ;
   if (!cert)
     return NULL;
@@ -144,9 +144,52 @@ _ntbtls_x509_get_cert (x509_cert_t cert, int idx, size_t *r_derlen)
 }
 
 
+/* Return the public key from the certificate with index IDX in CERT
+   and store it as an S-expression at R_PK.  On error return an error
+   code and store NULL at R_PK.  */
+gpg_error_t
+_ntbtls_x509_get_pk (x509_cert_t cert, int idx, gcry_sexp_t *r_pk)
+{
+  gpg_error_t err;
+  ksba_sexp_t pk;
+  size_t pklen;
+  gcry_sexp_t s_pk;
+
+  if (!r_pk)
+    return gpg_error (GPG_ERR_INV_ARG);
+  *r_pk = NULL;
+
+  if (idx < 0)
+    gpg_error (GPG_ERR_INV_INDEX);
+  for (; cert && idx; cert = cert->next, idx--)
+    ;
+  if (!cert)
+    return gpg_error (GPG_ERR_NO_DATA);
+
+  pk = ksba_cert_get_public_key (cert->crt);
+  pklen = gcry_sexp_canon_len (pk, 0, NULL, NULL);
+  if (!pklen)
+    {
+      /* CRT is NULL or other problem.  */
+      ksba_free (pk);
+      return gpg_error (GPG_ERR_NO_PUBKEY);
+    }
+
+  err = gcry_sexp_sscan (&s_pk, NULL, pk, pklen);
+  ksba_free (pk);
+  if (err)
+    {
+      debug_ret (1, "gcry_sexp_scan", err);
+      return err;
+    }
+  *r_pk = s_pk;
+  return 0;
+}
+
+
 
 gpg_error_t
-_ntbtls_x509_verify (x509_cert_t cert, x509_cert_t trust_ca, x509_crl_t ca_crl,
+_ntbtls_x509_verify (x509_cert_t chain, x509_cert_t trust_ca, x509_crl_t ca_crl,
                      const char *cn, int *r_flags)
 {
   //FIXME:
@@ -158,7 +201,7 @@ _ntbtls_x509_verify (x509_cert_t cert, x509_cert_t trust_ca, x509_crl_t ca_crl,
 /* Return true if PRIVKEY can do an operation using the public key
    algorithm PKALGO.  */
 int
-_ntbtls_x509_can_do (x509_privkey_t privkey, pk_algo_t pkalgo)
+_ntbtls_x509_can_do (x509_privkey_t privkey, pk_algo_t pk_alg)
 {
   if (!privkey)
     return 0;