ciphers: add FIPS error state handling
[openssl.git] / providers / implementations / ciphers / cipher_aes_siv.c
index 86243780336d81e1c167b1d2ddd4718f8ddbc259..6894567fb278520a787b38a822e37d308e85e2f1 100644 (file)
 
 #include "cipher_aes_siv.h"
 #include "prov/implementations.h"
+#include "prov/providercommon.h"
 #include "prov/providercommonerr.h"
 #include "prov/ciphercommon_aead.h"
+#include "prov/provider_ctx.h"
 
 #define siv_stream_update siv_cipher
 #define SIV_FLAGS AEAD_FLAGS
 static void *aes_siv_newctx(void *provctx, size_t keybits, unsigned int mode,
                             uint64_t flags)
 {
-    PROV_AES_SIV_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+    PROV_AES_SIV_CTX *ctx;
 
+    if (!ossl_prov_is_running())
+        return NULL;
+
+    ctx = OPENSSL_zalloc(sizeof(*ctx));
     if (ctx != NULL) {
         ctx->taglen = SIV_LEN;
         ctx->mode = mode;
         ctx->flags = flags;
         ctx->keylen = keybits / 8;
         ctx->hw = PROV_CIPHER_HW_aes_siv(keybits);
+        ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
     }
     return ctx;
 }
@@ -48,11 +55,34 @@ static void aes_siv_freectx(void *vctx)
     }
 }
 
+static void *siv_dupctx(void *vctx)
+{
+    PROV_AES_SIV_CTX *in = (PROV_AES_SIV_CTX *)vctx;
+    PROV_AES_SIV_CTX *ret;
+
+    if (!ossl_prov_is_running())
+        return NULL;
+
+    ret = OPENSSL_malloc(sizeof(*ret));
+    if (ret == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    if (!in->hw->dupctx(in, ret)) {
+        OPENSSL_free(ret);
+        ret = NULL;
+    }
+    return ret;
+}
+
 static int siv_init(void *vctx, const unsigned char *key, size_t keylen,
                     const unsigned char *iv, size_t ivlen, int enc)
 {
     PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
 
+    if (!ossl_prov_is_running())
+        return 0;
+
     ctx->enc = enc;
 
     if (key != NULL) {
@@ -82,6 +112,9 @@ static int siv_cipher(void *vctx, unsigned char *out, size_t *outl,
 {
     PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
 
+    if (!ossl_prov_is_running())
+        return 0;
+
     if (inl == 0) {
         *outl = 0;
         return 1;
@@ -105,6 +138,9 @@ static int siv_stream_final(void *vctx, unsigned char *out, size_t *outl,
 {
     PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
 
+    if (!ossl_prov_is_running())
+        return 0;
+
     if (!ctx->hw->cipher(vctx, out, NULL, 0))
         return 0;
 
@@ -148,7 +184,7 @@ static const OSSL_PARAM aes_siv_known_gettable_ctx_params[] = {
     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
     OSSL_PARAM_END
 };
-static const OSSL_PARAM *aes_siv_gettable_ctx_params(void)
+static const OSSL_PARAM *aes_siv_gettable_ctx_params(ossl_unused void *provctx)
 {
     return aes_siv_known_gettable_ctx_params;
 }
@@ -198,19 +234,33 @@ static const OSSL_PARAM aes_siv_known_settable_ctx_params[] = {
     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
     OSSL_PARAM_END
 };
-static const OSSL_PARAM *aes_siv_settable_ctx_params(void)
+static const OSSL_PARAM *aes_siv_settable_ctx_params(ossl_unused void *provctx)
 {
     return aes_siv_known_settable_ctx_params;
 }
 
 #define IMPLEMENT_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits)       \
-static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lc##_get_params;         \
+static OSSL_FUNC_cipher_newctx_fn alg##kbits##lc##_newctx;                     \
+static OSSL_FUNC_cipher_freectx_fn alg##_##lc##_freectx;                       \
+static OSSL_FUNC_cipher_dupctx_fn lc##_dupctx;                                 \
+static OSSL_FUNC_cipher_encrypt_init_fn lc##_einit;                            \
+static OSSL_FUNC_cipher_decrypt_init_fn lc##_dinit;                            \
+static OSSL_FUNC_cipher_update_fn lc##_stream_update;                          \
+static OSSL_FUNC_cipher_final_fn lc##_stream_final;                            \
+static OSSL_FUNC_cipher_cipher_fn lc##_cipher;                                 \
+static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lc##_get_params;       \
+static OSSL_FUNC_cipher_gettable_params_fn alg##_##lc##_gettable_ctx_params;   \
+static OSSL_FUNC_cipher_get_ctx_params_fn alg##_##lc##_get_ctx_params;         \
+static OSSL_FUNC_cipher_gettable_ctx_params_fn                                 \
+            alg##_##lc##_gettable_ctx_params;                                  \
+static OSSL_FUNC_cipher_set_ctx_params_fn alg##_##lc##_set_ctx_params;         \
+static OSSL_FUNC_cipher_settable_ctx_params_fn                                 \
+            alg##_##lc##_settable_ctx_params;                                  \
 static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[])              \
 {                                                                              \
     return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE,         \
                                      flags, 2*kbits, blkbits, ivbits);         \
 }                                                                              \
-static OSSL_OP_cipher_newctx_fn alg##kbits##lc##_newctx;                       \
 static void * alg##kbits##lc##_newctx(void *provctx)                           \
 {                                                                              \
     return alg##_##lc##_newctx(provctx, 2*kbits, EVP_CIPH_##UCMODE##_MODE,     \
@@ -219,6 +269,7 @@ static void * alg##kbits##lc##_newctx(void *provctx)                           \
 const OSSL_DISPATCH alg##kbits##lc##_functions[] = {                           \
     { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx },      \
     { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx },        \
+    { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) lc##_dupctx },                 \
     { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void)) lc##_einit },            \
     { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void)) lc##_dinit },            \
     { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void)) lc##_stream_update },          \