]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added Camellia-128/256, SHA-224/384/512 and support for DSA2 when using nettle.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 29 Jul 2010 08:26:33 +0000 (10:26 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 29 Jul 2010 08:26:33 +0000 (10:26 +0200)
NEWS
doc/manpages/Makefile.am
lib/gnutls_extensions.c
lib/m4/hooks.m4
lib/nettle/cipher.c
lib/nettle/mac.c
lib/nettle/pk.c
libextra/gnutls_extra.c

diff --git a/NEWS b/NEWS
index d689850e3f78adec110931a84dcc8039c92af0ae..1adfa61d90e089a3de418dc1204208906374b21c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,9 @@ See the end for copying conditions.
 
 * Version 2.11.1 (unreleased)
 
+** libgnutls: Depend on nettle 2.1. This makes nettle a fully working
+backend crypto library.
+
 ** libgnutls: Added RSA_NULL_SHA1 and SHA256 ciphersuites.
 
 ** libgnutls: Updated documentation and gnutls_pk_params_t mappings
index cb9374d542a79bb4357c265a4bb78ec6a12d86cf..794c1fa2eddf27a545f1671d99a3c686a1206de1 100644 (file)
@@ -116,6 +116,8 @@ APIMANS += gnutls_transport_set_global_errno.3
 APIMANS += gnutls_record_check_pending.3
 APIMANS += gnutls_transport_set_pull_function.3
 APIMANS += gnutls_transport_set_push_function.3
+APIMANS += gnutls_transport_set_push_function2.3
+APIMANS += gnutls_transport_set_errno_function.3
 APIMANS += gnutls_certificate_free_keys.3
 APIMANS += gnutls_certificate_free_cas.3
 APIMANS += gnutls_certificate_get_x509_cas.3
index cd5d0a29a806772309b966ce2bb7254abda99c8d..94196e62d329b47497c967aff0823624d96841df 100644 (file)
@@ -348,7 +348,6 @@ _gnutls_ext_init (void)
     return ret;
 #endif
 
-
 #ifdef ENABLE_SESSION_TICKET
   ret = _gnutls_ext_register (&ext_mod_session_ticket);
   if (ret != GNUTLS_E_SUCCESS)
index 378c94a36f794aed84ced0836cbe8403c4f67c06..78bb1aac883f56bcfddf36ea7ea1f47bb0fde39d 100644 (file)
@@ -45,7 +45,7 @@ AC_DEFUN([LIBGNUTLS_HOOKS],
       nettle=no)
     if test "$nettle" = "yes"; then
     AC_LIB_HAVE_LINKFLAGS([nettle],, [#include <nettle/aes.h>],
-                          [aes_set_encrypt_key (0, 0, 0)])
+                          [nettle_aes_invert_key (0, 0)])
     if test "$ac_cv_libnettle" != yes; then
       nettle=yes
       AC_MSG_WARN([[
index 777337046fb9911118de8e7cc7ec28494e11dfad..70d37372b73d274511e524c8273c1835d0ab5f7c 100644 (file)
@@ -29,6 +29,7 @@
 #include <gnutls_errors.h>
 #include <gnutls_cipher_int.h>
 #include <nettle/aes.h>
+#include <nettle/camellia.h>
 #include <nettle/arcfour.h>
 #include <nettle/arctwo.h>
 #include <nettle/des.h>
@@ -58,7 +59,7 @@ struct aes_bidi_ctx
 static void aes_bidi_setkey (struct aes_bidi_ctx* ctx, unsigned length, const uint8_t *key)
 {
        aes_set_encrypt_key (&ctx->encrypt, length, key);
-       aes_set_decrypt_key (&ctx->decrypt, length, key);
+       aes_invert_key (&ctx->decrypt, &ctx->encrypt);
 }
 
 static void aes_bidi_encrypt(struct aes_bidi_ctx *ctx,
@@ -73,9 +74,34 @@ static void aes_bidi_decrypt(struct aes_bidi_ctx *ctx,
        aes_decrypt(&ctx->decrypt, length, dst, src);
 }
 
+struct camellia_bidi_ctx
+{
+       struct camellia_ctx encrypt;
+       struct camellia_ctx decrypt;
+};
+
+static void camellia_bidi_setkey (struct camellia_bidi_ctx* ctx, unsigned length, const uint8_t *key)
+{
+       camellia_set_encrypt_key (&ctx->encrypt, length, key);
+       camellia_invert_key (&ctx->decrypt, &ctx->encrypt);
+}
+
+static void camellia_bidi_encrypt(struct camellia_bidi_ctx *ctx,
+          unsigned length, uint8_t *dst, const uint8_t *src)
+{
+       camellia_crypt(&ctx->encrypt, length, dst, src);
+}
+
+static void camellia_bidi_decrypt(struct camellia_bidi_ctx *ctx,
+          unsigned length, uint8_t *dst, const uint8_t *src)
+{
+       camellia_crypt(&ctx->decrypt, length, dst, src);
+}
+
 struct nettle_cipher_ctx {
     union {
                struct aes_bidi_ctx aes_bidi;
+               struct camellia_bidi_ctx camellia_bidi;
                struct arcfour_ctx arcfour;
                struct arctwo_ctx arctwo;
                struct des3_ctx des3;
@@ -107,6 +133,15 @@ wrap_nettle_cipher_init (gnutls_cipher_algorithm_t algo, void **_ctx)
     ctx->algo = algo;
 
     switch (algo) {
+    case GNUTLS_CIPHER_CAMELLIA_128_CBC:
+    case GNUTLS_CIPHER_CAMELLIA_256_CBC:
+               ctx->encrypt = cbc_encrypt;
+               ctx->decrypt = cbc_decrypt;
+               ctx->i_encrypt = (nettle_crypt_func*)camellia_bidi_encrypt;
+               ctx->i_decrypt = (nettle_crypt_func*)camellia_bidi_decrypt;
+               ctx->ctx_ptr = &ctx->ctx.camellia_bidi;
+               ctx->block_size = CAMELLIA_BLOCK_SIZE;
+               break;
     case GNUTLS_CIPHER_AES_128_CBC:
     case GNUTLS_CIPHER_AES_192_CBC:
     case GNUTLS_CIPHER_AES_256_CBC:
@@ -150,7 +185,6 @@ wrap_nettle_cipher_init (gnutls_cipher_algorithm_t algo, void **_ctx)
                ctx->ctx_ptr = &ctx->ctx.arctwo;
                ctx->block_size = ARCTWO_BLOCK_SIZE;
                break;
-       /* FIXME: Camellia? */
     default:
       gnutls_assert ();
       return GNUTLS_E_INVALID_REQUEST;
@@ -173,8 +207,11 @@ wrap_nettle_cipher_setkey (void *_ctx, const void *key, size_t keysize)
     case GNUTLS_CIPHER_AES_256_CBC:
                aes_bidi_setkey(ctx->ctx_ptr, keysize, key);
                break;
+    case GNUTLS_CIPHER_CAMELLIA_128_CBC:
+    case GNUTLS_CIPHER_CAMELLIA_256_CBC:
+               camellia_bidi_setkey(ctx->ctx_ptr, keysize, key);
+               break;
     case GNUTLS_CIPHER_3DES_CBC:
-               /* why do we have to deal with parity *@$(*$# */
                if (keysize != DES3_KEY_SIZE) {
                    gnutls_assert();
                    return GNUTLS_E_INTERNAL_ERROR;
@@ -195,7 +232,7 @@ wrap_nettle_cipher_setkey (void *_ctx, const void *key, size_t keysize)
                    return GNUTLS_E_INTERNAL_ERROR;
                   }
 
-               des_fix_parity(keysize, des_key, key);
+                des_fix_parity(keysize, des_key, key);
 
                if (des_set_key(ctx->ctx_ptr, des_key)!=1) {
                        gnutls_assert();
index 58218435047683611e4939861c27dc6941a92fa0..73a2c62cf6c35e6472a12fae0d22fb498759490b 100644 (file)
@@ -43,7 +43,10 @@ struct nettle_hash_ctx {
     union {
                struct md5_ctx md5;
                struct md2_ctx md2;
+               struct sha224_ctx sha224;
                struct sha256_ctx sha256;
+               struct sha384_ctx sha384;
+               struct sha512_ctx sha512;
                struct sha1_ctx sha1;
     } ctx;
     void *ctx_ptr;
@@ -56,7 +59,10 @@ struct nettle_hash_ctx {
 struct nettle_hmac_ctx {
     union {
                struct hmac_md5_ctx md5;
+               struct hmac_sha224_ctx sha224;
                struct hmac_sha256_ctx sha256;
+               struct hmac_sha384_ctx sha384;
+               struct hmac_sha512_ctx sha512;
                struct hmac_sha1_ctx sha1;
     } ctx;
     void *ctx_ptr;
@@ -94,6 +100,13 @@ static int wrap_nettle_hmac_init(gnutls_mac_algorithm_t algo, void **_ctx)
                ctx->ctx_ptr = &ctx->ctx.sha1;
                ctx->length = SHA1_DIGEST_SIZE;
                break;
+    case GNUTLS_MAC_SHA224:
+               ctx->update = (update_func)hmac_sha224_update;
+               ctx->digest = (digest_func)hmac_sha224_digest;
+               ctx->setkey = (set_key_func)hmac_sha224_set_key;
+               ctx->ctx_ptr = &ctx->ctx.sha224;
+               ctx->length = SHA224_DIGEST_SIZE;
+               break;
     case GNUTLS_MAC_SHA256:
                ctx->update = (update_func)hmac_sha256_update;
                ctx->digest = (digest_func)hmac_sha256_digest;
@@ -101,7 +114,20 @@ static int wrap_nettle_hmac_init(gnutls_mac_algorithm_t algo, void **_ctx)
                ctx->ctx_ptr = &ctx->ctx.sha256;
                ctx->length = SHA256_DIGEST_SIZE;
                break;
-       /* FIXME: SHA512/384/224? */
+    case GNUTLS_MAC_SHA384:
+               ctx->update = (update_func)hmac_sha384_update;
+               ctx->digest = (digest_func)hmac_sha384_digest;
+               ctx->setkey = (set_key_func)hmac_sha384_set_key;
+               ctx->ctx_ptr = &ctx->ctx.sha384;
+               ctx->length = SHA384_DIGEST_SIZE;
+               break;
+    case GNUTLS_MAC_SHA512:
+               ctx->update = (update_func)hmac_sha512_update;
+               ctx->digest = (digest_func)hmac_sha512_digest;
+               ctx->setkey = (set_key_func)hmac_sha512_set_key;
+               ctx->ctx_ptr = &ctx->ctx.sha512;
+               ctx->length = SHA512_DIGEST_SIZE;
+               break;
     default:
                gnutls_assert();
                return GNUTLS_E_INVALID_REQUEST;
@@ -218,6 +244,13 @@ static int wrap_nettle_hash_init(gnutls_mac_algorithm_t algo, void **_ctx)
                ctx->ctx_ptr = &ctx->ctx.md2;
                ctx->length = MD2_DIGEST_SIZE;
                break;
+    case GNUTLS_DIG_SHA224:
+               sha224_init(&ctx->ctx.sha224);
+               ctx->update = (update_func)sha224_update;
+               ctx->digest = (digest_func)sha224_digest;
+               ctx->ctx_ptr = &ctx->ctx.sha224;
+               ctx->length = SHA224_DIGEST_SIZE;
+               break;
     case GNUTLS_DIG_SHA256:
                sha256_init(&ctx->ctx.sha256);
                ctx->update = (update_func)sha256_update;
@@ -225,7 +258,20 @@ static int wrap_nettle_hash_init(gnutls_mac_algorithm_t algo, void **_ctx)
                ctx->ctx_ptr = &ctx->ctx.sha256;
                ctx->length = SHA256_DIGEST_SIZE;
                break;
-       /* FIXME: SHA512/384/224? */
+    case GNUTLS_DIG_SHA384:
+               sha384_init(&ctx->ctx.sha384);
+               ctx->update = (update_func)sha384_update;
+               ctx->digest = (digest_func)sha384_digest;
+               ctx->ctx_ptr = &ctx->ctx.sha384;
+               ctx->length = SHA384_DIGEST_SIZE;
+               break;
+    case GNUTLS_DIG_SHA512:
+               sha512_init(&ctx->ctx.sha512);
+               ctx->update = (update_func)sha512_update;
+               ctx->digest = (digest_func)sha512_digest;
+               ctx->ctx_ptr = &ctx->ctx.sha512;
+               ctx->length = SHA512_DIGEST_SIZE;
+               break;
     default:
                gnutls_assert();
                return GNUTLS_E_INVALID_REQUEST;
index 4681fcae207ae9b076ade657290a1ada3b4ae0d5..29434b52dc8156d6d0b66344c353c68358f65859 100644 (file)
@@ -243,7 +243,7 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
                     const gnutls_datum_t * vdata,
                     const gnutls_pk_params_st * pk_params)
 {
-       int ret;
+       int ret, hash;
 
        switch (algo) {
 
@@ -259,12 +259,25 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo,
 
                dsa_signature_init(&sig);
 
-               dsa_sign_digest(&pub, &priv, NULL, rnd_func, vdata->data, &sig);
+               hash = _gnutls_dsa_q_to_hash(pub.q);
+               if (vdata->size != _gnutls_hash_get_algo_len(hash)) {
+                   gnutls_assert();
+                   ret = GNUTLS_E_PK_SIGN_FAILED;
+                   goto dsa_fail;
+                }
+
+               ret = _dsa_sign(&pub, &priv, NULL, rnd_func, vdata->size, vdata->data, &sig);
+               if (ret == 0) {
+                   gnutls_assert();
+                   ret = GNUTLS_E_PK_SIGN_FAILED;
+                   goto dsa_fail;
+                }
 
                ret =
                        _gnutls_encode_ber_rs(signature, &sig.r,
                                          &sig.s);
-                                         
+
+dsa_fail:                                        
                dsa_signature_clear(&sig);
 
                if (ret < 0) {
@@ -357,7 +370,7 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
                       const gnutls_datum_t * signature,
                       const gnutls_pk_params_st * pk_params)
 {
-       int ret;
+       int ret, hash;
        bigint_t tmp[2] = { NULL, NULL };
 
        switch (algo) {
@@ -375,12 +388,20 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo,
                memcpy(&sig.r, tmp[0], sizeof(sig.r));
                memcpy(&sig.s, tmp[1], sizeof(sig.s));
 
-               ret = dsa_verify_digest(&pub, vdata->data, &sig);
+               hash = _gnutls_dsa_q_to_hash(pub.q);
+               if (vdata->size != _gnutls_hash_get_algo_len(hash)) {
+                   gnutls_assert();
+                   ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
+                   goto dsa_fail;
+                }
+
+               ret = _dsa_verify(&pub, vdata->size, vdata->data, &sig);
                if (ret == 0)
                        ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
                else
                        ret = 0;
 
+dsa_fail:
                _gnutls_mpi_release(&tmp[0]);
                _gnutls_mpi_release(&tmp[1]);
                break;
@@ -423,6 +444,7 @@ wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
                               gnutls_pk_params_st * params)
 {
 int ret, i;
+int q_bits;
 
        switch (algo) {
 
@@ -432,8 +454,15 @@ int ret, i;
        
                dsa_public_key_init(&pub);
                dsa_private_key_init(&priv);
+               
+               /* the best would be to use _gnutls_pk_bits_to_subgroup_bits()
+                * but we do NIST DSA here */
+               if (level <= 1024)
+                 q_bits = 160;
+               else
+                 q_bits = 256;
 
-               ret = dsa_generate_keypair (&pub, &priv, NULL, rnd_func, NULL, NULL, level);
+               ret = dsa_generate_keypair (&pub, &priv, NULL, rnd_func, NULL, NULL, level, q_bits);
                if (ret != 1) {
                        gnutls_assert();
                        return GNUTLS_E_INTERNAL_ERROR;
index 490f0c5ab73cfb9f205fd4351cd07f608445f6f3..4455cc575fcfde1eb32475375fbfe7159f626832 100644 (file)
@@ -27,7 +27,7 @@
 #include <gnutls_algorithms.h>
 #include <ext_inner_application.h>
 
-#ifndef HAVE_LIBNETTLE
+#ifdef HAVE_GCRYPT
 # include <gcrypt.h>
 #endif
 
@@ -148,7 +148,7 @@ gnutls_global_init_extra (void)
 #endif
 
 
-#ifndef HAVE_LIBNETTLE
+#ifdef HAVE_GCRYPT
 # ifdef gcry_fips_mode_active
   /* Libgcrypt manual says that gcry_version_check must be called
      before calling gcry_fips_mode_active. */