From 57049ca2ac4676ba6ab02509e740799cf39e42ac Mon Sep 17 00:00:00 2001
From: michellew-vmware <michellew@vmware.com>
Date: Tue, 27 Jun 2023 18:26:05 +0000
Subject: [PATCH] Get rid of  EVP_MD_CTX_FLAG_NON_FIPS_ALLOW

- openssl-3.x provides EVP_MD_fetch() api to make use of non fips algorithms in user space programs.
- EVP_MD_CTX_FLAG_NON_FIPS_ALLOW is obsolete.
---
 libntp/a_md5encrypt.c | 76 +++++++++++++++++++++++++++++++++++++------
 ntpd/ntp_control.c    | 54 ++++++++++++++++--------------
 ntpd/ntp_crypto.c     | 60 ++++++++++++++++++++++------------
 sntp/crypto.c         | 48 ++++++++++++++++++++-------
 4 files changed, 172 insertions(+), 66 deletions(-)

Index: ntp-4.2.8p17/libntp/a_md5encrypt.c
===================================================================
--- ntp-4.2.8p17.orig/libntp/a_md5encrypt.c
+++ ntp-4.2.8p17/libntp/a_md5encrypt.c
@@ -11,6 +11,8 @@
 #include "ntp.h"
 #include "isc/string.h"
 
+#include <openssl/core_names.h>
+
 typedef struct {
 	const void *	buf;
 	size_t		len;
@@ -110,10 +112,31 @@ make_mac(
 			goto mac_fail;
 		}
 
-	   #ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
-		/* make sure MD5 is allowd */
+
+#   if OPENSSL_VERSION_NUMBER >= 0x30000000
+                /* make sure MD5 is allowed */
+		OSSL_LIB_CTX *octx = OSSL_LIB_CTX_new();
+		if (!octx) {
+		    msyslog(LOG_ERR, "MAC encrypt: OSSL_LIB_CTX_new failed\n");
+		    goto mac_fail;
+		}
+
+		EVP_MD *type = EVP_MD_fetch(octx, OBJ_nid2sn(ktype), "-fips");
+		if (!type) {
+		    msyslog(LOG_ERR, "MAC encrypt: EVP_MD_fetch failed\n");
+		    goto mac_fail;
+		}
+
+		if (!EVP_DigestInit_ex(ctx, type, NULL)) {
+		    msyslog(LOG_ERR, "MAC encrypt: MAC %s Digest Init failed.",
+			    OBJ_nid2sn(ktype));
+		    goto mac_fail;
+		}
+#   else
+#       ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
 		EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-	   #endif
+#       endif
+
 		/* [Bug 3457] DON'T use plain EVP_DigestInit! It would
 		 * kill the flags! */
 		if (!EVP_DigestInit_ex(ctx, EVP_get_digestbynid(ktype), NULL)) {
@@ -121,6 +144,7 @@ make_mac(
 				OBJ_nid2sn(ktype));
 			goto mac_fail;
 		}
+#       endif
 		if ((size_t)EVP_MD_CTX_size(ctx) > digest->len) {
 			msyslog(LOG_ERR, "MAC encrypt: MAC %s buf too small.",
 				OBJ_nid2sn(ktype));
@@ -146,6 +170,12 @@ make_mac(
 
 		if (ctx)
 			EVP_MD_CTX_free(ctx);
+#   if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x30000000
+        if (type)
+            EVP_MD_free(type);
+        if (octx)
+            OSSL_LIB_CTX_free(octx);
+#   endif
 	}
 
 #else /* !OPENSSL follows */
@@ -270,23 +300,51 @@ addr2refid(sockaddr_u *addr)
 	INIT_SSL();
 
 	ctx = EVP_MD_CTX_new();
+#   if OPENSSL_VERSION_NUMBER >= 0x30000000
+    /* MD5 is not used as a crypto hash here. */
+    OSSL_LIB_CTX *octx = OSSL_LIB_CTX_new();
+    if (!octx) {
+        msyslog(LOG_ERR, "addr2refid: OSSL_LIB_CTX_new failed\n");
+        exit(1);
+    }
+
+    EVP_MD *type = EVP_MD_fetch(octx, OSSL_DIGEST_NAME_MD5, "-fips");
+    if (!type) {
+        msyslog(LOG_ERR, "addr2refid: EVP_MD_fetch failed\n");
+        exit(1);
+    }
+
+    if (!EVP_DigestInit_ex(ctx, type, NULL)) {
+        msyslog(LOG_ERR, "MD5 init failed");
+        EVP_MD_CTX_free(ctx);   /* pedantic... but safe */
+        exit(1);
+    }
+#   else
 #   ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
-	/* MD5 is not used as a crypto hash here. */
-	EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
 #   endif
 	/* [Bug 3457] DON'T use plain EVP_DigestInit! It would kill the
 	 * flags! */
 	if (!EVP_DigestInit_ex(ctx, EVP_md5(), NULL)) {
-		msyslog(LOG_ERR,
-		    "MD5 init failed");
+		msyslog(LOG_ERR, "MD5 init failed");
 		EVP_MD_CTX_free(ctx);	/* pedantic... but safe */
 		exit(1);
 	}
+#   endif
 
 	EVP_DigestUpdate(ctx, (u_char *)PSOCK_ADDR6(addr),
 	    sizeof(struct in6_addr));
 	EVP_DigestFinal(ctx, digest, &len);
 	EVP_MD_CTX_free(ctx);
-	memcpy(&addr_refid, digest, sizeof(addr_refid));
-	return (addr_refid);
+
+#   if OPENSSL_VERSION_NUMBER >= 0x30000000
+    if (type)
+        EVP_MD_free(type);
+    if (octx)
+        OSSL_LIB_CTX_free(octx);
+#   endif
+
+    memcpy(&addr_refid, digest, sizeof(addr_refid));
+
+    return (addr_refid);
 }
Index: ntp-4.2.8p17/ntpd/ntp_control.c
===================================================================
--- ntp-4.2.8p17.orig/ntpd/ntp_control.c
+++ ntp-4.2.8p17/ntpd/ntp_control.c
@@ -29,6 +29,8 @@
 #include "lib_strbuf.h"
 #include "timexsup.h"
 
+#include <openssl/core_names.h>
+
 #include <rc_cmdlength.h>
 #ifdef KERNEL_PLL
 # include "ntp_syscall.h"
@@ -3662,33 +3664,37 @@ static u_int32 derive_nonce(
 	}
 
 	ctx = EVP_MD_CTX_new();
-#   if defined(OPENSSL) && defined(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)
-	/* [Bug 3457] set flags and don't kill them again */
-	EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-	rc = EVP_DigestInit_ex(ctx, EVP_get_digestbynid(NID_md5), NULL);
+#   if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x30000000
+    /* [Bug 3457] set flags and don't kill them again */
+    OSSL_LIB_CTX *octx = OSSL_LIB_CTX_new();
+    EVP_MD *type = EVP_MD_fetch(octx, OSSL_DIGEST_NAME_MD5, "-fips");
+    EVP_DigestInit_ex(ctx, type, NULL);
 #   else
-	rc = EVP_DigestInit(ctx, EVP_get_digestbynid(NID_md5));
+#   ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#   endif
+        EVP_DigestInit(ctx, EVP_get_digestbynid(NID_md5));
+#   endif
+        EVP_DigestUpdate(ctx, salt, sizeof(salt));
+        EVP_DigestUpdate(ctx, &ts_i, sizeof(ts_i));
+        EVP_DigestUpdate(ctx, &ts_f, sizeof(ts_f));
+        if (IS_IPV4(addr))
+                EVP_DigestUpdate(ctx, &SOCK_ADDR4(addr),
+                                 sizeof(SOCK_ADDR4(addr)));
+        else
+                EVP_DigestUpdate(ctx, &SOCK_ADDR6(addr),
+                                 sizeof(SOCK_ADDR6(addr)));
+        EVP_DigestUpdate(ctx, &NSRCPORT(addr), sizeof(NSRCPORT(addr)));
+        EVP_DigestUpdate(ctx, salt, sizeof(salt));
+        EVP_DigestFinal(ctx, d.digest, &len);
+        EVP_MD_CTX_free(ctx);
+#   if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x30000000
+    EVP_MD_free(type);
+    OSSL_LIB_CTX_free(octx);
 #   endif
-	if (!rc) {
-		msyslog(LOG_ERR, "EVP_DigestInit failed in '%s'", __func__);
-		return (0);
-	}
 
-	EVP_DigestUpdate(ctx, salt, sizeof(salt));
-	EVP_DigestUpdate(ctx, &ts_i, sizeof(ts_i));
-	EVP_DigestUpdate(ctx, &ts_f, sizeof(ts_f));
-	if (IS_IPV4(addr))
-		EVP_DigestUpdate(ctx, &SOCK_ADDR4(addr),
-			         sizeof(SOCK_ADDR4(addr)));
-	else
-		EVP_DigestUpdate(ctx, &SOCK_ADDR6(addr),
-			         sizeof(SOCK_ADDR6(addr)));
-	EVP_DigestUpdate(ctx, &NSRCPORT(addr), sizeof(NSRCPORT(addr)));
-	EVP_DigestUpdate(ctx, salt, sizeof(salt));
-	EVP_DigestFinal(ctx, d.digest, &len);
-	EVP_MD_CTX_free(ctx);
+        return d.extract;
 
-	return d.extract;
 }
 
 
Index: ntp-4.2.8p17/ntpd/ntp_crypto.c
===================================================================
--- ntp-4.2.8p17.orig/ntpd/ntp_crypto.c
+++ ntp-4.2.8p17/ntpd/ntp_crypto.c
@@ -34,6 +34,8 @@
 #include "openssl/x509v3.h"
 #include "libssl_compat.h"
 
+#include <openssl/core_names.h>
+
 #ifdef KERNEL_PLL
 #include "ntp_syscall.h"
 #endif /* KERNEL_PLL */
@@ -268,16 +270,24 @@ session_key(
 		break;
 	}
 	ctx = EVP_MD_CTX_new();
-#   if defined(OPENSSL) && defined(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)
-	/* [Bug 3457] set flags and don't kill them again */
-	EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-	EVP_DigestInit_ex(ctx, EVP_get_digestbynid(crypto_nid), NULL);
+#   if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x30000000
+    /* [Bug 3457] set flags and don't kill them again */
+    OSSL_LIB_CTX *octx = OSSL_LIB_CTX_new();
+    EVP_MD *type = EVP_MD_fetch(octx, OBJ_nid2sn(crypto_nid), "-fips");
+    EVP_DigestInit_ex(ctx, type, NULL);
 #   else
-	EVP_DigestInit(ctx, EVP_get_digestbynid(crypto_nid));
+#   ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#   endif
+        EVP_DigestInit(ctx, EVP_get_digestbynid(crypto_nid));
+#   endif
+        EVP_DigestUpdate(ctx, (u_char *)header, hdlen);
+        EVP_DigestFinal(ctx, dgst, &len);
+        EVP_MD_CTX_free(ctx);
+#   if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x30000000
+    EVP_MD_free(type);
+    OSSL_LIB_CTX_free(octx);
 #   endif
-	EVP_DigestUpdate(ctx, (u_char *)header, hdlen);
-	EVP_DigestFinal(ctx, dgst, &len);
-	EVP_MD_CTX_free(ctx);
 	memcpy(&keyid, dgst, 4);
 	keyid = ntohl(keyid);
 	if (lifetime != 0) {
@@ -374,7 +384,7 @@ make_keylist(
 	 * Save the last session key ID, sequence number and timestamp,
 	 * then sign these values for later retrieval by the clients. Be
 	 * careful not to use invalid key media. Use the public values
-	 * timestamp as filestamp. 
+	 * timestamp as filestamp.
 	 */
 	vp = &peer->sndval;
 	if (vp->ptr == NULL)
@@ -896,8 +906,8 @@ crypto_recv(
 			 * autokey values.
 			 */
 			if ((rval = crypto_verify(ep, &peer->recval,
-			    peer)) != XEVNT_OK) 
-				break;
+                            peer)) != XEVNT_OK)
+                                break;
 
 			/*
 			 * Discard the message if a broadcast client and
@@ -2094,18 +2104,26 @@ bighash(
 	ptr = emalloc(len);
 	BN_bn2bin(bn, ptr);
 	ctx = EVP_MD_CTX_new();
-#   if defined(OPENSSL) && defined(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)
-	/* [Bug 3457] set flags and don't kill them again */
-	EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-	EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
+#   if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x30000000
+    /* [Bug 3457] set flags and don't kill them again */
+    OSSL_LIB_CTX *octx = OSSL_LIB_CTX_new();
+    EVP_MD *type = EVP_MD_fetch(octx, OSSL_DIGEST_NAME_MD5, "-fips");
+    EVP_DigestInit_ex(ctx, type, NULL);
 #   else
-	EVP_DigestInit(ctx, EVP_md5());
+#   ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
 #   endif
-	EVP_DigestUpdate(ctx, ptr, len);
-	EVP_DigestFinal(ctx, dgst, &len);
-	EVP_MD_CTX_free(ctx);
-	BN_bin2bn(dgst, len, bk);
-	free(ptr);
+        EVP_DigestInit(ctx, EVP_md5());
+#   endif
+        EVP_DigestUpdate(ctx, ptr, len);
+        EVP_DigestFinal(ctx, dgst, &len);
+        EVP_MD_CTX_free(ctx);
+#   if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x30000000
+    EVP_MD_free(type);
+    OSSL_LIB_CTX_free(octx);
+#   endif
+        BN_bin2bn(dgst, len, bk);
+        free(ptr);
 }
 
 
Index: ntp-4.2.8p17/sntp/crypto.c
===================================================================
--- ntp-4.2.8p17.orig/sntp/crypto.c
+++ ntp-4.2.8p17/sntp/crypto.c
@@ -80,16 +80,36 @@ compute_mac(
 			goto mac_fail;
 		}
 #ifdef OPENSSL	/* OpenSSL 1 supports return codes 0 fail, 1 okay */
-#	    ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
-		EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-#	    endif
-		/* [Bug 3457] DON'T use plain EVP_DigestInit! It would
-		 *  kill the flags! */
-		if (!EVP_DigestInit_ex(ctx, EVP_get_digestbynid(key_type), NULL)) {
-			msyslog(LOG_ERR, "make_mac: MAC %s Digest Init failed.",
-				macname);
-			goto mac_fail;
-		}
+#   if OPENSSL_VERSION_NUMBER >= 0x30000000
+        OSSL_LIB_CTX *octx = OSSL_LIB_CTX_new();
+        if (!octx) {
+            msyslog(LOG_ERR, "make_mac: OSSL_LIB_CTX_new failed");
+            goto mac_fail;
+        }
+
+        EVP_MD *type = EVP_MD_fetch(octx, OBJ_nid2sn(key_type), "-fips");
+        if (!type) {
+            msyslog(LOG_ERR, "make_mac: EVP_MD_fetch failed");
+            goto mac_fail;
+        }
+
+        /* [Bug 3457] DON'T use plain EVP_DigestInit! It would
+                 *  kill the flags! */
+        if (!EVP_DigestInit_ex(ctx, type, NULL)) {
+                        msyslog(LOG_ERR, "make_mac: MAC %s Digest Init failed.",
+                                macname);
+                        goto mac_fail;
+                }
+#   else
+#       ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+        EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#       endif
+        if (!EVP_DigestInit_ex(ctx, EVP_get_digestbynid(key_type), NULL)) {
+            msyslog(LOG_ERR, "make_mac: MAC %s Digest Init failed.",
+                    macname);
+            goto mac_fail;
+        }
+#   endif
 		if (!EVP_DigestUpdate(ctx, key_data, key_size)) {
 			msyslog(LOG_ERR, "make_mac: MAC %s Digest Update key failed.",
 				macname);
@@ -117,7 +137,13 @@ compute_mac(
 #endif
 	  mac_fail:
 		EVP_MD_CTX_free(ctx);
-	}
+#   if defined(OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x30000000
+        if (type)
+            EVP_MD_free(type);
+        if (octx)
+            OSSL_LIB_CTX_free(octx);
+#   endif
+        }
 
 	return len;
 }
