From: Nikos Mavrogiannopoulos Date: Mon, 7 Feb 2011 09:50:54 +0000 (+0100) Subject: Added gnutls_cipher_add_auth() gnutls_cipher_tag() to export the X-Git-Tag: gnutls_2_99_0~314 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8dbb79875c5d2b5d95286675eb369d9daf2b10a9;p=thirdparty%2Fgnutls.git Added gnutls_cipher_add_auth() gnutls_cipher_tag() to export the GCM interface. Updated the benchmark. --- diff --git a/NEWS b/NEWS index f91641aea6..1fb6119603 100644 --- a/NEWS +++ b/NEWS @@ -22,9 +22,12 @@ using the --verify option. Combined with --load-ca-certificate it can verify a certificate chain against a list of certificates. ** API and ABI modifications: +gnutls_cipher_add_auth: ADDED +gnutls_cipher_tag: ADDED gnutls_ext_register: REMOVED gnutls_certificate_get_x509_crls: REMOVED gnutls_certificate_get_x509_cas: REMOVED +gnutls_certificate_get_openpgp_keyring: REMOVED gnutls_session_get_server_random: REMOVED gnutls_session_get_client_random: REMOVED gnutls_session_get_master_secret: REMOVED diff --git a/lib/crypto-api.c b/lib/crypto-api.c index d89b7a2b53..b5f6cc52bb 100644 --- a/lib/crypto-api.c +++ b/lib/crypto-api.c @@ -61,6 +61,57 @@ gnutls_cipher_init (gnutls_cipher_hd_t * handle, return _gnutls_cipher_init (((cipher_hd_st *) * handle), cipher, key, iv); } +/** + * gnutls_cipher_tag: + * @handle: is a #gnutls_cipher_hd_t structure. + * @tag: will hold the tag + * @tag_size: The length of the tag to return + * + * This function operates on authenticated encryption with + * associated data (AEAD) ciphers and will return the + * output tag. + * + * Returns: Zero or a negative value on error. + * + * Since: 2.99.0 + **/ +int +gnutls_cipher_tag (gnutls_cipher_hd_t handle, void *tag, size_t tag_size) +{ + if (_gnutls_cipher_is_aead( (cipher_hd_st*)handle)==0) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + _gnutls_cipher_tag( (cipher_hd_st*)handle, tag, tag_size); + + return 0; +} + +/** + * gnutls_cipher_add_auth: + * @handle: is a #gnutls_cipher_hd_t structure. + * @text: the data to be authenticated + * @text_size: The length of the data + * + * This function operates on authenticated encryption with + * associated data (AEAD) ciphers and authenticate the + * input data. This function can only be called before + * encryption operations. + * + * Returns: Zero or a negative value on error. + * + * Since: 2.99.0 + **/ +int +gnutls_cipher_add_auth (gnutls_cipher_hd_t handle, const void *text, size_t text_size) +{ + if (_gnutls_cipher_is_aead( (cipher_hd_st*)handle)==0) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + _gnutls_cipher_auth( (cipher_hd_st*)handle, text, text_size); + + return 0; +} + /** * gnutls_cipher_encrypt: * @handle: is a #gnutls_cipher_hd_t structure. diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c index 5696a6e8cd..4c032d43bd 100644 --- a/lib/gnutls_algorithms.c +++ b/lib/gnutls_algorithms.c @@ -958,7 +958,7 @@ _gnutls_cipher_is_block (gnutls_cipher_algorithm_t algorithm) } int -_gnutls_cipher_is_aead (gnutls_cipher_algorithm_t algorithm) +_gnutls_cipher_algo_is_aead (gnutls_cipher_algorithm_t algorithm) { size_t ret = 0; diff --git a/lib/gnutls_algorithms.h b/lib/gnutls_algorithms.h index eabbda1bf3..50504f360a 100644 --- a/lib/gnutls_algorithms.h +++ b/lib/gnutls_algorithms.h @@ -77,7 +77,7 @@ cipher_suite_st _gnutls_cipher_suite_get_suite_name (cipher_suite_st * /* Functions for ciphers. */ int _gnutls_cipher_is_block (gnutls_cipher_algorithm_t algorithm); -int _gnutls_cipher_is_aead (gnutls_cipher_algorithm_t algorithm); +int _gnutls_cipher_algo_is_aead (gnutls_cipher_algorithm_t algorithm); int _gnutls_cipher_is_ok (gnutls_cipher_algorithm_t algorithm); int _gnutls_cipher_get_iv_size (gnutls_cipher_algorithm_t algorithm); int _gnutls_cipher_get_export_flag (gnutls_cipher_algorithm_t algorithm); diff --git a/lib/gnutls_cipher_int.c b/lib/gnutls_cipher_int.c index 8689a683ec..e766504513 100644 --- a/lib/gnutls_cipher_int.c +++ b/lib/gnutls_cipher_int.c @@ -43,6 +43,10 @@ _gnutls_cipher_init (cipher_hd_st * handle, gnutls_cipher_algorithm_t cipher, int ret = GNUTLS_E_INTERNAL_ERROR; const gnutls_crypto_cipher_st *cc = NULL; + handle->is_aead = _gnutls_cipher_algo_is_aead(cipher); + if (handle->is_aead) + handle->tag_size = gnutls_cipher_get_block_size(cipher); + /* check if a cipher has been registered */ cc = _gnutls_get_crypto_cipher (cipher); @@ -146,12 +150,8 @@ int ret; handle->tag_size = _gnutls_hash_get_algo_len(mac); } - else - { - handle->is_auth = _gnutls_cipher_is_aead(cipher); - if (handle->is_auth) - handle->tag_size = gnutls_cipher_get_block_size(cipher); - } + else if (_gnutls_cipher_is_aead(&handle->cipher)) + handle->tag_size = _gnutls_cipher_tag_len(&handle->cipher); return 0; cleanup: @@ -170,7 +170,7 @@ int _gnutls_auth_cipher_add_auth (auth_cipher_hd_st * handle, const void *text, else return _gnutls_hmac(&handle->mac, text, textlen); } - else if (handle->is_auth) + else if (_gnutls_cipher_is_aead(&handle->cipher)) return _gnutls_cipher_auth(&handle->cipher, text, textlen); else return 0; @@ -202,7 +202,7 @@ int ret; if (ret < 0) return gnutls_assert_val(ret); } - else if (handle->is_auth) + else if (_gnutls_cipher_is_aead(&handle->cipher)) { ret = _gnutls_cipher_encrypt2(&handle->cipher, text, textlen, ciphertext, ciphertextlen); if (ret < 0) @@ -263,7 +263,7 @@ int ret = 0; _gnutls_hmac_reset (&handle->mac); } } - else if (handle->is_auth) + else if (_gnutls_cipher_is_aead(&handle->cipher)) { _gnutls_cipher_tag(&handle->cipher, tag, tag_size); } diff --git a/lib/gnutls_cipher_int.h b/lib/gnutls_cipher_int.h index 989076182d..13de47726d 100644 --- a/lib/gnutls_cipher_int.h +++ b/lib/gnutls_cipher_int.h @@ -51,6 +51,9 @@ typedef struct cipher_tag_func tag; cipher_setiv_func setiv; cipher_deinit_func deinit; + + int tag_size; + int is_aead:1; } cipher_hd_st; int _gnutls_cipher_init (cipher_hd_st *, gnutls_cipher_algorithm_t cipher, @@ -99,6 +102,16 @@ _gnutls_cipher_deinit (cipher_hd_st * handle) } } +inline static unsigned int _gnutls_cipher_tag_len( cipher_hd_st * handle) +{ + return handle->tag_size; +} + +inline static unsigned int _gnutls_cipher_is_aead( cipher_hd_st * handle) +{ + return handle->is_aead; +} + /* returns the tag in AUTHENC ciphers */ inline static void _gnutls_cipher_tag( const cipher_hd_st * handle, void* tag, int tag_size) { @@ -130,7 +143,6 @@ typedef struct { cipher_hd_st cipher; digest_hd_st mac; - int is_auth:1; int is_mac:1; int ssl_hmac:1; int tag_size; @@ -168,7 +180,7 @@ inline static unsigned int _gnutls_auth_cipher_tag_len( auth_cipher_hd_st * hand inline static unsigned int _gnutls_auth_cipher_is_aead( auth_cipher_hd_st * handle) { - return handle->is_auth; + return _gnutls_cipher_is_aead(&handle->cipher); } #define _gnutls_auth_cipher_encrypt_tag(x,y,z,t,s,a) _gnutls_auth_cipher_encrypt2_tag(x,y,z,y,z,t,s,a) diff --git a/lib/includes/gnutls/crypto.h b/lib/includes/gnutls/crypto.h index edec2f4d87..0b2b00bb6a 100644 --- a/lib/includes/gnutls/crypto.h +++ b/lib/includes/gnutls/crypto.h @@ -47,6 +47,9 @@ extern "C" size_t textlen, void *ciphertext, size_t ciphertextlen); + int gnutls_cipher_tag( gnutls_cipher_hd_t handle, void* tag, size_t tag_size); + int gnutls_cipher_add_auth( gnutls_cipher_hd_t handle, const void* test, size_t textlen); + void gnutls_cipher_deinit (gnutls_cipher_hd_t handle); int gnutls_cipher_get_block_size (gnutls_cipher_algorithm_t algorithm); diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 623c0fd39a..d0b178b702 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -52,11 +52,8 @@ GNUTLS_1_4 gnutls_certificate_free_credentials; gnutls_certificate_free_crls; gnutls_certificate_free_keys; - gnutls_certificate_get_openpgp_keyring; gnutls_certificate_get_ours; gnutls_certificate_get_peers; - gnutls_certificate_get_x509_cas; - gnutls_certificate_get_x509_crls; gnutls_certificate_send_x509_rdn_sequence; gnutls_certificate_server_set_request; gnutls_certificate_server_set_retrieve_function; @@ -139,7 +136,6 @@ GNUTLS_1_4 gnutls_dh_set_prime_bits; gnutls_error_is_fatal; gnutls_error_to_alert; - gnutls_ext_register; gnutls_fingerprint; gnutls_free; gnutls_global_deinit; @@ -334,13 +330,10 @@ GNUTLS_1_4 gnutls_server_name_get; gnutls_server_name_set; gnutls_session_enable_compatibility_mode; - gnutls_session_get_client_random; gnutls_session_get_data2; gnutls_session_get_data; gnutls_session_get_id; - gnutls_session_get_master_secret; gnutls_session_get_ptr; - gnutls_session_get_server_random; gnutls_session_is_resumed; gnutls_session_set_data; gnutls_session_set_finished_function; @@ -703,6 +696,8 @@ GNUTLS_2_12 gnutls_x509_crl_list_import; gnutls_x509_crl_list_import2; gnutls_x509_crt_list_import2; + gnutls_cipher_tag; + gnutls_cipher_add_auth; } GNUTLS_2_10; GNUTLS_PRIVATE { diff --git a/src/benchmark.c b/src/benchmark.c index df96f533d2..d8196d71b4 100644 --- a/src/benchmark.c +++ b/src/benchmark.c @@ -82,10 +82,11 @@ value2human (double bytes, double time, double *data, double *speed, } static void -cipher_bench (int algo, int size) +cipher_mac_bench (int algo, int mac_algo, int size) { int ret; gnutls_cipher_hd_t ctx; + gnutls_hmac_hd_t mac_ctx; void *_key, *_iv; gnutls_datum_t key, iv; struct timespec start, stop; @@ -95,6 +96,92 @@ cipher_bench (int algo, int size) int blocksize = gnutls_cipher_get_block_size (algo); int keysize = gnutls_cipher_get_key_size (algo); char metric[16]; + int step = size*1024; + + _key = malloc (keysize); + if (_key == NULL) + return; + memset (_key, 0xf0, keysize); + + _iv = malloc (blocksize); + if (_iv == NULL) + return; + memset (_iv, 0xf0, blocksize); + + iv.data = _iv; + iv.size = blocksize; + + key.data = _key; + key.size = keysize; + + printf ("Checking %s with %s (%dkb payload)... ", gnutls_cipher_get_name (algo), + gnutls_mac_get_name(mac_algo), size); + fflush (stdout); + + must_finish = 0; + alarm (5); + + gettime (&start); + + ret = gnutls_hmac_init(&mac_ctx, mac_algo, key.data, key.size); + if (ret < 0) + { + fprintf (stderr, "error: %s\n", gnutls_strerror (ret)); + goto leave; + } + + ret = gnutls_cipher_init (&ctx, algo, &key, &iv); + if (ret < 0) + { + fprintf (stderr, "error: %s\n", gnutls_strerror (ret)); + goto leave; + } + + gnutls_hmac(mac_ctx, data, 1024); + + do + { + gnutls_hmac(mac_ctx, data, step); + gnutls_cipher_encrypt (ctx, data, step); + data_size += step; + } + while (must_finish == 0); + + gnutls_cipher_deinit (ctx); + gnutls_hmac_deinit(mac_ctx, NULL); + + gettime (&stop); + + secs = (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) - + (start.tv_sec * 1000 + start.tv_nsec / (1000 * 1000))); + secs /= 1000; + + value2human (data_size, secs, &ddata, &dspeed, metric); + printf ("Encrypted and hashed %.2f %s in %.2f secs: ", ddata, metric, secs); + printf ("%.2f %s/sec\n", dspeed, metric); + +leave: + free (_key); + free (_iv); + +} + + +static void +cipher_bench (int algo, int size, int aead) +{ + int ret; + gnutls_cipher_hd_t ctx; + void *_key, *_iv; + gnutls_datum_t key, iv; + struct timespec start, stop; + double secs; + double data_size = 0; + double dspeed, ddata; + int blocksize = gnutls_cipher_get_block_size (algo); + int keysize = gnutls_cipher_get_key_size (algo); + char metric[16]; + int step = size*1024; _key = malloc (keysize); if (_key == NULL) @@ -128,10 +215,13 @@ cipher_bench (int algo, int size) goto leave; } + if (aead) + gnutls_cipher_add_auth (ctx, data, 1024); + do { - gnutls_cipher_encrypt (ctx, data, size * 1024); - data_size += size * 1024; + gnutls_cipher_encrypt (ctx, data, step); + data_size += step; } while (must_finish == 0); @@ -163,6 +253,7 @@ mac_bench (int algo, int size) double ddata, dspeed; int blocksize = gnutls_hmac_get_len (algo); char metric[16]; + int step = size*1024; _key = malloc (blocksize); if (_key == NULL) @@ -179,8 +270,8 @@ mac_bench (int algo, int size) do { - gnutls_hmac_fast (algo, _key, blocksize, data, size * 1024, _key); - data_size += size * 1024; + gnutls_hmac_fast (algo, _key, blocksize, data, step, _key); + data_size += step; } while (must_finish == 0); @@ -213,25 +304,21 @@ main (int argc, char **argv) gnutls_global_set_log_level (debug_level); gnutls_global_init (); - mac_bench (GNUTLS_MAC_SHA1, 4); - mac_bench (GNUTLS_MAC_SHA1, 8); + gnutls_rnd( GNUTLS_RND_NONCE, data, sizeof(data)); + + cipher_bench ( GNUTLS_CIPHER_AES_128_GCM, 16, 1); + cipher_mac_bench ( GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA256, 16); + cipher_mac_bench ( GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1, 16); + mac_bench (GNUTLS_MAC_SHA1, 16); - mac_bench (GNUTLS_MAC_SHA256, 4); - mac_bench (GNUTLS_MAC_SHA256, 8); mac_bench (GNUTLS_MAC_SHA256, 16); - cipher_bench (GNUTLS_CIPHER_3DES_CBC, 4); - cipher_bench (GNUTLS_CIPHER_3DES_CBC, 8); - cipher_bench (GNUTLS_CIPHER_3DES_CBC, 16); + cipher_bench (GNUTLS_CIPHER_3DES_CBC, 16, 0); - cipher_bench (GNUTLS_CIPHER_AES_128_CBC, 4); - cipher_bench (GNUTLS_CIPHER_AES_128_CBC, 8); - cipher_bench (GNUTLS_CIPHER_AES_128_CBC, 16); + cipher_bench (GNUTLS_CIPHER_AES_128_CBC, 16, 0); - cipher_bench (GNUTLS_CIPHER_ARCFOUR, 4); - cipher_bench (GNUTLS_CIPHER_ARCFOUR, 8); - cipher_bench (GNUTLS_CIPHER_ARCFOUR, 16); + cipher_bench (GNUTLS_CIPHER_ARCFOUR, 16, 0); return 0; }