EVP_CIPHER_CTX_settable_params(c), 4);
}
}
- sk_EVP_CIPHER_pop_free(ciphers, EVP_CIPHER_meth_free);
+ sk_EVP_CIPHER_pop_free(ciphers, EVP_CIPHER_free);
}
static void list_md_fn(const EVP_MD *m,
EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len)
{
- EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER));
+ EVP_CIPHER *cipher = evp_cipher_new();
if (cipher != NULL) {
cipher->nid = cipher_type;
cipher->block_size = block_size;
cipher->key_len = key_len;
- cipher->lock = CRYPTO_THREAD_lock_new();
- if (cipher->lock == NULL) {
- OPENSSL_free(cipher);
- return NULL;
- }
- cipher->refcnt = 1;
}
return cipher;
}
EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher)
{
- EVP_CIPHER *to = EVP_CIPHER_meth_new(cipher->nid, cipher->block_size,
- cipher->key_len);
+ EVP_CIPHER *to = NULL;
- if (to != NULL) {
+ /*
+ * Non-legacy EVP_CIPHERs can't be duplicated like this.
+ * Use EVP_CIPHER_up_ref() instead.
+ */
+ if (cipher->prov != NULL)
+ return NULL;
+
+ if ((to = EVP_CIPHER_meth_new(cipher->nid, cipher->block_size,
+ cipher->key_len)) == NULL) {
CRYPTO_RWLOCK *lock = to->lock;
memcpy(to, cipher, sizeof(*to));
void EVP_CIPHER_meth_free(EVP_CIPHER *cipher)
{
- if (cipher != NULL) {
- int i;
-
- CRYPTO_DOWN_REF(&cipher->refcnt, &i, cipher->lock);
- if (i > 0)
- return;
- ossl_provider_free(cipher->prov);
- OPENSSL_free(cipher->name);
- CRYPTO_THREAD_lock_free(cipher->lock);
- OPENSSL_free(cipher);
- }
-}
-
-int EVP_CIPHER_up_ref(EVP_CIPHER *cipher)
-{
- int ref = 0;
-
- CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock);
- return 1;
+ EVP_CIPHER_free(cipher);
}
int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len)
ctx->provctx = NULL;
}
if (ctx->fetched_cipher != NULL)
- EVP_CIPHER_meth_free(ctx->fetched_cipher);
+ EVP_CIPHER_free(ctx->fetched_cipher);
memset(ctx, 0, sizeof(*ctx));
return 1;
|| impl != NULL) {
if (ctx->cipher == ctx->fetched_cipher)
ctx->cipher = NULL;
- EVP_CIPHER_meth_free(ctx->fetched_cipher);
+ EVP_CIPHER_free(ctx->fetched_cipher);
ctx->fetched_cipher = NULL;
goto legacy;
}
return 0;
}
cipher = provciph;
- EVP_CIPHER_meth_free(ctx->fetched_cipher);
+ EVP_CIPHER_free(ctx->fetched_cipher);
ctx->fetched_cipher = provciph;
#endif
}
return 1;
}
+EVP_CIPHER *evp_cipher_new(void)
+{
+ EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER));
+
+ if (cipher != NULL) {
+ cipher->lock = CRYPTO_THREAD_lock_new();
+ if (cipher->lock == NULL) {
+ OPENSSL_free(cipher);
+ return NULL;
+ }
+ cipher->refcnt = 1;
+ }
+ return cipher;
+}
+
static void *evp_cipher_from_dispatch(const char *name,
const OSSL_DISPATCH *fns,
OSSL_PROVIDER *prov,
EVP_CIPHER *cipher = NULL;
int fnciphcnt = 0, fnctxcnt = 0;
- if ((cipher = EVP_CIPHER_meth_new(0, 0, 0)) == NULL
+ if ((cipher = evp_cipher_new()) == NULL
|| (cipher->name = OPENSSL_strdup(name)) == NULL) {
- EVP_CIPHER_meth_free(cipher);
+ EVP_CIPHER_free(cipher);
EVPerr(0, ERR_R_MALLOC_FAILURE);
return NULL;
}
* functions, or a single "cipher" function. In all cases we need both
* the "newctx" and "freectx" functions.
*/
- EVP_CIPHER_meth_free(cipher);
+ EVP_CIPHER_free(cipher);
EVPerr(EVP_F_EVP_CIPHER_FROM_DISPATCH, EVP_R_INVALID_PROVIDER_FUNCTIONS);
return NULL;
}
static void evp_cipher_free(void *cipher)
{
- EVP_CIPHER_meth_free(cipher);
+ EVP_CIPHER_free(cipher);
}
EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
return cipher;
}
+int EVP_CIPHER_up_ref(EVP_CIPHER *cipher)
+{
+ int ref = 0;
+
+ CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock);
+ return 1;
+}
+
+void EVP_CIPHER_free(EVP_CIPHER *cipher)
+{
+ int i;
+
+ if (cipher == NULL)
+ return;
+
+ CRYPTO_DOWN_REF(&cipher->refcnt, &i, cipher->lock);
+ if (i > 0)
+ return;
+ ossl_provider_free(cipher->prov);
+ OPENSSL_free(cipher->name);
+ CRYPTO_THREAD_lock_free(cipher->lock);
+ OPENSSL_free(cipher);
+}
+
void EVP_CIPHER_do_all_ex(OPENSSL_CTX *libctx,
void (*fn)(EVP_CIPHER *mac, void *arg),
void *arg)
/* Internal structure constructors for fetched methods */
EVP_MD *evp_md_new(void);
+EVP_CIPHER *evp_cipher_new(void);
/* Helper functions to avoid duplicating code */
{
EVP_CIPHER_CTX_free(drbg->data.ctr.ctx);
EVP_CIPHER_CTX_free(drbg->data.ctr.ctx_df);
- EVP_CIPHER_meth_free(drbg->data.ctr.cipher);
+ EVP_CIPHER_free(drbg->data.ctr.cipher);
OPENSSL_cleanse(&drbg->data.ctr, sizeof(drbg->data.ctr));
return 1;
}
if (cipher == NULL)
return 0;
- EVP_CIPHER_meth_free(ctr->cipher);
+ EVP_CIPHER_free(ctr->cipher);
ctr->cipher = cipher;
drbg->meth = &drbg_ctr_meth;
EVP_CIPHER_meth_set_ctrl, EVP_CIPHER_meth_get_init,
EVP_CIPHER_meth_get_do_cipher, EVP_CIPHER_meth_get_cleanup,
EVP_CIPHER_meth_get_set_asn1_params, EVP_CIPHER_meth_get_get_asn1_params,
-EVP_CIPHER_meth_get_ctrl, EVP_CIPHER_up_ref
+EVP_CIPHER_meth_get_ctrl
- Routines to build up EVP_CIPHER methods
=head1 SYNOPSIS
int type, int arg,
void *ptr);
- int EVP_CIPHER_up_ref(EVP_CIPHER *cipher);
-
=head1 DESCRIPTION
The B<EVP_CIPHER> type is a structure for symmetric cipher method
are all used to retrieve the method data given with the
EVP_CIPHER_meth_set_*() functions above.
-EVP_CIPHER_up_ref() increments the reference count for an EVP_CIPHER structure.
-
=head1 RETURN VALUES
EVP_CIPHER_meth_new() and EVP_CIPHER_meth_dup() return a pointer to a
All EVP_CIPHER_meth_get_*() functions return pointers to their
respective B<cipher> function.
-EVP_CIPHER_up_ref() returns 1 for success or 0 otherwise.
-
=head1 SEE ALSO
L<EVP_EncryptInit>
=head1 HISTORY
The functions described here were added in OpenSSL 1.1.0.
+The B<EVP_CIPHER> structure created with these functions became reference
+counted in OpenSSL 3.0.
=head1 COPYRIGHT
=head1 NAME
EVP_CIPHER_fetch,
+EVP_CIPHER_up_ref,
+EVP_CIPHER_free,
EVP_CIPHER_CTX_new,
EVP_CIPHER_CTX_reset,
EVP_CIPHER_CTX_free,
EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
const char *properties);
+ int EVP_CIPHER_up_ref(EVP_CIPHER *cipher);
+ void EVP_CIPHER_free(EVP_CIPHER *cipher);
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx);
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx);
The EVP cipher routines are a high level interface to certain
symmetric ciphers.
+The B<EVP_CIPHER> type is a structure for cipher method implementation.
+
EVP_CIPHER_fetch() fetches the cipher implementation for the given
B<algorithm> from any provider offering it, within the criteria given
by the B<properties>.
See L<provider(7)/Fetching algorithms> for further information.
-The returned value must eventually be freed with
-L<EVP_CIPHER_meth_free(3)>.
+The returned value must eventually be freed with EVP_CIPHER_free().
+
+EVP_CIPHER_up_ref() increments the reference count for an B<EVP_CIPHER>
+structure.
+
+EVP_CIPHER_free() decrements the reference count for the B<EVP_CIPHER>
+structure.
+If the reference count drops to 0 then the structure is freed.
EVP_CIPHER_CTX_new() creates a cipher context.
EVP_CIPHER_fetch() returns a pointer to a B<EVP_CIPHER> for success
and B<NULL> for failure.
+EVP_CIPHER_up_ref() returns 1 for success or 0 otherwise.
+
EVP_CIPHER_CTX_new() returns a pointer to a newly created
B<EVP_CIPHER_CTX> for success and B<NULL> for failure.
disappeared. EVP_CIPHER_CTX_init() remains as an alias for
EVP_CIPHER_CTX_reset().
+The EVP_CIPHER_fetch(), EVP_CIPHER_free(), EVP_CIPHER_up_ref(),
+EVP_CIPHER_CTX_set_params() and EVP_CIPHER_CTX_get_params() functions
+were added in 3.0.
+
=head1 COPYRIGHT
Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len);
EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher);
void EVP_CIPHER_meth_free(EVP_CIPHER *cipher);
-int EVP_CIPHER_up_ref(EVP_CIPHER *cipher);
int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len);
int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags);
int EVP_CIPHER_mode(const EVP_CIPHER *cipher);
EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
const char *properties);
+int EVP_CIPHER_up_ref(EVP_CIPHER *cipher);
+void EVP_CIPHER_free(EVP_CIPHER *cipher);
const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx);
int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx);
if (macctx != NULL) {
CMAC_CTX_free(macctx->ctx);
- EVP_CIPHER_meth_free(macctx->alloc_cipher);
+ EVP_CIPHER_free(macctx->alloc_cipher);
OPENSSL_free(macctx);
}
}
propquery = p->data;
}
- EVP_CIPHER_meth_free(macctx->alloc_cipher);
+ EVP_CIPHER_free(macctx->alloc_cipher);
macctx->tmpcipher = macctx->alloc_cipher =
EVP_CIPHER_fetch(PROV_LIBRARY_CONTEXT_OF(macctx->provctx),
if (macctx != NULL) {
EVP_CIPHER_CTX_free(macctx->ctx);
- EVP_CIPHER_meth_free(macctx->alloc_cipher);
+ EVP_CIPHER_free(macctx->alloc_cipher);
OPENSSL_free(macctx);
}
}
propquery = p->data;
}
- EVP_CIPHER_meth_free(macctx->alloc_cipher);
+ EVP_CIPHER_free(macctx->alloc_cipher);
macctx->cipher = macctx->alloc_cipher = NULL;
macctx->cipher = macctx->alloc_cipher =
if (!TEST_true(EVP_CIPHER_up_ref(cipher)))
goto err;
/* Ref count should now be 2. Release both */
- EVP_CIPHER_meth_free(cipher);
- EVP_CIPHER_meth_free(cipher);
+ EVP_CIPHER_free(cipher);
+ EVP_CIPHER_free(cipher);
cipher = NULL;
/*
goto err;
}
- EVP_CIPHER_meth_free(cipher);
+ EVP_CIPHER_free(cipher);
cipher = NULL;
/*
goto err;
}
- EVP_CIPHER_meth_free(cipher);
+ EVP_CIPHER_free(cipher);
cipher = NULL;
/*
ret = 1;
err:
- EVP_CIPHER_meth_free(cipher);
+ EVP_CIPHER_free(cipher);
OSSL_PROVIDER_unload(defltprov);
OSSL_PROVIDER_unload(fipsprov);
/* Not normally needed, but we would like to test that
EVP_MAC_provider 4843 3_0_0 EXIST::FUNCTION:
EVP_MAC_do_all_ex 4844 3_0_0 EXIST::FUNCTION:
EVP_MD_free 4845 3_0_0 EXIST::FUNCTION:
+EVP_CIPHER_free 4846 3_0_0 EXIST::FUNCTION: