]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Updated cryptodev code to support the linux cryptodev extensions.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 2 Oct 2010 20:15:02 +0000 (22:15 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 2 Oct 2010 21:26:45 +0000 (23:26 +0200)
Removed the clone() capability from HMAC. It was never used and having
it prevents using it with hardware accelerators that might not have this
capability.

lib/cryptodev.c
lib/gcrypt/mac.c
lib/gnutls_hash_int.c
lib/includes/gnutls/crypto.h
lib/nettle/mac.c

index 3001a59cc2d6eea0c0fa8f9c4bcc8e5ad29f9709..29f2ee9ccab2ef51be7797ad545204143081f802 100644 (file)
 # define EALG_MAX_BLOCK_LEN 16
 #endif
 
-
 static int cryptodev_fd = -1;
 
+static int register_mac (int cfd);
+
 struct cryptodev_ctx
 {
   struct session_op sess;
@@ -79,18 +80,7 @@ cryptodev_cipher_init (gnutls_cipher_algorithm_t algorithm, void **_ctx)
 
   ctx = *_ctx;
 
-  if (ioctl (cryptodev_fd, CRIOGET, &ctx->cfd))
-    {
-      gnutls_assert ();
-      return GNUTLS_E_CRYPTODEV_IOCTL_ERROR;
-    }
-
-  if (fcntl (ctx->cfd, F_SETFD, 1) == -1)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_CRYPTODEV_IOCTL_ERROR;
-    }
-
+  ctx->cfd = cryptodev_fd;
   ctx->sess.cipher = cipher;
   ctx->sess.key = ctx->key;
   ctx->cryp.iv = ctx->iv;
@@ -99,7 +89,7 @@ cryptodev_cipher_init (gnutls_cipher_algorithm_t algorithm, void **_ctx)
 }
 
 static int
-cryptodev_setkey (void *_ctx, const void *key, size_t keysize)
+cryptodev_cipher_setkey (void *_ctx, const void *key, size_t keysize)
 {
   struct cryptodev_ctx *ctx = _ctx;
 
@@ -114,7 +104,6 @@ cryptodev_setkey (void *_ctx, const void *key, size_t keysize)
   ctx->cryp.ses = ctx->sess.ses;
 
   return 0;
-
 }
 
 static int
@@ -169,37 +158,18 @@ cryptodev_deinit (void *_ctx)
   struct cryptodev_ctx *ctx = _ctx;
 
   ioctl(ctx->cfd, CIOCFSESSION, &ctx->sess);
-  close (ctx->cfd);
   gnutls_free (ctx);
 }
 
 static const gnutls_crypto_cipher_st cipher_struct = {
   .init = cryptodev_cipher_init,
-  .setkey = cryptodev_setkey,
+  .setkey = cryptodev_cipher_setkey,
   .setiv = cryptodev_setiv,
   .encrypt = cryptodev_encrypt,
   .decrypt = cryptodev_decrypt,
   .deinit = cryptodev_deinit,
 };
 
-struct cipher_map
-{
-  gnutls_cipher_algorithm_t gnutls_cipher;
-  int cryptodev_cipher;
-  int keylen;
-};
-
-static const struct cipher_map cipher_map[] = {
-  {GNUTLS_CIPHER_3DES_CBC, CRYPTO_3DES_CBC, 21},
-  {GNUTLS_CIPHER_AES_128_CBC, CRYPTO_AES_CBC, 16},
-  {GNUTLS_CIPHER_AES_192_CBC, CRYPTO_AES_CBC, 24},
-  {GNUTLS_CIPHER_AES_256_CBC, CRYPTO_AES_CBC, 32},
-  {GNUTLS_CIPHER_CAMELLIA_128_CBC, CRYPTO_CAMELLIA_CBC, 16},
-  {GNUTLS_CIPHER_CAMELLIA_256_CBC, CRYPTO_CAMELLIA_CBC, 24},
-  {GNUTLS_CIPHER_DES_CBC, CRYPTO_DES_CBC, 8},
-  {GNUTLS_CIPHER_UNKNOWN, 0}
-};
-
 static int
 register_crypto (int cfd)
 {
@@ -208,11 +178,14 @@ register_crypto (int cfd)
   int i = 0, ret;
 
   memset (&sess, 0, sizeof (sess));
-  do
+
+  for (i=0;i<sizeof(gnutls_cipher_map)/sizeof(gnutls_cipher_map[0]);i++)
     {
+      if (gnutls_cipher_map[i] == 0) continue;
+
       /* test if a cipher is support it and if yes register it */
-      sess.cipher = cipher_map[i].cryptodev_cipher;
-      sess.keylen = cipher_map[i].keylen;
+      sess.cipher = gnutls_cipher_map[i];
+      sess.keylen = gnutls_cipher_get_key_size(i);
       sess.key = fake_key;
 
       if (ioctl (cfd, CIOCGSESSION, &sess))
@@ -222,10 +195,9 @@ register_crypto (int cfd)
 
       ioctl(cfd, CIOCFSESSION, &sess);
       
-      _gnutls_debug_log("/dev/crypto: registering: %s\n", gnutls_cipher_get_name(cipher_map[i].gnutls_cipher));
+      _gnutls_debug_log("/dev/crypto: registering: %s\n", gnutls_cipher_get_name(i));
       ret =
-       gnutls_crypto_single_cipher_register (cipher_map[i].gnutls_cipher, 90,
-                                             &cipher_struct);
+       gnutls_crypto_single_cipher_register (i, 90, &cipher_struct);
       if (ret < 0)
        {
          gnutls_assert ();
@@ -233,15 +205,13 @@ register_crypto (int cfd)
        }
 
     }
-  while (cipher_map[i++].gnutls_cipher != GNUTLS_CIPHER_UNKNOWN);
 
   return 0;
 }
 
-int
-_gnutls_cryptodev_init (void)
+int _gnutls_cryptodev_init (void)
 {
-  int cfd = -1, ret;
+  int ret;
 
   /* Open the crypto device */
   cryptodev_fd = open ("/dev/crypto", O_RDWR, 0);
@@ -251,34 +221,195 @@ _gnutls_cryptodev_init (void)
       return GNUTLS_E_CRYPTODEV_DEVICE_ERROR;
     }
 
-  /* Clone file descriptor */
-  if (ioctl (cryptodev_fd, CRIOGET, &cfd))
+#ifndef CRIOGET_NOT_NEEDED
+  {
+    int cfd = -1;
+    /* Clone file descriptor */
+    if (ioctl (cryptodev_fd, CRIOGET, &cfd))
+      {
+        gnutls_assert ();
+        return GNUTLS_E_CRYPTODEV_IOCTL_ERROR;
+      }
+
+    /* Set close-on-exec (not really neede here) */
+    if (fcntl (cfd, F_SETFD, 1) == -1)
+      {
+        gnutls_assert ();
+        return GNUTLS_E_CRYPTODEV_IOCTL_ERROR;
+      }
+
+    close(cryptodev_fd);
+    cryptodev_fd = cfd;
+  }
+#endif
+
+  ret = register_crypto (cryptodev_fd);
+  if (ret < 0)
+          gnutls_assert();
+
+  if (ret >= 0)
+    {
+      ret = register_mac (cryptodev_fd);
+      if (ret < 0)
+          gnutls_assert();
+    }
+
+  if (ret < 0)
+    {
+      gnutls_assert();
+      close(cryptodev_fd);
+    }
+
+  return ret;
+}
+
+void _gnutls_cryptodev_deinit(void)
+{
+  close (cryptodev_fd);
+}
+
+/* MAC and digest stuff */
+
+/* if we are using linux /dev/crypto
+ */
+#if defined(COP_FLAG_UPDATE)
+
+static const int gnutls_mac_map[] = {
+   [GNUTLS_MAC_MD5] = CRYPTO_MD5_HMAC,
+   [GNUTLS_MAC_SHA1] = CRYPTO_SHA1_HMAC,
+   [GNUTLS_MAC_SHA256] = CRYPTO_SHA2_256_HMAC,
+   [GNUTLS_MAC_SHA384] = CRYPTO_SHA2_384_HMAC,
+   [GNUTLS_MAC_SHA512] = CRYPTO_SHA2_512_HMAC,
+};
+
+static int cryptodev_mac_init(gnutls_mac_algorithm_t algorithm, void **_ctx)
+{
+  struct cryptodev_ctx *ctx;
+  int mac = gnutls_mac_map[algorithm];
+
+  *_ctx = gnutls_calloc (1, sizeof (struct cryptodev_ctx));
+  if (*_ctx == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  ctx = *_ctx;
+
+  ctx->cfd = cryptodev_fd;
+
+  ctx->sess.mac = mac;
+  ctx->sess.mackey = ctx->key;
+
+  return 0;
+}
+
+static int
+cryptodev_mac_setkey (void *_ctx, const void *key, size_t keysize)
+{
+  struct cryptodev_ctx *ctx = _ctx;
+
+  ctx->sess.mackeylen = keysize;
+  memcpy (ctx->key, key, keysize);
+
+  if (ioctl (ctx->cfd, CIOCGSESSION, &ctx->sess))
     {
       gnutls_assert ();
       return GNUTLS_E_CRYPTODEV_IOCTL_ERROR;
     }
+  ctx->cryp.ses = ctx->sess.ses;
 
-  /* Set close-on-exec (not really neede here) */
-  if (fcntl (cfd, F_SETFD, 1) == -1)
+  return 0;
+}
+
+static int cryptodev_mac_hash (void *_ctx, const void *text, size_t textsize)
+{
+  struct cryptodev_ctx *ctx = _ctx;
+  ctx->cryp.len = textsize;
+  ctx->cryp.src = (void *) text;
+  ctx->cryp.dst = NULL;
+  ctx->cryp.op = COP_ENCRYPT;
+  ctx->cryp.flags = COP_FLAG_UPDATE;
+  if (ioctl (ctx->cfd, CIOCCRYPT, &ctx->cryp))
     {
       gnutls_assert ();
       return GNUTLS_E_CRYPTODEV_IOCTL_ERROR;
     }
+  return 0;
+}
 
-  /* Run the test itself */
-  ret = register_crypto (cfd);
+static int cryptodev_mac_output (void *_ctx, void *digest, size_t digestsize)
+{
+  struct cryptodev_ctx *ctx = _ctx;
+  ctx->cryp.len = 0;
+  ctx->cryp.src = NULL;
+  ctx->cryp.mac = digest;
+  ctx->cryp.op = COP_ENCRYPT;
+  ctx->cryp.flags = COP_FLAG_FINAL;
+  if (ioctl (ctx->cfd, CIOCCRYPT, &ctx->cryp))
+    {
+      gnutls_assert ();
+      return GNUTLS_E_CRYPTODEV_IOCTL_ERROR;
+    }
 
-  close (cfd);
-  return ret;
+  return 0;
 }
 
-void
-_gnutls_cryptodev_deinit ()
+#define cryptodev_mac_deinit cryptodev_deinit
+
+static const gnutls_crypto_mac_st mac_struct = {
+  .init = cryptodev_mac_init,
+  .setkey = cryptodev_mac_setkey,
+  .hash = cryptodev_mac_hash,
+  .output = cryptodev_mac_output,
+  .deinit = cryptodev_mac_deinit
+};
+
+static int register_mac (int cfd)
 {
-  close (cryptodev_fd);
+  struct session_op sess;
+  char fake_key[CRYPTO_CIPHER_MAX_KEY_LEN];
+  int i = 0, ret;
+
+  memset (&sess, 0, sizeof (sess));
+  for (i=0;i<sizeof(gnutls_mac_map)/sizeof(gnutls_mac_map[0]);i++)
+    {
+      if (gnutls_mac_map[i] == 0) continue;
+
+      sess.mac = gnutls_mac_map[i];
+      sess.keylen = 8;
+      sess.key = fake_key;
+            
+      if (ioctl (cfd, CIOCGSESSION, &sess))
+       {
+         continue;
+       }
+
+      ioctl(cfd, CIOCFSESSION, &sess);
+
+      _gnutls_debug_log("/dev/crypto: registering: %s\n", gnutls_mac_get_name(i));
+      ret =
+       gnutls_crypto_single_mac_register (i, 90, &mac_struct);
+      if (ret < 0)
+       {
+         gnutls_assert ();
+         return ret;
+       }
+            
+    }
+
+  return 0;
 }
 
 #else
+static int register_mac (int cfd)
+{
+  return 0;
+}
+
+#endif /* defined(CIOCSESSIONCLONE) && defined(COP_FLAG_UPDATE) */
+
+#else /* ENABLE_CRYPTODEV */
 int
 _gnutls_cryptodev_init ()
 {
index 703d68b31660e3bb1eec66a52c0144ccfdcc72d7..d4075d8e62ec5bf91180ce82ed17d595fbe390cc 100644 (file)
@@ -164,7 +164,6 @@ gnutls_crypto_mac_st _gnutls_mac_ops = {
   .init = wrap_gcry_mac_init,
   .setkey = wrap_gcry_md_setkey,
   .hash = wrap_gcry_md_write,
-  .copy = wrap_gcry_md_copy,
   .output = wrap_gcry_mac_output,
   .deinit = wrap_gcry_md_close,
 };
index 5cf1956925aac220748e4e3585b83e6ef9d548dd..38883c5acb6b62a065269adcf029342d45e4b690 100644 (file)
@@ -254,7 +254,6 @@ _gnutls_hmac_init (digest_hd_st * dig, gnutls_mac_algorithm_t algorithm,
         }
 
       dig->hash = cc->hash;
-      dig->copy = cc->copy;
       dig->output = cc->output;
       dig->deinit = cc->deinit;
 
@@ -271,7 +270,6 @@ _gnutls_hmac_init (digest_hd_st * dig, gnutls_mac_algorithm_t algorithm,
   _gnutls_mac_ops.setkey (dig->handle, key, keylen);
 
   dig->hash = _gnutls_mac_ops.hash;
-  dig->copy = _gnutls_mac_ops.copy;
   dig->output = _gnutls_mac_ops.output;
   dig->deinit = _gnutls_mac_ops.deinit;
 
index d121490f0d84b9413e4502b52493bb620e4a5ce5..61279597dc3e83c01e7c27f1aae87f5837c9c090 100644 (file)
@@ -69,7 +69,7 @@ int gnutls_hash_fast (gnutls_digest_algorithm_t algorithm,
 
 /* register ciphers */
 
-#define GNUTLS_CRYPTO_API_VERSION 0x02
+#define GNUTLS_CRYPTO_API_VERSION 0x03
 
 #define gnutls_crypto_single_cipher_st gnutls_crypto_cipher_st
 #define gnutls_crypto_single_mac_st gnutls_crypto_mac_st
@@ -92,13 +92,18 @@ typedef struct
   int (*init) (gnutls_mac_algorithm_t, void **ctx);
   int (*setkey) (void *ctx, const void *key, size_t keysize);
   int (*hash) (void *ctx, const void *text, size_t textsize);
-  int (*copy) (void **dst_ctx, void *src_ctx);
   int (*output) (void *src_ctx, void *digest, size_t digestsize);
   void (*deinit) (void *ctx);
 } gnutls_crypto_mac_st;
 
-/* the same... setkey should be null */
-typedef gnutls_crypto_mac_st gnutls_crypto_digest_st;
+typedef struct
+{
+  int (*init) (gnutls_mac_algorithm_t, void **ctx);
+  int (*hash) (void *ctx, const void *text, size_t textsize);
+  int (*copy) (void **dst_ctx, void *src_ctx);
+  int (*output) (void *src_ctx, void *digest, size_t digestsize);
+  void (*deinit) (void *ctx);
+} gnutls_crypto_digest_st;
 
 /**
  * gnutls_rnd_level_t:
index 2eb8a63880e1e1385bb9cb0be1ba96daeb43217c..71b9d012cb9d615ee83ddcde7a7a55565dc78353 100644 (file)
@@ -186,25 +186,6 @@ static int wrap_nettle_hash_copy(void **bhd, void *ahd)
        return 0;
 }
 
-static int wrap_nettle_hmac_copy(void **bhd, void *ahd)
-{
-       struct nettle_hmac_ctx *ctx = ahd;
-       struct nettle_hmac_ctx *dst_ctx;
-       int ret;
-
-       ret = wrap_nettle_hmac_init(ctx->algo, bhd);
-       if (ret < 0) {
-               gnutls_assert();
-               return ret;
-       }
-       
-       dst_ctx = *bhd;
-
-       memcpy(&dst_ctx->ctx, &ctx->ctx, sizeof(ctx->ctx));
-       
-       return 0;
-}
-
 static void wrap_nettle_md_close(void *hd)
 {
     gnutls_free(hd);
@@ -318,7 +299,6 @@ gnutls_crypto_mac_st _gnutls_mac_ops = {
     .init = wrap_nettle_hmac_init,
     .setkey = wrap_nettle_hmac_setkey,
     .hash = wrap_nettle_hmac_update,
-    .copy = wrap_nettle_hmac_copy,
     .output = wrap_nettle_hmac_output,
     .deinit = wrap_nettle_md_close,
 };