From e765de94eefd28262504d96e19146950a13ed826 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 28 Jul 2025 08:32:54 -0400 Subject: [PATCH] Add a way to cleanse params arrays This uses the return_size field of the last terminating parameter similaraly to how secure memory uses the data and data_size fields, to hold the total size of memory allocated for params. This is then used to be able to call OPENSSL_cleanse on the params fields via the new OSSL_PARAM_clear_free() call. Signed-off-by: Simo Sorce Reviewed-by: Tomas Mraz Reviewed-by: Dmitry Belyavskiy (Merged from https://github.com/openssl/openssl/pull/28108) --- crypto/param_build.c | 1 + crypto/params_dup.c | 16 ++++++++++++++++ doc/man3/OSSL_PARAM_dup.pod | 12 ++++++++++-- include/openssl/params.h | 1 + util/libcrypto.num | 1 + 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/crypto/param_build.c b/crypto/param_build.c index 62142aaf593..d2f082ff9ef 100644 --- a/crypto/param_build.c +++ b/crypto/param_build.c @@ -382,6 +382,7 @@ OSSL_PARAM *OSSL_PARAM_BLD_to_param(OSSL_PARAM_BLD *bld) blk = p_blks + (OSSL_PARAM_ALIGNED_BLOCK *)(params); last = param_bld_convert(bld, params, blk, s); ossl_param_set_secure_block(last, s, ss); + last->return_size = total; /* Reset builder for reuse */ bld->total_blocks = 0; diff --git a/crypto/params_dup.c b/crypto/params_dup.c index 73b18f38ff4..15a26eed9bb 100644 --- a/crypto/params_dup.c +++ b/crypto/params_dup.c @@ -139,6 +139,7 @@ OSSL_PARAM *OSSL_PARAM_dup(const OSSL_PARAM *src) /* Store the allocated secure memory buffer in the last param block */ ossl_param_set_secure_block(last, buf[OSSL_PARAM_BUF_SECURE].alloc, buf[OSSL_PARAM_BUF_SECURE].alloc_sz); + last->return_size = buf[OSSL_PARAM_BUF_PUBLIC].alloc_sz; return dst; } @@ -241,3 +242,18 @@ void OSSL_PARAM_free(OSSL_PARAM *params) OPENSSL_free(params); } } + +void OSSL_PARAM_clear_free(OSSL_PARAM *params) +{ + if (params != NULL) { + OSSL_PARAM *p; + + for (p = params; p->key != NULL; p++) + ; + if (p->data_type == OSSL_PARAM_ALLOCATED_END) + OPENSSL_secure_clear_free(p->data, p->data_size); + if (p->return_size > 0 && p->return_size != OSSL_PARAM_UNMODIFIED) + OPENSSL_cleanse(params, p->return_size); + OPENSSL_free(params); + } +} diff --git a/doc/man3/OSSL_PARAM_dup.pod b/doc/man3/OSSL_PARAM_dup.pod index c8d109a2278..9926ff41dac 100644 --- a/doc/man3/OSSL_PARAM_dup.pod +++ b/doc/man3/OSSL_PARAM_dup.pod @@ -2,7 +2,7 @@ =head1 NAME -OSSL_PARAM_dup, OSSL_PARAM_merge, OSSL_PARAM_free +OSSL_PARAM_dup, OSSL_PARAM_merge, OSSL_PARAM_free, OSSL_PARAM_clear_free - OSSL_PARAM array copy functions =head1 SYNOPSIS @@ -12,6 +12,7 @@ OSSL_PARAM_dup, OSSL_PARAM_merge, OSSL_PARAM_free OSSL_PARAM *OSSL_PARAM_dup(const OSSL_PARAM *params); OSSL_PARAM *OSSL_PARAM_merge(const OSSL_PARAM *params, const OSSL_PARAM *params1); void OSSL_PARAM_free(OSSL_PARAM *params); + void OSSL_PARAM_clear_free(OSSL_PARAM *params); =head1 DESCRIPTION @@ -34,6 +35,12 @@ OSSL_PARAM_free() frees the parameter array I that was created using OSSL_PARAM_dup(), OSSL_PARAM_merge() or OSSL_PARAM_BLD_to_param(). If the argument to OSSL_PARAM_free() is NULL, nothing is done. +OSSL_PARAM_clear_free() performs the same function as OSSL_PARAM_free() but +additionally calls OPENSSL_cleanse() on the contents copied in. Note: only +params built via the OSSL_PARAM_dup() or OSSL_PARAM_BLD_to_param() functions +will be effectively cleared, parameters built any other way will still be +freed but no cleanse operation will be performed. + =head1 RETURN VALUES The functions OSSL_PARAM_dup() and OSSL_PARAM_merge() return a newly allocated @@ -46,7 +53,8 @@ L, L =head1 HISTORY -The functions were added in OpenSSL 3.0. +The OSSL_PARAM_dup, OSSL_PARAM_merge and OSSL_PARAM_free functions were added +in OpenSSL 3.0. OSSL_PARAM_clear_free was added in OpenSSL 4.0.0. =head1 COPYRIGHT diff --git a/include/openssl/params.h b/include/openssl/params.h index eae67b11ca5..dfc67b5fb99 100644 --- a/include/openssl/params.h +++ b/include/openssl/params.h @@ -156,6 +156,7 @@ void OSSL_PARAM_set_all_unmodified(OSSL_PARAM *p); OSSL_PARAM *OSSL_PARAM_dup(const OSSL_PARAM *p); OSSL_PARAM *OSSL_PARAM_merge(const OSSL_PARAM *p1, const OSSL_PARAM *p2); void OSSL_PARAM_free(OSSL_PARAM *p); +void OSSL_PARAM_clear_free(OSSL_PARAM *p); int OSSL_PARAM_set_octet_string_or_ptr(OSSL_PARAM *p, const void *val, size_t len); diff --git a/util/libcrypto.num b/util/libcrypto.num index 327f9ca8924..c243ea0bd3b 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5950,3 +5950,4 @@ CRYPTO_secure_calloc ? 4_0_0 EXIST::FUNCTION: OPENSSL_posix_to_tm ? 4_0_0 EXIST::FUNCTION: OPENSSL_tm_to_posix ? 4_0_0 EXIST::FUNCTION: OPENSSL_timegm ? 4_0_0 EXIST::FUNCTION: +OSSL_PARAM_clear_free ? 4_0_0 EXIST::FUNCTION: -- 2.47.3