diff options
Diffstat (limited to 'crypto/evp/cmeth_lib.c')
-rw-r--r-- | crypto/evp/cmeth_lib.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/crypto/evp/cmeth_lib.c b/crypto/evp/cmeth_lib.c index 6c328c0deb..0520157cd8 100644 --- a/crypto/evp/cmeth_lib.c +++ b/crypto/evp/cmeth_lib.c @@ -11,6 +11,7 @@ #include <openssl/evp.h> #include "internal/evp_int.h" +#include "internal/provider.h" #include "evp_locl.h" EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len) @@ -21,6 +22,12 @@ EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len) 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; } @@ -30,14 +37,35 @@ 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); - if (to != NULL) + if (to != NULL) { + CRYPTO_RWLOCK *lock = to->lock; + memcpy(to, cipher, sizeof(*to)); + to->lock = lock; + } return to; } void EVP_CIPHER_meth_free(EVP_CIPHER *cipher) { - OPENSSL_free(cipher); + if (cipher != NULL) { + int i; + + CRYPTO_DOWN_REF(&cipher->refcnt, &i, cipher->lock); + if (i > 0) + return; + ossl_provider_free(cipher->prov); + CRYPTO_THREAD_lock_free(cipher->lock); + OPENSSL_free(cipher); + } +} + +int EVP_CIPHER_upref(EVP_CIPHER *cipher) +{ + int ref = 0; + + CRYPTO_UP_REF(&cipher->refcnt, &ref, cipher->lock); + return 1; } int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len) |