Commit 96fddf6b9c for openssl.org
commit 96fddf6b9c44af363efeaaa5220301780a98f5ae
Author: Eugene Syromiatnikov <esyr@openssl.org>
Date: Tue May 12 14:14:00 2026 +0200
Consistenly zeroize public parameters based on OPENSSL_PEDANTIC_ZEROIZATION
Commit fa338aa7cd1e "fips: zeroization of public security parameters (PSPs)"[1]
introduced zeroization of public security params, which then[2] switched
its usage to OPENSSL_PEDANTIC_ZEROIZATION; however, zeroization has
implemented inconsistently, leaving out public security parameter
updates. Consistently use newly introduced wrappers,
ossl_public_bn_free and ossl_public_param_free, for freeing such
parameters, and use them for FFC and RSA.
[1] https://github.com/openssl/openssl/pull/24355
[2] https://github.com/openssl/openssl/pull/26068
Complements: fa338aa7cd1e "fips: zeroization of public security parameters (PSPs)"
Signed-off-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Milan Broz <mbroz@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
MergeDate: Wed Jun 10 12:52:14 2026
(Merged from https://github.com/openssl/openssl/pull/31157)
diff --git a/crypto/ffc/ffc_params.c b/crypto/ffc/ffc_params.c
index 6da6527a4b..23d3fab56b 100644
--- a/crypto/ffc/ffc_params.c
+++ b/crypto/ffc/ffc_params.c
@@ -12,6 +12,7 @@
#include "internal/ffc.h"
#include "internal/param_build_set.h"
#include "internal/nelem.h"
+#include "internal/zeroization.h"
#ifndef FIPS_MODULE
#include <openssl/asn1.h> /* ossl_ffc_params_print */
@@ -27,34 +28,27 @@ void ossl_ffc_params_init(FFC_PARAMS *params)
void ossl_ffc_params_cleanup(FFC_PARAMS *params)
{
-#ifdef OPENSSL_PEDANTIC_ZEROIZATION
- BN_clear_free(params->p);
- BN_clear_free(params->q);
- BN_clear_free(params->g);
- BN_clear_free(params->j);
- OPENSSL_clear_free(params->seed, params->seedlen);
-#else
- BN_free(params->p);
- BN_free(params->q);
- BN_free(params->g);
- BN_free(params->j);
- OPENSSL_free(params->seed);
-#endif
+ ossl_public_bn_free(params->p);
+ ossl_public_bn_free(params->q);
+ ossl_public_bn_free(params->g);
+ ossl_public_bn_free(params->j);
+ ossl_public_param_free(params->seed, params->seedlen);
+
ossl_ffc_params_init(params);
}
void ossl_ffc_params_set0_pqg(FFC_PARAMS *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
{
if (p != NULL && p != d->p) {
- BN_free(d->p);
+ ossl_public_bn_free(d->p);
d->p = p;
}
if (q != NULL && q != d->q) {
- BN_free(d->q);
+ ossl_public_bn_free(d->q);
d->q = q;
}
if (g != NULL && g != d->g) {
- BN_free(d->g);
+ ossl_public_bn_free(d->g);
d->g = g;
}
}
@@ -73,7 +67,7 @@ void ossl_ffc_params_get0_pqg(const FFC_PARAMS *d, const BIGNUM **p,
/* j is the 'cofactor' that is optionally output for ASN1. */
void ossl_ffc_params_set0_j(FFC_PARAMS *d, BIGNUM *j)
{
- BN_free(d->j);
+ ossl_public_bn_free(d->j);
d->j = NULL;
if (j != NULL)
d->j = j;
@@ -85,7 +79,7 @@ int ossl_ffc_params_set_seed(FFC_PARAMS *params,
if (params->seed != NULL) {
if (params->seed == seed)
return 1;
- OPENSSL_free(params->seed);
+ ossl_public_param_free(params->seed, params->seedlen);
}
if (seed != NULL && seedlen > 0) {
@@ -172,7 +166,7 @@ static int ffc_bn_cpy(BIGNUM **dst, const BIGNUM *src)
a = (BIGNUM *)src;
else if ((a = BN_dup(src)) == NULL)
return 0;
- BN_clear_free(*dst);
+ ossl_public_bn_free(*dst);
*dst = a;
return 1;
}
@@ -189,7 +183,7 @@ int ossl_ffc_params_copy(FFC_PARAMS *dst, const FFC_PARAMS *src)
dst->mdname = src->mdname;
dst->mdprops = src->mdprops;
- OPENSSL_free(dst->seed);
+ ossl_public_param_free(dst->seed, dst->seedlen);
dst->seedlen = src->seedlen;
if (src->seed != NULL) {
dst->seed = OPENSSL_memdup(src->seed, src->seedlen);
diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c
index e6b16162dd..a7d5798c88 100644
--- a/crypto/rsa/rsa_lib.c
+++ b/crypto/rsa/rsa_lib.c
@@ -17,9 +17,10 @@
#include <openssl/core_names.h>
#include <openssl/evp.h>
#include <openssl/param_build.h>
+#include "internal/common.h"
#include "internal/cryptlib.h"
#include "internal/refcount.h"
-#include "internal/common.h"
+#include "internal/zeroization.h"
#include "crypto/bn.h"
#include "crypto/evp.h"
#include "crypto/rsa.h"
@@ -137,13 +138,8 @@ void RSA_free(RSA *r)
CRYPTO_THREAD_lock_free(r->lock);
CRYPTO_FREE_REF(&r->references);
-#ifdef OPENSSL_PEDANTIC_ZEROIZATION
- BN_clear_free(r->n);
- BN_clear_free(r->e);
-#else
- BN_free(r->n);
- BN_free(r->e);
-#endif
+ ossl_public_bn_free(r->n);
+ ossl_public_bn_free(r->e);
BN_clear_free(r->d);
BN_clear_free(r->p);
BN_clear_free(r->q);
@@ -384,11 +380,11 @@ int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
return 0;
if (n != NULL) {
- BN_free(r->n);
+ ossl_public_bn_free(r->n);
r->n = n;
}
if (e != NULL) {
- BN_free(r->e);
+ ossl_public_bn_free(r->e);
r->e = e;
}
if (d != NULL) {
diff --git a/include/internal/zeroization.h b/include/internal/zeroization.h
new file mode 100644
index 0000000000..be8e18d638
--- /dev/null
+++ b/include/internal/zeroization.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * Utility functions for handling OPENSSL_PEDANTIC_ZEROIZATION.
+ *
+ * ISO 19790:2012/Cor.1:2015 7.9 requires cryptographic module to provide
+ * methods to zeroise all unproctected security sensitive parameters
+ * (which includes both Critical/Private and Public security parameters).
+ *
+ * To comply with these (arguably, unnecessarily onerous) requirements,
+ * freeing of public parameters is done via ossl_public_security_param_free()
+ * and ossl_public_security_param_bn_free() functions, and those implement
+ * the required behaviour if OPENSSL_PEDANTIC_ZEROIZATION is defined.
+ */
+
+#ifndef OSSL_INTERNAL_ZEROIZATION_H
+#define OSSL_INTERNAL_ZEROIZATION_H
+
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#include <openssl/e_os2.h>
+
+static ossl_unused ossl_inline void
+ossl_public_param_free(void *ptr, size_t size)
+{
+#ifdef OPENSSL_PEDANTIC_ZEROIZATION
+ OPENSSL_clear_free(ptr, size);
+#else
+ OPENSSL_free(ptr);
+#endif
+}
+
+static ossl_unused ossl_inline void
+ossl_public_bn_free(BIGNUM *bn)
+{
+#ifdef OPENSSL_PEDANTIC_ZEROIZATION
+ BN_clear_free(bn);
+#else
+ BN_free(bn);
+#endif
+}
+
+#endif /* OSSL_INTERNAL_ZEROIZATION_H */