]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added ability to hash and hmac with VIA padlock.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 1 Oct 2011 18:04:56 +0000 (20:04 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 1 Oct 2011 18:05:36 +0000 (20:05 +0200)
lib/accelerated/intel/Makefile.am
lib/accelerated/intel/aes-padlock.c
lib/accelerated/intel/aes-padlock.h
lib/accelerated/intel/sha-padlock.c [new file with mode: 0644]
lib/gnutls_str.h

index cbb00e95c82ca5df1660ce0179fc7c767cf90449..315c2775a147a51c78fa3ec482fa441e4be326fa 100644 (file)
@@ -34,7 +34,7 @@ EXTRA_DIST = README license.txt
 
 noinst_LTLIBRARIES = libintel.la
 
-libintel_la_SOURCES = aes-x86.c aes-padlock.c aes-gcm-padlock.c aes-padlock.h aes-x86.h x86.h
+libintel_la_SOURCES = sha-padlock.c aes-x86.c aes-padlock.c aes-gcm-padlock.c aes-padlock.h aes-x86.h x86.h
 
 if ASM_X86_64
 AM_CPPFLAGS += -DASM_X86_64
index 881ab280ffc26d592eb3405ae4773815117f324d..4e7b8cc2a0b6c41bbd1d24295ec8de12e1ff417f 100644 (file)
 #include <aes-padlock.h>
 
 static int
-aes_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx, int enc)
+aes_cipher_init (gnutls_cipher_algorithm_t algorithm, void **_ctx, int enc)
 {
-    /* we use key size to distinguish */
-    if (algorithm != GNUTLS_CIPHER_AES_128_CBC
-        && algorithm != GNUTLS_CIPHER_AES_192_CBC
-        && algorithm != GNUTLS_CIPHER_AES_256_CBC)
-        return GNUTLS_E_INVALID_REQUEST;
-
-    *_ctx = gnutls_calloc(1, sizeof(struct padlock_ctx));
-    if (*_ctx == NULL) {
-        gnutls_assert();
-        return GNUTLS_E_MEMORY_ERROR;
+  /* we use key size to distinguish */
+  if (algorithm != GNUTLS_CIPHER_AES_128_CBC
+      && algorithm != GNUTLS_CIPHER_AES_192_CBC
+      && algorithm != GNUTLS_CIPHER_AES_256_CBC)
+    return GNUTLS_E_INVALID_REQUEST;
+
+  *_ctx = gnutls_calloc (1, sizeof (struct padlock_ctx));
+  if (*_ctx == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_MEMORY_ERROR;
     }
 
-    ((struct padlock_ctx *) (*_ctx))->enc = enc;
-    return 0;
+  ((struct padlock_ctx *) (*_ctx))->enc = enc;
+  return 0;
 }
 
-int padlock_aes_cipher_setkey(void *_ctx, const void *userkey, size_t keysize)
+int
+padlock_aes_cipher_setkey (void *_ctx, const void *userkey, size_t keysize)
 {
-    struct padlock_ctx *ctx = _ctx;
-    struct padlock_cipher_data *pce;
+  struct padlock_ctx *ctx = _ctx;
+  struct padlock_cipher_data *pce;
 #ifdef HAVE_LIBNETTLE
-    struct aes_ctx nc;
+  struct aes_ctx nc;
 #endif
 
-    memset(_ctx, 0, sizeof(struct padlock_cipher_data));
+  memset (_ctx, 0, sizeof (struct padlock_cipher_data));
 
-    pce = ALIGN16(&ctx->expanded_key);
+  pce = ALIGN16 (&ctx->expanded_key);
 
-    pce->cword.b.encdec = (ctx->enc == 0);
+  pce->cword.b.encdec = (ctx->enc == 0);
 
-    switch (keysize) {
+  switch (keysize)
+    {
     case 16:
-        pce->cword.b.ksize = 0;
-        pce->cword.b.rounds = 10;
-        memcpy(pce->ks.rd_key, userkey, 16);
-        pce->cword.b.keygen = 0;
-        break;
+      pce->cword.b.ksize = 0;
+      pce->cword.b.rounds = 10;
+      memcpy (pce->ks.rd_key, userkey, 16);
+      pce->cword.b.keygen = 0;
+      break;
 #ifdef HAVE_LIBNETTLE
     case 24:
-        pce->cword.b.ksize = 1;
-        pce->cword.b.rounds = 12;
-        goto common_24_32;
+      pce->cword.b.ksize = 1;
+      pce->cword.b.rounds = 12;
+      goto common_24_32;
     case 32:
-        pce->cword.b.ksize = 2;
-        pce->cword.b.rounds = 14;
-      common_24_32:
-        /* expand key using nettle */
-        if (ctx->enc)
-            aes_set_encrypt_key(&nc, keysize, userkey);
-        else 
-            aes_set_decrypt_key(&nc, keysize, userkey);
-
-        memcpy(pce->ks.rd_key, nc.keys, sizeof(nc.keys));
-        pce->ks.rounds = nc.nrounds;
-
-        pce->cword.b.keygen = 1;
-        break;
+      pce->cword.b.ksize = 2;
+      pce->cword.b.rounds = 14;
+    common_24_32:
+      /* expand key using nettle */
+      if (ctx->enc)
+        aes_set_encrypt_key (&nc, keysize, userkey);
+      else
+        aes_set_decrypt_key (&nc, keysize, userkey);
+
+      memcpy (pce->ks.rd_key, nc.keys, sizeof (nc.keys));
+      pce->ks.rounds = nc.nrounds;
+
+      pce->cword.b.keygen = 1;
+      break;
 #endif
     default:
-        return gnutls_assert_val(GNUTLS_E_ENCRYPTION_FAILED);
+      return gnutls_assert_val (GNUTLS_E_ENCRYPTION_FAILED);
     }
 
-    padlock_reload_key();
+  padlock_reload_key ();
 
-    return 0;
+  return 0;
 }
 
-static int aes_setiv(void *_ctx, const void *iv, size_t iv_size)
+static int
+aes_setiv (void *_ctx, const void *iv, size_t iv_size)
 {
-    struct padlock_ctx *ctx = _ctx;
-    struct padlock_cipher_data *pce;
+  struct padlock_ctx *ctx = _ctx;
+  struct padlock_cipher_data *pce;
 
-    pce = ALIGN16(&ctx->expanded_key);
+  pce = ALIGN16 (&ctx->expanded_key);
 
-    memcpy(pce->iv, iv, 16);
+  memcpy (pce->iv, iv, 16);
 
-    return 0;
+  return 0;
 }
 
 static int
-padlock_aes_cbc_encrypt(void *_ctx, const void *src, size_t src_size,
-                    void *dst, size_t dst_size)
+padlock_aes_cbc_encrypt (void *_ctx, const void *src, size_t src_size,
+                         void *dst, size_t dst_size)
 {
-    struct padlock_ctx *ctx = _ctx;
-    struct padlock_cipher_data *pce;
+  struct padlock_ctx *ctx = _ctx;
+  struct padlock_cipher_data *pce;
 
-    pce = ALIGN16(&ctx->expanded_key);
+  pce = ALIGN16 (&ctx->expanded_key);
 
-    padlock_cbc_encrypt(dst, src, pce, src_size);
+  padlock_cbc_encrypt (dst, src, pce, src_size);
 
-    return 0;
+  return 0;
 }
 
 
 static int
-padlock_aes_cbc_decrypt(void *_ctx, const void *src, size_t src_size,
-                    void *dst, size_t dst_size)
+padlock_aes_cbc_decrypt (void *_ctx, const void *src, size_t src_size,
+                         void *dst, size_t dst_size)
 {
-    struct padlock_ctx *ctx = _ctx;
-    struct padlock_cipher_data *pcd;
+  struct padlock_ctx *ctx = _ctx;
+  struct padlock_cipher_data *pcd;
 
-    pcd = ALIGN16(&ctx->expanded_key);
+  pcd = ALIGN16 (&ctx->expanded_key);
 
-    padlock_cbc_encrypt(dst, src, pcd, src_size);
+  padlock_cbc_encrypt (dst, src, pcd, src_size);
 
-    return 0;
+  return 0;
 }
 
-static void aes_deinit(void *_ctx)
+static void
+aes_deinit (void *_ctx)
 {
-    gnutls_free(_ctx);
+  gnutls_free (_ctx);
 }
 
 static const gnutls_crypto_cipher_st aes_padlock_struct = {
-    .init = aes_cipher_init,
-    .setkey = padlock_aes_cipher_setkey,
-    .setiv = aes_setiv,
-    .encrypt = padlock_aes_cbc_encrypt,
-    .decrypt = padlock_aes_cbc_decrypt,
-    .deinit = aes_deinit,
+  .init = aes_cipher_init,
+  .setkey = padlock_aes_cipher_setkey,
+  .setiv = aes_setiv,
+  .encrypt = padlock_aes_cbc_encrypt,
+  .decrypt = padlock_aes_cbc_decrypt,
+  .deinit = aes_deinit,
 };
 
-static int check_padlock(void)
+static int
+check_padlock (void)
+{
+  unsigned int edx = padlock_capability ();
+
+  return ((edx & (0x3 << 6)) == (0x3 << 6));
+}
+
+static int
+check_phe (void)
 {
-    unsigned int edx = padlock_capability();
+  unsigned int edx = padlock_capability ();
 
-    return ((edx & (0x3 << 6)) == (0x3 << 6));
+  return ((edx & (0x3 << 10)) == (0x3 << 10));
 }
 
-static unsigned check_via(void)
+static unsigned
+check_via (void)
 {
-    unsigned int a, b, c, d;
-    _gnutls_cpuid(0, &a, &b, &c, &d);
+  unsigned int a, b, c, d;
+  _gnutls_cpuid (0, &a, &b, &c, &d);
 
-    if ((memcmp(&b, "Cent", 4) == 0 &&
-         memcmp(&d, "aurH", 4) == 0 && memcmp(&c, "auls", 4) == 0)) {
-        return 1;
+  if ((memcmp (&b, "Cent", 4) == 0 &&
+       memcmp (&d, "aurH", 4) == 0 && memcmp (&c, "auls", 4) == 0))
+    {
+      return 1;
     }
 
-    return 0;
+  return 0;
 }
 
-void register_padlock_crypto(void)
+void
+register_padlock_crypto (void)
 {
-    int ret;
-
-    /* Only enable the 32-bit padlock variant, until
-     * the 64-bit code is tested.
-     */
-    if (check_via() == 0)
-        return;
-
-    if (check_padlock()) {
-        _gnutls_debug_log("Padlock AES accelerator was detected\n");
-        ret =
-            gnutls_crypto_single_cipher_register(GNUTLS_CIPHER_AES_128_CBC,
-                                                 80, &aes_padlock_struct);
-        if (ret < 0) {
-            gnutls_assert();
+  int ret;
+
+  /* Only enable the 32-bit padlock variant, until
+   * the 64-bit code is tested.
+   */
+  if (check_via () == 0)
+    return;
+
+  if (check_padlock ())
+    {
+      _gnutls_debug_log ("Padlock AES accelerator was detected\n");
+      ret =
+          gnutls_crypto_single_cipher_register
+          (GNUTLS_CIPHER_AES_128_CBC, 80, &aes_padlock_struct);
+      if (ret < 0)
+        {
+          gnutls_assert ();
         }
 
-        /* register GCM ciphers */
-        ret =
-            gnutls_crypto_single_cipher_register(GNUTLS_CIPHER_AES_128_GCM,
-                                                 80,
-                                                 &aes_gcm_padlock_struct);
-        if (ret < 0) {
-            gnutls_assert();
+      /* register GCM ciphers */
+      ret =
+          gnutls_crypto_single_cipher_register
+          (GNUTLS_CIPHER_AES_128_GCM, 80, &aes_gcm_padlock_struct);
+      if (ret < 0)
+        {
+          gnutls_assert ();
         }
-    }
 #ifdef HAVE_LIBNETTLE
-    ret =
-        gnutls_crypto_single_cipher_register(GNUTLS_CIPHER_AES_192_CBC,
-                                             80, &aes_padlock_struct);
-    if (ret < 0) {
-        gnutls_assert();
-    }
+      ret =
+          gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_192_CBC,
+                                                80, &aes_padlock_struct);
+      if (ret < 0)
+        {
+          gnutls_assert ();
+        }
 
-    ret =
-        gnutls_crypto_single_cipher_register(GNUTLS_CIPHER_AES_256_CBC,
-                                             80, &aes_padlock_struct);
-    if (ret < 0) {
-        gnutls_assert();
+      ret =
+          gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_CBC,
+                                                80, &aes_padlock_struct);
+      if (ret < 0)
+        {
+          gnutls_assert ();
+        }
+
+      ret =
+          gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_GCM,
+                                                80,
+                                                &aes_gcm_padlock_struct);
+      if (ret < 0)
+        {
+          gnutls_assert ();
+        }
+
+#endif
     }
 
-    ret =
-        gnutls_crypto_single_cipher_register(GNUTLS_CIPHER_AES_256_GCM,
-                                             80, &aes_gcm_padlock_struct);
-    if (ret < 0) {
-        gnutls_assert();
+  if (check_phe())
+    {
+      ret =
+          gnutls_crypto_single_digest_register (GNUTLS_DIG_SHA1,
+                                             80, &sha_padlock_struct);
+      if (ret < 0)
+        {
+          gnutls_assert ();
+        }
+
+      ret =
+          gnutls_crypto_single_digest_register (GNUTLS_DIG_SHA256,
+                                             80, &sha_padlock_struct);
+      if (ret < 0)
+        {
+          gnutls_assert ();
+        }
+
+      ret =
+          gnutls_crypto_single_mac_register (GNUTLS_MAC_SHA1,
+                                             80, &hmac_sha_padlock_struct);
+      if (ret < 0)
+        {
+          gnutls_assert ();
+        }
+
+      ret =
+          gnutls_crypto_single_mac_register (GNUTLS_MAC_SHA256,
+                                             80, &hmac_sha_padlock_struct);
+      if (ret < 0)
+        {
+          gnutls_assert ();
+        }
     }
-#endif
 
-    return;
+  return;
 }
index d15a6b9de568bf7797bd7f2c93c7b7e7b24e9556..c3798d6b0e9707b8ac2cc96780f24397f0b72360 100644 (file)
@@ -2,6 +2,7 @@
 # define AES_PADLOCK_H
 
 #include <gnutls_int.h>
+#include <aes-x86.h>
 
 struct padlock_cipher_data {
     unsigned char iv[16];       /* Initialization vector */
@@ -27,6 +28,8 @@ struct padlock_ctx {
 };
 
 extern const gnutls_crypto_cipher_st aes_gcm_padlock_struct;
+extern const gnutls_crypto_mac_st hmac_sha_padlock_struct;
+extern const gnutls_crypto_digest_st sha_padlock_struct;
 
 int padlock_aes_cipher_setkey(void *_ctx, const void *userkey, size_t keysize);
 
diff --git a/lib/accelerated/intel/sha-padlock.c b/lib/accelerated/intel/sha-padlock.c
new file mode 100644 (file)
index 0000000..8c707fa
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include <gnutls_int.h>
+#include <gnutls_hash_int.h>
+#include <gnutls_errors.h>
+#include <nettle/sha.h>
+#include <aes-padlock.h>
+
+/* This enables padlock's SHA capabilities for HMAC operations. 
+ * Unfortunately due to padlock's inner workings only the final hash
+ * of the HMAC() is being hardware accelerated. The rest is plain
+ * software.
+ */
+
+typedef void (*update_func) (void *, unsigned, const uint8_t *);
+typedef void (*digest_func) (void *, unsigned, uint8_t *);
+typedef void (*padlock_hash_func) (void* digest, const void* src, size_t len);
+
+#define SHA_BLOCK_SIZE 64
+#define MAX_SHA_DIGEST_SIZE 32
+#define IPAD 0x36
+#define OPAD 0x5c
+
+struct padlock_hmac_ctx
+{
+  gnutls_buffer_st buf;
+
+  gnutls_mac_algorithm_t algo;
+  size_t length;
+
+  unsigned char ipad[SHA_BLOCK_SIZE];
+  unsigned char opad[SHA_BLOCK_SIZE];
+};
+
+static int
+wrap_padlock_hmac_init (gnutls_mac_algorithm_t algo, void **_ctx)
+{
+  struct padlock_hmac_ctx *ctx;
+  
+  if (algo != GNUTLS_MAC_SHA1 && algo != GNUTLS_MAC_SHA256)
+    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+  ctx = gnutls_calloc (1, sizeof (struct padlock_hmac_ctx));
+  if (ctx == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  ctx->algo = algo;
+  _gnutls_buffer_init(&ctx->buf);
+
+  *_ctx = ctx;
+
+  return 0;
+}
+
+
+static int
+wrap_padlock_hmac_setkey (void *_ctx, const void *key, size_t key_size)
+{
+  struct padlock_hmac_ctx *ctx = _ctx;
+  padlock_hash_func hash;
+  unsigned char hkey[MAX_SHA_DIGEST_SIZE];
+
+  if (key_size > SHA_BLOCK_SIZE) 
+    {
+      if (ctx->algo == GNUTLS_MAC_SHA1)
+        hash = padlock_sha1_oneshot;
+      else
+        hash = padlock_sha256_oneshot;
+
+      hash(hkey, key, key_size);
+      key = hkey;
+      key_size = _gnutls_hmac_get_algo_len(ctx->algo);
+    }
+
+  memset (ctx->ipad, IPAD, SHA_BLOCK_SIZE);
+  memxor (ctx->ipad, key, key_size);
+
+  _gnutls_buffer_append_data( &ctx->buf, ctx->ipad, SHA_BLOCK_SIZE);
+
+  return GNUTLS_E_SUCCESS;
+}
+
+static void
+wrap_padlock_hmac_reset (void *_ctx)
+{
+  struct padlock_hmac_ctx *ctx = _ctx;
+
+  _gnutls_buffer_reset(&ctx->buf);
+  _gnutls_buffer_append_data( &ctx->buf, ctx->ipad, SHA_BLOCK_SIZE);
+}
+
+static int
+wrap_padlock_hmac_update (void *_ctx, const void *text, size_t textsize)
+{
+  struct padlock_hmac_ctx *ctx = _ctx;
+
+  _gnutls_buffer_append_data( &ctx->buf, text, textsize);
+
+  return GNUTLS_E_SUCCESS;
+}
+
+static void
+wrap_padlock_hmac_deinit (void *_ctx)
+{
+  struct padlock_hmac_ctx *ctx = _ctx;
+
+  _gnutls_buffer_clear(&ctx->buf);
+  gnutls_free (ctx);
+}
+
+static int
+wrap_padlock_hmac_output (void *_ctx, void *digest, size_t digestsize)
+{
+  struct padlock_hmac_ctx *ctx = _ctx;
+  unsigned char pad[SHA_BLOCK_SIZE + MAX_SHA_DIGEST_SIZE];
+  padlock_hash_func hash;
+
+  if (ctx->algo == GNUTLS_MAC_SHA1)
+    hash = padlock_sha1_oneshot;
+  else
+    hash = padlock_sha256_oneshot;
+
+  if (digestsize < ctx->length)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_SHORT_MEMORY_BUFFER;
+    }
+
+  memcpy (pad, ctx->opad, SHA_BLOCK_SIZE);
+  hash(&pad[SHA_BLOCK_SIZE], ctx->buf.data, ctx->buf.length);
+
+  hash(digest, pad, ctx->length + SHA_BLOCK_SIZE);
+
+  return 0;
+}
+
+
+static int wrap_padlock_hmac_fast(gnutls_mac_algorithm_t algo, 
+  const void *key, size_t key_size, const void* text, size_t text_size, 
+  void* digest)
+{
+  unsigned char *pad;
+  unsigned char pad2[SHA_BLOCK_SIZE + MAX_SHA_DIGEST_SIZE];
+  unsigned char hkey[MAX_SHA_DIGEST_SIZE];
+  padlock_hash_func hash;
+
+  if (algo == GNUTLS_MAC_SHA1)
+    hash = padlock_sha1_oneshot;
+  else
+    hash = padlock_sha256_oneshot;
+
+  if (key_size > SHA_BLOCK_SIZE) 
+    {
+      hash(hkey, key, key_size);
+      key = hkey;
+      key_size = _gnutls_hmac_get_algo_len(algo);
+    }
+
+  pad = gnutls_malloc(text_size + SHA_BLOCK_SIZE);
+  if (pad == NULL)
+    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+  
+  memset (pad, IPAD, SHA_BLOCK_SIZE);
+  memxor (pad, key, key_size);
+  
+  memcpy (&pad[SHA_BLOCK_SIZE], text, text_size);
+  
+  hash(&pad2[SHA_BLOCK_SIZE], pad, text_size + SHA_BLOCK_SIZE);
+  
+  gnutls_free(pad);
+
+  memset (pad2, OPAD, SHA_BLOCK_SIZE);
+  memxor (pad2, key, key_size);
+  
+  hash(digest, pad2, SHA1_DIGEST_SIZE + SHA_BLOCK_SIZE);
+  
+  return 0;
+}
+
+const gnutls_crypto_mac_st hmac_sha_padlock_struct = {
+  .init = wrap_padlock_hmac_init,
+  .setkey = wrap_padlock_hmac_setkey,
+  .hash = wrap_padlock_hmac_update,
+  .reset = wrap_padlock_hmac_reset,
+  .output = wrap_padlock_hmac_output,
+  .deinit = wrap_padlock_hmac_deinit,
+  .fast = wrap_padlock_hmac_fast
+};
+
+
+struct padlock_hash_ctx
+{
+  gnutls_buffer_st buf;
+  gnutls_digest_algorithm_t algo;
+  size_t length; /* output length */
+};
+
+static int
+wrap_padlock_hash_init (gnutls_digest_algorithm_t algo, void **_ctx)
+{
+  struct padlock_hash_ctx *ctx;
+  
+  if (algo != GNUTLS_DIG_SHA1 && algo != GNUTLS_DIG_SHA256)
+    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+  ctx = gnutls_calloc (1, sizeof (struct padlock_hash_ctx));
+  if (ctx == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  ctx->algo = algo;
+  _gnutls_buffer_init(&ctx->buf);
+
+  *_ctx = ctx;
+
+  return 0;
+}
+
+static int
+wrap_padlock_hash_update (void *_ctx, const void *text, size_t textsize)
+{
+  struct padlock_hash_ctx *ctx = _ctx;
+
+  _gnutls_buffer_append_data( &ctx->buf, text, textsize);
+
+  return GNUTLS_E_SUCCESS;
+}
+
+static void
+wrap_padlock_hash_deinit (void *_ctx)
+{
+  struct padlock_hash_ctx *ctx = _ctx;
+
+  _gnutls_buffer_clear(&ctx->buf);
+  gnutls_free (ctx);
+}
+
+static int
+wrap_padlock_hash_output (void *_ctx, void *digest, size_t digestsize)
+{
+  struct padlock_hash_ctx *ctx = _ctx;
+
+  if (ctx->algo == GNUTLS_DIG_SHA1)
+    padlock_sha1_oneshot (digest, ctx->buf.data, ctx->buf.length);
+  else
+    padlock_sha256_oneshot (digest, ctx->buf.data, ctx->buf.length);
+
+  return 0;
+}
+
+static int wrap_padlock_hash_fast(gnutls_digest_algorithm_t algo, 
+  const void* text, size_t text_size, 
+  void* digest)
+{
+  if (algo == GNUTLS_DIG_SHA1)
+    padlock_sha1_oneshot (digest, text, text_size);
+  else
+    padlock_sha256_oneshot (digest, text, text_size);
+  
+  return 0;
+}
+
+const gnutls_crypto_digest_st sha_padlock_struct = {
+  .init = wrap_padlock_hash_init,
+  .hash = wrap_padlock_hash_update,
+  .output = wrap_padlock_hash_output,
+  .deinit = wrap_padlock_hash_deinit,
+  .fast = wrap_padlock_hash_fast
+};
index dbf299c0cb337eaeabb6934496406ccf342e7d7c..3b6562e4c4dc02824678b086e6a1aec88689fe09 100644 (file)
@@ -41,6 +41,12 @@ typedef struct
 
 void _gnutls_buffer_init (gnutls_buffer_st *);
 void _gnutls_buffer_clear (gnutls_buffer_st *);
+inline static void _gnutls_buffer_reset (gnutls_buffer_st * buf)
+{
+  buf->data = buf->allocd;
+  buf->length = 0;
+}
+
 int _gnutls_buffer_resize (gnutls_buffer_st *, size_t new_size);
 
 int _gnutls_buffer_append_str (gnutls_buffer_st *, const char *str);