#include "fips.h"
#include "algorithms.h"
+#ifdef ENABLE_PKCS11
+#include "pkcs11/p11_provider.h"
+#endif
+
#define SR_FB(x, cleanup) \
ret = (x); \
if (ret < 0) { \
*/
int _gnutls_cipher_exists(gnutls_cipher_algorithm_t cipher)
{
- const gnutls_crypto_cipher_st *cc;
- int ret;
-
if (!is_cipher_algo_allowed(cipher))
return 0;
if (cipher == GNUTLS_CIPHER_NULL)
return 1;
- cc = _gnutls_get_crypto_cipher(cipher);
- if (cc != NULL)
+ if (_gnutls_get_crypto_cipher(cipher) != NULL)
return 1;
- ret = _gnutls_cipher_ops.exists(cipher);
- return ret;
+ return _gnutls_cipher_backend()->exists(cipher);
}
int _gnutls_cipher_init(cipher_hd_st *handle, const cipher_entry_st *e,
{
int ret = GNUTLS_E_INTERNAL_ERROR;
const gnutls_crypto_cipher_st *cc = NULL;
+ const gnutls_crypto_cipher_st *fallback_cc = _gnutls_cipher_backend();
if (unlikely(e == NULL || e->id == GNUTLS_CIPHER_NULL))
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
handle->e = e;
handle->handle = NULL;
+#if defined(ENABLE_PKCS11) && defined(ENABLE_FIPS140)
+ /* Prioritize crypto from pkcs11 provider */
+ if (_p11_provider_is_initialized())
+ goto fallback;
+#endif
+
/* check if a cipher has been registered
*/
cc = _gnutls_get_crypto_cipher(e->id);
}
fallback:
- handle->encrypt = _gnutls_cipher_ops.encrypt;
- handle->decrypt = _gnutls_cipher_ops.decrypt;
- handle->aead_encrypt = _gnutls_cipher_ops.aead_encrypt;
- handle->aead_decrypt = _gnutls_cipher_ops.aead_decrypt;
- handle->deinit = _gnutls_cipher_ops.deinit;
- handle->auth = _gnutls_cipher_ops.auth;
- handle->tag = _gnutls_cipher_ops.tag;
- handle->setiv = _gnutls_cipher_ops.setiv;
- handle->getiv = _gnutls_cipher_ops.getiv;
- handle->setkey = _gnutls_cipher_ops.setkey;
+ handle->encrypt = fallback_cc->encrypt;
+ handle->decrypt = fallback_cc->decrypt;
+ handle->aead_encrypt = fallback_cc->aead_encrypt;
+ handle->aead_decrypt = fallback_cc->aead_decrypt;
+ handle->deinit = fallback_cc->deinit;
+ handle->auth = fallback_cc->auth;
+ handle->tag = fallback_cc->tag;
+ handle->setiv = fallback_cc->setiv;
+ handle->getiv = fallback_cc->getiv;
+ handle->setkey = fallback_cc->setkey;
/* otherwise use generic cipher interface
*/
- ret = _gnutls_cipher_ops.init(e->id, &handle->handle, enc);
+ ret = fallback_cc->init(e->id, &handle->handle, enc);
if (ret < 0) {
gnutls_assert();
return ret;
}
- ret = _gnutls_cipher_ops.setkey(handle->handle, key->data, key->size);
+ ret = fallback_cc->setkey(handle->handle, key->data, key->size);
if (ret < 0) {
gnutls_assert();
goto cc_cleanup;
}
if (iv) {
- ret = _gnutls_cipher_ops.setiv(handle->handle, iv->data,
- iv->size);
+ ret = fallback_cc->setiv(handle->handle, iv->data, iv->size);
if (ret < 0) {
gnutls_assert();
goto cc_cleanup;
#include "crypto-backend.h"
extern int crypto_cipher_prio;
-extern gnutls_crypto_cipher_st _gnutls_cipher_ops;
typedef int (*cipher_encrypt_func)(void *hd, const void *plaintext, size_t,
void *ciphertext, size_t);
gnutls_free(handle);
}
-extern gnutls_crypto_kdf_st _gnutls_kdf_ops;
-
/* Same as @gnutls_hkdf_extract but without changing FIPS context */
int _gnutls_hkdf_extract(gnutls_mac_algorithm_t mac, const gnutls_datum_t *key,
const gnutls_datum_t *salt, void *output)
/* We don't check whether MAC is approved, because HKDF is
* only approved in TLS, which is handled separately. */
- return _gnutls_kdf_ops.hkdf_extract(mac, key->data, key->size,
- salt ? salt->data : NULL,
- salt ? salt->size : 0, output);
+ return _gnutls_kdf_backend()->hkdf_extract(mac, key->data, key->size,
+ salt ? salt->data : NULL,
+ salt ? salt->size : 0,
+ output);
}
/**
/* We don't check whether MAC is approved, because HKDF is
* only approved in TLS, which is handled separately. */
- return _gnutls_kdf_ops.hkdf_expand(mac, key->data, key->size,
- info->data, info->size, output,
- length);
+ return _gnutls_kdf_backend()->hkdf_expand(mac, key->data, key->size,
+ info->data, info->size,
+ output, length);
}
/**
not_approved = true;
}
- ret = _gnutls_kdf_ops.pbkdf2(mac, key->data, key->size, salt->data,
- salt->size, iter_count, output, length);
+ ret = _gnutls_kdf_backend()->pbkdf2(mac, key->data, key->size,
+ salt->data, salt->size, iter_count,
+ output, length);
if (ret < 0) {
_gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
} else if (not_approved) {
_deregister(&glob_dl);
}
+extern gnutls_crypto_cipher_st _gnutls_cipher_ops;
+extern gnutls_crypto_pk_st _gnutls_pk_ops;
+extern gnutls_crypto_mac_st _gnutls_mac_ops;
+extern gnutls_crypto_digest_st _gnutls_digest_ops;
+extern gnutls_crypto_kdf_st _gnutls_kdf_ops;
+
+#ifdef ENABLE_PKCS11
+extern gnutls_crypto_cipher_st _gnutls_p11_cipher_ops;
+extern gnutls_crypto_pk_st _gnutls_p11_pk_ops;
+extern gnutls_crypto_mac_st _gnutls_p11_mac_ops;
+extern gnutls_crypto_digest_st _gnutls_p11_digest_ops;
+extern gnutls_crypto_kdf_st _gnutls_p11_kdf_ops;
+#endif
+
+const gnutls_crypto_cipher_st *_gnutls_cipher_backend(void)
+{
+#if defined(ENABLE_PKCS11) && defined(ENABLE_FIPS140)
+ if (_p11_provider_is_initialized())
+ return &_gnutls_p11_cipher_ops;
+#endif
+ return &_gnutls_cipher_ops;
+}
+
+const gnutls_crypto_pk_st *_gnutls_pk_backend(void)
+{
+#if defined(ENABLE_PKCS11) && defined(ENABLE_FIPS140)
+ if (_p11_provider_is_initialized())
+ return &_gnutls_p11_pk_ops;
+#endif
+ return &_gnutls_pk_ops;
+}
+
+const gnutls_crypto_mac_st *_gnutls_mac_backend(void)
+{
+#if defined(ENABLE_PKCS11) && defined(ENABLE_FIPS140)
+ if (_p11_provider_is_initialized())
+ return &_gnutls_p11_mac_ops;
+#endif
+ return &_gnutls_mac_ops;
+}
+
+const gnutls_crypto_digest_st *_gnutls_digest_backend(void)
+{
+#if defined(ENABLE_PKCS11) && defined(ENABLE_FIPS140)
+ if (_p11_provider_is_initialized())
+ return &_gnutls_p11_digest_ops;
+#endif
+ return &_gnutls_digest_ops;
+}
+
+const gnutls_crypto_kdf_st *_gnutls_kdf_backend(void)
+{
+#if defined(ENABLE_PKCS11) && defined(ENABLE_FIPS140)
+ if (_p11_provider_is_initialized())
+ return &_gnutls_p11_kdf_ops;
+#endif
+ return &_gnutls_kdf_ops;
+}
+
/*-
* gnutls_crypto_single_cipher_register:
* @algorithm: is the gnutls algorithm identifier
const gnutls_datum_t *data, unsigned char *buffer,
size_t buffer_size);
+const gnutls_crypto_cipher_st *_gnutls_cipher_backend(void) ATTRIBUTE_PURE;
+const gnutls_crypto_pk_st *_gnutls_pk_backend(void) ATTRIBUTE_PURE;
+const gnutls_crypto_mac_st *_gnutls_mac_backend(void) ATTRIBUTE_PURE;
+const gnutls_crypto_digest_st *_gnutls_digest_backend(void) ATTRIBUTE_PURE;
+const gnutls_crypto_kdf_st *_gnutls_kdf_backend(void) ATTRIBUTE_PURE;
+
#endif /* GNUTLS_LIB_CRYPTO_BACKEND_H */
#include "algorithms.h"
#include "fips.h"
+#ifdef ENABLE_PKCS11
+#include "pkcs11/p11_provider.h"
+#endif
+
int _gnutls_hash_init(digest_hd_st *dig, const mac_entry_st *e)
{
int result;
/* check if a digest has been registered
*/
cc = _gnutls_get_crypto_digest((gnutls_digest_algorithm_t)e->id);
- if (cc != NULL && cc->init) {
+ if (
+#if defined(ENABLE_PKCS11) && defined(ENABLE_FIPS140)
+ /* Prioritize crypto from pkcs11 provider */
+ !_p11_provider_is_initialized() &&
+#endif
+ cc != NULL && cc->init) {
if (cc->init((gnutls_digest_algorithm_t)e->id, &dig->handle) <
0) {
gnutls_assert();
return 0;
}
- result = _gnutls_digest_ops.init((gnutls_digest_algorithm_t)e->id,
- &dig->handle);
+ result = _gnutls_digest_backend()->init(
+ (gnutls_digest_algorithm_t)e->id, &dig->handle);
if (result < 0) {
gnutls_assert();
return result;
}
- dig->hash = _gnutls_digest_ops.hash;
- dig->output = _gnutls_digest_ops.output;
- dig->deinit = _gnutls_digest_ops.deinit;
- dig->copy = _gnutls_digest_ops.copy;
+ dig->hash = _gnutls_digest_backend()->hash;
+ dig->output = _gnutls_digest_backend()->output;
+ dig->deinit = _gnutls_digest_backend()->deinit;
+ dig->copy = _gnutls_digest_backend()->copy;
return 0;
}
return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
cc = _gnutls_get_crypto_digest(algo);
- if (cc != NULL)
+ if (
+#if defined(ENABLE_PKCS11) && defined(ENABLE_FIPS140)
+ /* Prioritize crypto from pkcs11 provider */
+ !_p11_provider_is_initialized() &&
+#endif
+ cc != NULL)
return 1;
- return _gnutls_digest_ops.exists(algo);
+ return _gnutls_digest_backend()->exists(algo);
}
int _gnutls_hash_copy(const digest_hd_st *handle, digest_hd_st *dst)
/* check if a digest has been registered
*/
cc = _gnutls_get_crypto_digest(algorithm);
- if (cc != NULL) {
+ if (
+#if defined(ENABLE_PKCS11) && defined(ENABLE_FIPS140)
+ /* Prioritize crypto from pkcs11 provider */
+ !_p11_provider_is_initialized() &&
+#endif
+ cc != NULL) {
if (cc->fast(algorithm, text, textlen, digest) < 0) {
gnutls_assert();
return GNUTLS_E_HASH_FAILED;
return 0;
}
- ret = _gnutls_digest_ops.fast(algorithm, text, textlen, digest);
+ ret = _gnutls_digest_backend()->fast(algorithm, text, textlen, digest);
if (ret < 0) {
gnutls_assert();
return ret;
/* check if a digest has been registered
*/
cc = _gnutls_get_crypto_mac(algorithm);
- if (cc != NULL) {
+ if (
+#if defined(ENABLE_PKCS11) && defined(ENABLE_FIPS140)
+ /* Prioritize crypto from pkcs11 provider */
+ !_p11_provider_is_initialized() &&
+#endif
+ cc != NULL) {
if (cc->fast(algorithm, NULL, 0, key, keylen, text, textlen,
digest) < 0) {
gnutls_assert();
return 0;
}
- ret = _gnutls_mac_ops.fast(algorithm, NULL, 0, key, keylen, text,
- textlen, digest);
+ ret = _gnutls_mac_backend()->fast(algorithm, NULL, 0, key, keylen, text,
+ textlen, digest);
if (ret < 0) {
gnutls_assert();
return ret;
return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
cc = _gnutls_get_crypto_mac(algo);
- if (cc != NULL)
+ if (
+#if defined(ENABLE_PKCS11) && defined(ENABLE_FIPS140)
+ /* Prioritize crypto from pkcs11 provider */
+ !_p11_provider_is_initialized() &&
+#endif
+ cc != NULL)
return 1;
- return _gnutls_mac_ops.exists(algo);
+ return _gnutls_mac_backend()->exists(algo);
}
int _gnutls_mac_init(mac_hd_st *mac, const mac_entry_st *e, const void *key,
/* check if a digest has been registered
*/
cc = _gnutls_get_crypto_mac(e->id);
- if (cc != NULL && cc->init != NULL) {
+ if (
+#if defined(ENABLE_PKCS11) && defined(ENABLE_FIPS140)
+ /* Prioritize crypto from pkcs11 provider */
+ !_p11_provider_is_initialized() &&
+#endif
+ cc != NULL && cc->init != NULL) {
+
if (cc->init(e->id, &mac->handle) < 0) {
gnutls_assert();
return GNUTLS_E_HASH_FAILED;
return 0;
}
- result = _gnutls_mac_ops.init(e->id, &mac->handle);
+ result = _gnutls_mac_backend()->init(e->id, &mac->handle);
if (result < 0) {
gnutls_assert();
return result;
}
- mac->hash = _gnutls_mac_ops.hash;
- mac->setnonce = _gnutls_mac_ops.setnonce;
- mac->output = _gnutls_mac_ops.output;
- mac->deinit = _gnutls_mac_ops.deinit;
- mac->copy = _gnutls_mac_ops.copy;
- mac->setkey = _gnutls_mac_ops.setkey;
+ mac->hash = _gnutls_mac_backend()->hash;
+ mac->setnonce = _gnutls_mac_backend()->setnonce;
+ mac->output = _gnutls_mac_backend()->output;
+ mac->deinit = _gnutls_mac_backend()->deinit;
+ mac->copy = _gnutls_mac_backend()->copy;
+ mac->setkey = _gnutls_mac_backend()->setkey;
- if (_gnutls_mac_ops.setkey(mac->handle, key, keylen) < 0) {
+ if (_gnutls_mac_backend()->setkey(mac->handle, key, keylen) < 0) {
gnutls_assert();
mac->deinit(mac->handle);
return GNUTLS_E_HASH_FAILED;
/* for message digests */
extern int crypto_mac_prio;
-extern gnutls_crypto_mac_st _gnutls_mac_ops;
-
extern int crypto_digest_prio;
-extern gnutls_crypto_digest_st _gnutls_digest_ops;
typedef int (*hash_func)(void *handle, const void *text, size_t size);
typedef int (*nonce_func)(void *handle, const void *text, size_t size);
#ifndef GNUTLS_LIB_PK_H
#define GNUTLS_LIB_PK_H
+#include "crypto-backend.h"
+
extern int crypto_pk_prio;
-extern gnutls_crypto_pk_st _gnutls_pk_ops;
#define _gnutls_pk_encrypt(algo, ciphertext, plaintext, params) \
- _gnutls_pk_ops.encrypt(algo, ciphertext, plaintext, params)
+ _gnutls_pk_backend()->encrypt(algo, ciphertext, plaintext, params)
#define _gnutls_pk_decrypt(algo, ciphertext, plaintext, params) \
- _gnutls_pk_ops.decrypt(algo, ciphertext, plaintext, params)
-#define _gnutls_pk_decrypt2(algo, ciphertext, plaintext, size, params) \
- _gnutls_pk_ops.decrypt2(algo, ciphertext, plaintext, size, params)
+ _gnutls_pk_backend()->decrypt(algo, ciphertext, plaintext, params)
+#define _gnutls_pk_decrypt2(algo, ciphertext, plaintext, size, params) \
+ _gnutls_pk_backend()->decrypt2(algo, ciphertext, plaintext, size, \
+ params)
#define _gnutls_pk_sign(algo, sig, data, params, sign_params) \
- _gnutls_pk_ops.sign(algo, sig, data, params, sign_params)
+ _gnutls_pk_backend()->sign(algo, sig, data, params, sign_params)
#define _gnutls_pk_verify(algo, data, sig, params, sign_params) \
- _gnutls_pk_ops.verify(algo, data, sig, params, sign_params)
+ _gnutls_pk_backend()->verify(algo, data, sig, params, sign_params)
#define _gnutls_pk_verify_priv_params(algo, params) \
- _gnutls_pk_ops.verify_priv_params(algo, params)
+ _gnutls_pk_backend()->verify_priv_params(algo, params)
#define _gnutls_pk_verify_pub_params(algo, params) \
- _gnutls_pk_ops.verify_pub_params(algo, params)
+ _gnutls_pk_backend()->verify_pub_params(algo, params)
#define _gnutls_pk_derive(algo, out, pub, priv) \
- _gnutls_pk_ops.derive(algo, out, pub, priv, NULL, 0)
+ _gnutls_pk_backend()->derive(algo, out, pub, priv, NULL, 0)
#define _gnutls_pk_derive_nonce(algo, out, pub, priv, nonce) \
- _gnutls_pk_ops.derive(algo, out, pub, priv, nonce, 0)
-#define _gnutls_pk_derive_tls13(algo, out, pub, priv) \
- _gnutls_pk_ops.derive(algo, out, pub, priv, NULL, PK_DERIVE_TLS13)
+ _gnutls_pk_backend()->derive(algo, out, pub, priv, nonce, 0)
+#define _gnutls_pk_derive_tls13(algo, out, pub, priv) \
+ _gnutls_pk_backend()->derive(algo, out, pub, priv, NULL, \
+ PK_DERIVE_TLS13)
#define _gnutls_pk_encaps(algo, ciphertext, shared_secret, pub) \
- _gnutls_pk_ops.encaps(algo, ciphertext, shared_secret, pub)
+ _gnutls_pk_backend()->encaps(algo, ciphertext, shared_secret, pub)
#define _gnutls_pk_decaps(algo, shared_secret, ciphertext, priv) \
- _gnutls_pk_ops.decaps(algo, shared_secret, ciphertext, priv)
+ _gnutls_pk_backend()->decaps(algo, shared_secret, ciphertext, priv)
#define _gnutls_pk_generate_keys(algo, bits, params, temporal) \
- _gnutls_pk_ops.generate_keys(algo, bits, params, temporal)
+ _gnutls_pk_backend()->generate_keys(algo, bits, params, temporal)
#define _gnutls_pk_generate_params(algo, bits, priv) \
- _gnutls_pk_ops.generate_params(algo, bits, priv)
+ _gnutls_pk_backend()->generate_params(algo, bits, priv)
#define _gnutls_pk_hash_algorithm(pk, sig, params, hash) \
- _gnutls_pk_ops.hash_algorithm(pk, sig, params, hash)
-#define _gnutls_pk_curve_exists(curve) _gnutls_pk_ops.curve_exists(curve)
-#define _gnutls_pk_exists(algo) _gnutls_pk_ops.pk_exists(algo)
-#define _gnutls_pk_sign_exists(algo) _gnutls_pk_ops.sign_exists(algo)
+ _gnutls_pk_backend()->hash_algorithm(pk, sig, params, hash)
+#define _gnutls_pk_curve_exists(curve) _gnutls_pk_backend()->curve_exists(curve)
+#define _gnutls_pk_exists(algo) _gnutls_pk_backend()->pk_exists(algo)
+#define _gnutls_pk_sign_exists(algo) _gnutls_pk_backend()->sign_exists(algo)
inline static int _gnutls_pk_fixup(gnutls_pk_algorithm_t algo,
gnutls_direction_t direction,
gnutls_pk_params_st *params)
{
- if (_gnutls_pk_ops.pk_fixup_private_params)
- return _gnutls_pk_ops.pk_fixup_private_params(algo, direction,
- params);
+ if (_gnutls_pk_backend()->pk_fixup_private_params)
+ return _gnutls_pk_backend()->pk_fixup_private_params(
+ algo, direction, params);
return 0;
}