From: Nikos Mavrogiannopoulos Date: Wed, 18 Mar 2015 10:44:26 +0000 (+0100) Subject: Added API to register AEAD and legacy ciphers. X-Git-Tag: gnutls_3_4_0~181 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8d3d2fbbbf92a0c9db9058b472a9506061c33dce;p=thirdparty%2Fgnutls.git Added API to register AEAD and legacy ciphers. --- diff --git a/lib/accelerated/cryptodev-gcm.c b/lib/accelerated/cryptodev-gcm.c index 5772914df8..52f9e85b8c 100644 --- a/lib/accelerated/cryptodev-gcm.c +++ b/lib/accelerated/cryptodev-gcm.c @@ -275,7 +275,7 @@ int _cryptodev_register_gcm_crypto(int cfd) gnutls_cipher_get_name(i)); ret = gnutls_crypto_single_cipher_register(i, 90, - &cipher_struct); + &cipher_struct, 0); if (ret < 0) { gnutls_assert(); return ret; diff --git a/lib/accelerated/cryptodev.c b/lib/accelerated/cryptodev.c index 012221dffb..9d97637458 100644 --- a/lib/accelerated/cryptodev.c +++ b/lib/accelerated/cryptodev.c @@ -211,7 +211,7 @@ static int register_crypto(int cfd) gnutls_cipher_get_name(i)); ret = gnutls_crypto_single_cipher_register(i, 90, - &cipher_struct); + &cipher_struct, 0); if (ret < 0) { gnutls_assert(); return ret; diff --git a/lib/accelerated/x86/x86-common.c b/lib/accelerated/x86/x86-common.c index 7ced638b38..73c356594f 100644 --- a/lib/accelerated/x86/x86-common.c +++ b/lib/accelerated/x86/x86-common.c @@ -193,7 +193,7 @@ void register_x86_padlock_crypto(unsigned capabilities) ("Padlock AES accelerator was detected\n"); ret = gnutls_crypto_single_cipher_register - (GNUTLS_CIPHER_AES_128_CBC, 80, &_gnutls_aes_padlock); + (GNUTLS_CIPHER_AES_128_CBC, 80, &_gnutls_aes_padlock, 0); if (ret < 0) { gnutls_assert(); } @@ -202,21 +202,21 @@ void register_x86_padlock_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_128_GCM, 80, - &_gnutls_aes_gcm_padlock); + &_gnutls_aes_gcm_padlock, 0); if (ret < 0) { gnutls_assert(); } #ifdef HAVE_LIBNETTLE ret = gnutls_crypto_single_cipher_register - (GNUTLS_CIPHER_AES_192_CBC, 80, &_gnutls_aes_padlock); + (GNUTLS_CIPHER_AES_192_CBC, 80, &_gnutls_aes_padlock, 0); if (ret < 0) { gnutls_assert(); } ret = gnutls_crypto_single_cipher_register - (GNUTLS_CIPHER_AES_256_CBC, 80, &_gnutls_aes_padlock); + (GNUTLS_CIPHER_AES_256_CBC, 80, &_gnutls_aes_padlock, 0); if (ret < 0) { gnutls_assert(); } @@ -224,7 +224,7 @@ void register_x86_padlock_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_GCM, 80, - &_gnutls_aes_gcm_padlock); + &_gnutls_aes_gcm_padlock, 0); if (ret < 0) { gnutls_assert(); } @@ -394,7 +394,7 @@ void register_x86_intel_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_128_GCM, 90, - &_gnutls_aes_gcm_x86_ssse3); + &_gnutls_aes_gcm_x86_ssse3, 0); if (ret < 0) { gnutls_assert(); } @@ -402,28 +402,28 @@ void register_x86_intel_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_GCM, 90, - &_gnutls_aes_gcm_x86_ssse3); + &_gnutls_aes_gcm_x86_ssse3, 0); if (ret < 0) { gnutls_assert(); } ret = gnutls_crypto_single_cipher_register - (GNUTLS_CIPHER_AES_128_CBC, 90, &_gnutls_aes_ssse3); + (GNUTLS_CIPHER_AES_128_CBC, 90, &_gnutls_aes_ssse3, 0); if (ret < 0) { gnutls_assert(); } ret = gnutls_crypto_single_cipher_register - (GNUTLS_CIPHER_AES_192_CBC, 90, &_gnutls_aes_ssse3); + (GNUTLS_CIPHER_AES_192_CBC, 90, &_gnutls_aes_ssse3, 0); if (ret < 0) { gnutls_assert(); } ret = gnutls_crypto_single_cipher_register - (GNUTLS_CIPHER_AES_256_CBC, 90, &_gnutls_aes_ssse3); + (GNUTLS_CIPHER_AES_256_CBC, 90, &_gnutls_aes_ssse3, 0); if (ret < 0) { gnutls_assert(); } @@ -508,21 +508,21 @@ void register_x86_intel_crypto(unsigned capabilities) _gnutls_debug_log("Intel AES accelerator was detected\n"); ret = gnutls_crypto_single_cipher_register - (GNUTLS_CIPHER_AES_128_CBC, 80, &_gnutls_aesni_x86); + (GNUTLS_CIPHER_AES_128_CBC, 80, &_gnutls_aesni_x86, 0); if (ret < 0) { gnutls_assert(); } ret = gnutls_crypto_single_cipher_register - (GNUTLS_CIPHER_AES_192_CBC, 80, &_gnutls_aesni_x86); + (GNUTLS_CIPHER_AES_192_CBC, 80, &_gnutls_aesni_x86, 0); if (ret < 0) { gnutls_assert(); } ret = gnutls_crypto_single_cipher_register - (GNUTLS_CIPHER_AES_256_CBC, 80, &_gnutls_aesni_x86); + (GNUTLS_CIPHER_AES_256_CBC, 80, &_gnutls_aesni_x86, 0); if (ret < 0) { gnutls_assert(); } @@ -530,7 +530,7 @@ void register_x86_intel_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_128_CCM, 80, - &_gnutls_aes_ccm_x86_aesni); + &_gnutls_aes_ccm_x86_aesni, 0); if (ret < 0) { gnutls_assert(); } @@ -538,7 +538,7 @@ void register_x86_intel_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_CCM, 80, - &_gnutls_aes_ccm_x86_aesni); + &_gnutls_aes_ccm_x86_aesni, 0); if (ret < 0) { gnutls_assert(); } @@ -551,7 +551,7 @@ void register_x86_intel_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_128_GCM, 80, - &_gnutls_aes_gcm_pclmul); + &_gnutls_aes_gcm_pclmul, 0); if (ret < 0) { gnutls_assert(); } @@ -559,7 +559,7 @@ void register_x86_intel_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_GCM, 80, - &_gnutls_aes_gcm_pclmul); + &_gnutls_aes_gcm_pclmul, 0); if (ret < 0) { gnutls_assert(); } @@ -569,7 +569,7 @@ void register_x86_intel_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_128_GCM, 80, - &_gnutls_aes_gcm_x86_aesni); + &_gnutls_aes_gcm_x86_aesni, 0); if (ret < 0) { gnutls_assert(); } @@ -577,7 +577,7 @@ void register_x86_intel_crypto(unsigned capabilities) ret = gnutls_crypto_single_cipher_register (GNUTLS_CIPHER_AES_256_GCM, 80, - &_gnutls_aes_gcm_x86_aesni); + &_gnutls_aes_gcm_x86_aesni, 0); if (ret < 0) { gnutls_assert(); } diff --git a/lib/crypto-backend.c b/lib/crypto-backend.c index 17f3dd03c8..4e5e7515b1 100644 --- a/lib/crypto-backend.c +++ b/lib/crypto-backend.c @@ -38,7 +38,8 @@ int crypto_cipher_prio = INT_MAX; typedef struct algo_list { int algorithm; int priority; - const void *alg_data; + void *alg_data; + int free_alg_data; struct algo_list *next; } algo_list; @@ -47,7 +48,7 @@ typedef struct algo_list { #define digest_list algo_list static int -_algo_register(algo_list * al, int algorithm, int priority, const void *s) +_algo_register(algo_list * al, int algorithm, int priority, void *s, int free_s) { algo_list *cl; algo_list *last_cl = al; @@ -68,6 +69,7 @@ _algo_register(algo_list * al, int algorithm, int priority, const void *s) cl->algorithm = algorithm; cl->priority = priority; cl->alg_data = s; + cl->free_alg_data = free_s; return 0; } } @@ -123,6 +125,8 @@ static void _deregister(algo_list * cl) while (cl) { next = cl->next; + if (cl->free_alg_data) + gnutls_free(cl->alg_data); gnutls_free(cl); cl = next; } @@ -159,9 +163,11 @@ void _gnutls_crypto_deregister(void) int gnutls_crypto_single_cipher_register(gnutls_cipher_algorithm_t algorithm, int priority, - const gnutls_crypto_cipher_st * s) + const gnutls_crypto_cipher_st * s, + int free_s) { - return _algo_register(&glob_cl, algorithm, priority, s); + /* we override const in case free_s is set */ + return _algo_register(&glob_cl, algorithm, priority, (void*)s, free_s); } const gnutls_crypto_cipher_st @@ -170,6 +176,100 @@ const gnutls_crypto_cipher_st return _get_algo(&glob_cl, algo); } +/** + * gnutls_crypto_register_cipher: + * @algorithm: is the gnutls algorithm identifier + * @priority: is the priority of the algorithm + * @init: A function which initializes the cipher + * @setkey: A function which sets the key of the cipher + * @setiv: A function which sets the nonce/IV of the cipher (non-AEAD) + * @encrypt: A function which performs encryption (non-AEAD) + * @decrypt: A function which performs decryption (non-AEAD) + * @deinit: A function which deinitializes the cipher + * + * This function will register a cipher algorithm to be used by + * gnutls. Any algorithm registered will override the included + * algorithms and by convention kernel implemented algorithms have + * priority of 90 and CPU-assisted of 80. The algorithm with the lowest priority will be + * used by gnutls. + * + * The functions which are marked as non-AEAD they are not required when + * registering a cipher to be used with the new AEAD API introduced in + * GnuTLS 3.4.0. Internally GnuTLS uses the new AEAD API. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. + * + * Since: 3.4.0 + **/ +int +gnutls_crypto_register_cipher(gnutls_cipher_algorithm_t algorithm, + int priority, + gnutls_cipher_init_func init, + gnutls_cipher_setkey_func setkey, + gnutls_cipher_setiv_func setiv, + gnutls_cipher_encrypt_func encrypt, + gnutls_cipher_decrypt_func decrypt, + gnutls_cipher_deinit_func deinit) +{ + gnutls_crypto_cipher_st *s = gnutls_calloc(1, sizeof(gnutls_crypto_cipher_st)); + if (s == NULL) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + s->init = init; + s->setkey = setkey; + s->setiv = setiv; + s->encrypt = encrypt; + s->decrypt = decrypt; + s->deinit = deinit; + + return gnutls_crypto_single_cipher_register(algorithm, priority, s, 1); +} + +/** + * gnutls_crypto_register_aead_cipher: + * @algorithm: is the gnutls AEAD cipher identifier + * @priority: is the priority of the algorithm + * @init: A function which initializes the cipher + * @setkey: A function which sets the key of the cipher + * @aead_encrypt: Perform the AEAD encryption + * @aead_decrypt: Perform the AEAD decryption + * @deinit: A function which deinitializes the cipher + * + * This function will register a cipher algorithm to be used by + * gnutls. Any algorithm registered will override the included + * algorithms and by convention kernel implemented algorithms have + * priority of 90 and CPU-assisted of 80. The algorithm with the lowest priority will be + * used by gnutls. + * + * The functions registered will be used with the new AEAD API introduced in + * GnuTLS 3.4.0. Internally GnuTLS uses the new AEAD API. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. + * + * Since: 3.4.0 + **/ +int +gnutls_crypto_register_aead_cipher(gnutls_cipher_algorithm_t algorithm, + int priority, + gnutls_cipher_init_func init, + gnutls_cipher_setkey_func setkey, + gnutls_cipher_aead_encrypt_func aead_encrypt, + gnutls_cipher_aead_decrypt_func aead_decrypt, + gnutls_cipher_deinit_func deinit) +{ + gnutls_crypto_cipher_st *s = gnutls_calloc(1, sizeof(gnutls_crypto_cipher_st)); + if (s == NULL) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + s->init = init; + s->setkey = setkey; + s->aead_encrypt = aead_encrypt; + s->aead_decrypt = aead_decrypt; + s->deinit = deinit; + + return gnutls_crypto_single_cipher_register(algorithm, priority, s, 1); +} + /*- * gnutls_crypto_rnd_register: * @priority: is the priority of the generator @@ -228,7 +328,7 @@ gnutls_crypto_single_mac_register(gnutls_mac_algorithm_t algorithm, int priority, const gnutls_crypto_mac_st * s) { - return _algo_register(&glob_ml, algorithm, priority, s); + return _algo_register(&glob_ml, algorithm, priority, s, 0); } const gnutls_crypto_mac_st *_gnutls_get_crypto_mac(gnutls_mac_algorithm_t @@ -263,7 +363,7 @@ gnutls_crypto_single_digest_register(gnutls_digest_algorithm_t algorithm, int priority, const gnutls_crypto_digest_st * s) { - return _algo_register(&glob_dl, algorithm, priority, s); + return _algo_register(&glob_dl, algorithm, priority, s, 0); } const gnutls_crypto_digest_st diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h index e2f0c0325b..1984d90562 100644 --- a/lib/crypto-backend.h +++ b/lib/crypto-backend.h @@ -30,28 +30,16 @@ #define gnutls_crypto_single_digest_st gnutls_crypto_digest_st typedef struct { - int (*init) (gnutls_cipher_algorithm_t, void **ctx, int enc); - int (*setkey) (void *ctx, const void *key, size_t keysize); - int (*setiv) (void *ctx, const void *iv, size_t ivsize); - int (*encrypt) (void *ctx, const void *plain, size_t plainsize, - void *encr, size_t encrsize); - int (*decrypt) (void *ctx, const void *encr, size_t encrsize, - void *plain, size_t plainsize); - int (*aead_encrypt) (void *ctx, - const void *nonce, size_t noncesize, - const void *auth, size_t authsize, - size_t tag_size, - const void *plain, size_t plainsize, - void *encr, size_t encrsize); - int (*aead_decrypt) (void *ctx, - const void *nonce, size_t noncesize, - const void *auth, size_t authsize, - size_t tag_size, - const void *encr, size_t encrsize, - void *plain, size_t plainsize); - int (*auth) (void *ctx, const void *data, size_t datasize); - void (*tag) (void *ctx, void *tag, size_t tagsize); - void (*deinit) (void *ctx); + gnutls_cipher_init_func init; + gnutls_cipher_setkey_func setkey; + gnutls_cipher_setiv_func setiv; + gnutls_cipher_encrypt_func encrypt; + gnutls_cipher_decrypt_func decrypt; + gnutls_cipher_aead_encrypt_func aead_encrypt; + gnutls_cipher_aead_decrypt_func aead_decrypt; + gnutls_cipher_deinit_func deinit; + gnutls_cipher_auth_func auth; + gnutls_cipher_tag_func tag; /* Not needed for registered on run-time. Only included * should define it. */ @@ -353,9 +341,8 @@ typedef struct gnutls_crypto_pk { */ int gnutls_crypto_single_cipher_register(gnutls_cipher_algorithm_t algorithm, int priority, - const - gnutls_crypto_single_cipher_st * - s); + const gnutls_crypto_single_cipher_st *s, + int free_s); int gnutls_crypto_single_mac_register(gnutls_mac_algorithm_t algorithm, int priority, const gnutls_crypto_single_mac_st * diff --git a/lib/includes/gnutls/crypto.h b/lib/includes/gnutls/crypto.h index 70ba3eaa7a..76bcc0652d 100644 --- a/lib/includes/gnutls/crypto.h +++ b/lib/includes/gnutls/crypto.h @@ -135,6 +135,52 @@ int gnutls_rnd(gnutls_rnd_level_t level, void *data, size_t len); void gnutls_rnd_refresh(void); +typedef int (*gnutls_cipher_init_func) (gnutls_cipher_algorithm_t, void **ctx, int enc); +typedef int (*gnutls_cipher_setkey_func) (void *ctx, const void *key, size_t keysize); +/* old style ciphers */ +typedef int (*gnutls_cipher_setiv_func) (void *ctx, const void *iv, size_t ivsize); +typedef int (*gnutls_cipher_encrypt_func) (void *ctx, const void *plain, size_t plainsize, + void *encr, size_t encrsize); +typedef int (*gnutls_cipher_decrypt_func) (void *ctx, const void *encr, size_t encrsize, + void *plain, size_t plainsize); + +/* aead ciphers */ +typedef int (*gnutls_cipher_auth_func) (void *ctx, const void *data, size_t datasize); +typedef void (*gnutls_cipher_tag_func) (void *ctx, void *tag, size_t tagsize); + +typedef int (*gnutls_cipher_aead_encrypt_func) (void *ctx, + const void *nonce, size_t noncesize, + const void *auth, size_t authsize, + size_t tag_size, + const void *plain, size_t plainsize, + void *encr, size_t encrsize); +typedef int (*gnutls_cipher_aead_decrypt_func) (void *ctx, + const void *nonce, size_t noncesize, + const void *auth, size_t authsize, + size_t tag_size, + const void *encr, size_t encrsize, + void *plain, size_t plainsize); +typedef void (*gnutls_cipher_deinit_func) (void *ctx); + +int +gnutls_crypto_register_cipher(gnutls_cipher_algorithm_t algorithm, + int priority, + gnutls_cipher_init_func init, + gnutls_cipher_setkey_func setkey, + gnutls_cipher_setiv_func setiv, + gnutls_cipher_encrypt_func encrypt, + gnutls_cipher_decrypt_func decrypt, + gnutls_cipher_deinit_func deinit); + +int +gnutls_crypto_register_aead_cipher(gnutls_cipher_algorithm_t algorithm, + int priority, + gnutls_cipher_init_func init, + gnutls_cipher_setkey_func setkey, + gnutls_cipher_aead_encrypt_func aead_encrypt, + gnutls_cipher_aead_decrypt_func aead_decrypt, + gnutls_cipher_deinit_func deinit); + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 84e304a7bb..3ea41a057e 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -1015,7 +1015,9 @@ GNUTLS_3_4 gnutls_record_set_state; gnutls_record_get_state; gnutls_pkcs11_obj_set_info; - local: + gnutls_crypto_register_cipher; + gnutls_crypto_register_aead_cipher; + local: *; };