diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2015-04-07 15:39:18 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2015-04-07 15:41:36 +0200 |
commit | 35d47fa659ad3509a888b4555f90e9b413af84c7 (patch) | |
tree | 7612fa33710c2c7fad7393b234840e79b7a303d3 | |
parent | ad4cac84dd32edf79827c48d549e0ddef7dbd669 (diff) | |
download | gnutls-35d47fa659ad3509a888b4555f90e9b413af84c7.tar.gz |
introduced GNUTLS_E_NEED_FALLBACK to allow falling back from registered ciphers
That allows a registered cipher to indicate that it cannot operate
(e.g., due to memory constraints, or internal limits), and gnutls should
proceed with the default algorithms.
-rw-r--r-- | lib/crypto-backend.c | 9 | ||||
-rw-r--r-- | lib/gnutls_cipher_int.c | 13 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 2 |
3 files changed, 23 insertions, 1 deletions
diff --git a/lib/crypto-backend.c b/lib/crypto-backend.c index a4415169ca..b509fabdc7 100644 --- a/lib/crypto-backend.c +++ b/lib/crypto-backend.c @@ -151,6 +151,9 @@ void _gnutls_crypto_deregister(void) * priority of 90 and CPU-assisted of 80. The algorithm with the lowest priority will be * used by gnutls. * + * In the case the registered init function return %GNUTLS_E_NEED_FALLBACK + * then GnuTLS will attempt to use the next in priority registered cipher. + * * This function should be called before gnutls_global_init(). * * For simplicity you can use the convenience @@ -193,6 +196,9 @@ const gnutls_crypto_cipher_st * priority of 90 and CPU-assisted of 80. The algorithm with the lowest priority will be * used by gnutls. * + * In the case the registered init function return %GNUTLS_E_NEED_FALLBACK + * then GnuTLS will attempt to use the next in priority registered cipher. + * * 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. @@ -241,6 +247,9 @@ gnutls_crypto_register_cipher(gnutls_cipher_algorithm_t algorithm, * priority of 90 and CPU-assisted of 80. The algorithm with the lowest priority will be * used by gnutls. * + * In the case the registered init function return %GNUTLS_E_NEED_FALLBACK + * then GnuTLS will attempt to use the next in priority registered cipher. + * * The functions registered will be used with the new AEAD API introduced in * GnuTLS 3.4.0. Internally GnuTLS uses the new AEAD API. * diff --git a/lib/gnutls_cipher_int.c b/lib/gnutls_cipher_int.c index 3368bae5b4..6670023c8c 100644 --- a/lib/gnutls_cipher_int.c +++ b/lib/gnutls_cipher_int.c @@ -30,6 +30,14 @@ #include <fips.h> #include <algorithms.h> +#define SR_FB(x, cleanup) ret=(x); if ( ret<0 ) { \ + if (ret == GNUTLS_E_NEED_FALLBACK) \ + goto fallback; \ + gnutls_assert(); \ + ret = GNUTLS_E_INTERNAL_ERROR; \ + goto cleanup; \ + } + #define SR(x, cleanup) if ( (x)<0 ) { \ gnutls_assert(); \ ret = GNUTLS_E_INTERNAL_ERROR; \ @@ -80,7 +88,9 @@ _gnutls_cipher_init(cipher_hd_st * handle, const cipher_entry_st * e, handle->tag = cc->tag; handle->setiv = cc->setiv; - SR(cc->init(e->id, &handle->handle, enc), cc_cleanup); + /* if cc->init() returns GNUTLS_E_NEED_FALLBACK we + * use the default ciphers */ + SR_FB(cc->init(e->id, &handle->handle, enc), cc_cleanup); SR(cc->setkey(handle->handle, key->data, key->size), cc_cleanup); if (iv) { @@ -91,6 +101,7 @@ _gnutls_cipher_init(cipher_hd_st * handle, const cipher_entry_st * e, return 0; } + fallback: handle->encrypt = _gnutls_cipher_ops.encrypt; handle->decrypt = _gnutls_cipher_ops.decrypt; handle->aead_encrypt = _gnutls_cipher_ops.aead_encrypt; diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 2511b99915..a4bb933500 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -2507,6 +2507,8 @@ int gnutls_fips140_mode_enabled(void); #define GNUTLS_E_PK_GENERATION_ERROR -403 #define GNUTLS_E_IDNA_ERROR -404 +#define GNUTLS_E_NEED_FALLBACK -405 + #define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250 |