From: Nikos Mavrogiannopoulos Date: Thu, 29 Jul 2010 08:26:33 +0000 (+0200) Subject: Added Camellia-128/256, SHA-224/384/512 and support for DSA2 when using nettle. X-Git-Tag: gnutls_2_11_3~70 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a46d42296b2ceea3bab94d4e144f7bd9cf71d10d;p=thirdparty%2Fgnutls.git Added Camellia-128/256, SHA-224/384/512 and support for DSA2 when using nettle. --- diff --git a/NEWS b/NEWS index d689850e3f..1adfa61d90 100644 --- 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 diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am index cb9374d542..794c1fa2ed 100644 --- a/doc/manpages/Makefile.am +++ b/doc/manpages/Makefile.am @@ -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 diff --git a/lib/gnutls_extensions.c b/lib/gnutls_extensions.c index cd5d0a29a8..94196e62d3 100644 --- a/lib/gnutls_extensions.c +++ b/lib/gnutls_extensions.c @@ -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) diff --git a/lib/m4/hooks.m4 b/lib/m4/hooks.m4 index 378c94a36f..78bb1aac88 100644 --- a/lib/m4/hooks.m4 +++ b/lib/m4/hooks.m4 @@ -45,7 +45,7 @@ AC_DEFUN([LIBGNUTLS_HOOKS], nettle=no) if test "$nettle" = "yes"; then AC_LIB_HAVE_LINKFLAGS([nettle],, [#include ], - [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([[ diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c index 777337046f..70d37372b7 100644 --- a/lib/nettle/cipher.c +++ b/lib/nettle/cipher.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -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(); diff --git a/lib/nettle/mac.c b/lib/nettle/mac.c index 5821843504..73a2c62cf6 100644 --- a/lib/nettle/mac.c +++ b/lib/nettle/mac.c @@ -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; diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index 4681fcae20..29434b52dc 100644 --- a/lib/nettle/pk.c +++ b/lib/nettle/pk.c @@ -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; diff --git a/libextra/gnutls_extra.c b/libextra/gnutls_extra.c index 490f0c5ab7..4455cc575f 100644 --- a/libextra/gnutls_extra.c +++ b/libextra/gnutls_extra.c @@ -27,7 +27,7 @@ #include #include -#ifndef HAVE_LIBNETTLE +#ifdef HAVE_GCRYPT # include #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. */