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 */