[Git][NTPsec/ntpsec][master] 8 commits: Remove/cleanup unneeded calls to EVP_MD_CTX_reset()

Hal Murray (@hal.murray) gitlab at mg.gitlab.com
Thu Mar 23 06:31:39 UTC 2023



Hal Murray pushed to branch master at NTPsec / ntpsec


Commits:
d80b4279 by Hal Murray at 2023-03-21T20:56:58-07:00
Remove/cleanup unneeded calls to EVP_MD_CTX_reset()

- - - - -
eb7aaf48 by Hal Murray at 2023-03-21T20:56:58-07:00
More tweaks for Coverity

- - - - -
e777754e by Hal Murray at 2023-03-21T20:56:58-07:00
Update/cleanup attic/cmac-timing.c

It now has 3 EVP sections
  one with no preloads
  one that preloads the cipher
  one that preloads both cipher and key

- - - - -
c5e8f6c9 by Hal Murray at 2023-03-21T20:56:59-07:00
First pass at switching from CMAC_xxx to EVP_MD_xxx

The current code has a per key EVP_MD_CTX
I expect to switch to one per cipher.

No change to libaes_siv yet.

- - - - -
42a0de82 by Hal Murray at 2023-03-21T20:56:59-07:00
Added AES test vectors from RFC 4493

- - - - -
cfc97680 by Hal Murray at 2023-03-22T00:33:19-07:00
Drop CMAC_VERSION_CUTOFF

- - - - -
6aed1205 by Hal Murray at 2023-03-22T00:34:00-07:00
authreadkeys now uses EVP_MAC_CTX_get_mac_size

- - - - -
cc4b750b by Hal Murray at 2023-03-22T00:34:38-07:00
Add attic/aes-siv-timing.c

- - - - -


16 changed files:

- + attic/aes-siv-timing.c
- attic/cmac-timing.c
- attic/random.c
- attic/sht.c
- attic/wscript
- devel/ifdex-ignores
- include/ntp_auth.h
- libntp/authkeys.c
- libntp/authreadkeys.c
- libntp/macencrypt.c
- libntp/pymodule-mac.c
- libntp/ssl_init.c
- ntpd/ntp_control.c
- ntpd/refclock_generic.c
- ntpd/refclock_oncore.c
- tests/libntp/macencrypt.c


Changes:

=====================================
attic/aes-siv-timing.c
=====================================
@@ -0,0 +1,371 @@
+/* Last modified on Sat Aug 28 14:30:11 PDT 1999 by murray */
+
+/* 
+ * Hack to time aead routines from libaes_siv
+ *
+ * RFC5297, October 2008
+ * Synthetic Initialization Vector (SIV) Authenticated Encryption
+ *           Using the Advanced Encryption Standard (AES)
+ *
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include "aes_siv.h"
+#include "nts.h"
+
+#define UNUSED_ARG(arg)         ((void)(arg))
+#define INSIST(x)       assert(x)
+
+int SAMPLESIZE = 1000000;
+
+AES_SIV_CTX* cookie_ctx;
+uint32_t key_I = 123;  /* timestamp or whatever used to \
+                        * indicate key used for this cookie */
+uint8_t key_K[NTS_MAX_KEYLEN];
+int     key_K_length;
+
+pthread_mutex_t cookie_lock = PTHREAD_MUTEX_INITIALIZER;
+
+
+/* sizeof(key_I) + sizeof(NONCE) */
+#define AD_LENGTH 20
+
+static void ssl_init(void)
+{
+  cookie_ctx = AES_SIV_CTX_new();
+  if (NULL == cookie_ctx) {
+    printf("NTS: Can't init cookie_ctx\n");
+    exit(1);
+  }
+}
+
+static void nts_lock_cookielock(void) {
+        int err = pthread_mutex_lock(&cookie_lock);
+        if (0 != err) {      
+                printf("ERR: Can't lock cookie_lock: %d\n", err);
+                exit(2);
+        }                    
+}
+        
+static void nts_unlock_cookielock(void) {
+        int err = pthread_mutex_unlock(&cookie_lock);
+        if (0 != err) {
+                printf("ERR: Can't unlock cookie_lock: %d\n", err);
+                exit(2);
+        }
+}
+
+static void ntp_RAND_bytes(unsigned char *buf, int num) {
+        int err;
+        err = RAND_bytes(buf, num);
+        if (1 != err) {
+                printf("ERR: RAND_bytes failed\n");
+                exit(1);
+        }
+}
+
+
+
+static void DoLock(void)
+{
+	struct timespec start, stop;
+	double fast;
+	int samplesize = SAMPLESIZE;
+
+	clock_gettime(CLOCK_MONOTONIC, &start);
+	for (int i = 0; i < samplesize; i++) {
+          nts_lock_cookielock();
+          nts_unlock_cookielock();
+	}
+	clock_gettime(CLOCK_MONOTONIC, &stop);
+	fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+	printf("LocK          %6.0f %7.3f",
+	       fast/samplesize,  fast/1E9);
+	printf("\n");
+}
+
+
+static void DoNonce(void)
+{
+        uint8_t nonce[NONCE_LENGTH];
+	struct timespec start, stop;
+	double fast;
+	int samplesize = SAMPLESIZE;
+
+	clock_gettime(CLOCK_MONOTONIC, &start);
+	for (int i = 0; i < samplesize; i++) {
+          ntp_RAND_bytes(nonce, NONCE_LENGTH);
+	}
+	clock_gettime(CLOCK_MONOTONIC, &stop);
+	fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+	printf("Nonce     %3d %6.0f %7.3f",
+	       NONCE_LENGTH, fast/samplesize,  fast/1E9);
+	printf("\n");
+}
+
+
+/* Clone of nts_make_cookie() from ntpd/nts_cookie.c */
+/* returns actual length */
+int nts_make_cookie(uint8_t *cookie,
+  uint16_t aead,
+  uint8_t *c2s, uint8_t *s2c, int keylen) {
+        uint8_t plaintext[NTS_MAX_COOKIELEN];
+        uint8_t *nonce;
+        int used, plainlength;
+        bool ok;
+        uint8_t * finger;
+        uint32_t temp;  /* keep 4 byte alignment */
+        size_t left;
+
+        if (NULL == cookie_ctx)
+                return 0;               /* We aren't initialized yet. */
+
+//        nts_cookie_make++;
+
+        INSIST(keylen <= NTS_MAX_KEYLEN);
+
+        finger = plaintext;
+        temp = aead;
+        memcpy(finger, &temp, sizeof(temp));
+        finger += sizeof(temp);
+        memcpy(finger, c2s, keylen);
+        finger += keylen;
+        memcpy(finger, s2c, keylen);
+        finger += keylen;
+        plainlength = finger-plaintext;
+
+        /* collect associated data */
+        finger = cookie;
+
+        memcpy(finger, &key_I, sizeof(key_I));
+        finger += sizeof(key_I);
+
+        nonce = finger;
+        ntp_RAND_bytes(nonce, NONCE_LENGTH);
+        finger += NONCE_LENGTH;
+
+        used = finger-cookie;
+        left = NTS_MAX_COOKIELEN-used;
+
+        nts_lock_cookielock();
+        ok = AES_SIV_Encrypt(cookie_ctx,
+                             finger, &left,   /* left: in: max out length, out: length used */
+                             key_K, key_K_length,
+                             nonce, NONCE_LENGTH,
+                             plaintext, plainlength,
+                             cookie, AD_LENGTH);
+        nts_unlock_cookielock();
+
+        if (!ok) {
+                printf("NTS: nts_make_cookie - Error from AES_SIV_Encrypt\n");
+                exit(1);
+        }
+
+        used += left;
+        INSIST(used <= NTS_MAX_COOKIELEN);
+
+        return used;
+}
+
+
+static void DoMakeCookie(
+  const char *name,       /* name of aead */
+  int     aead,		  /* algorithm used to make cookie */
+  int     keylength       /* length of c2s and s2c */
+)
+{
+	uint8_t cookie[NTS_MAX_COOKIELEN];
+	uint8_t c2s[NTS_MAX_KEYLEN], s2c[NTS_MAX_KEYLEN];
+	struct timespec start, stop;
+	double fast;
+	int cookielength = 0;
+	int samplesize = SAMPLESIZE;
+
+	switch (aead) {
+	  case AEAD_AES_SIV_CMAC_256:
+		key_K_length = AEAD_AES_SIV_CMAC_256_KEYLEN;
+		break;
+	  case AEAD_AES_SIV_CMAC_384:
+		key_K_length = AEAD_AES_SIV_CMAC_384_KEYLEN;
+		break;
+	  case AEAD_AES_SIV_CMAC_512:
+		key_K_length = AEAD_AES_SIV_CMAC_512_KEYLEN;
+		break;
+	  default:
+		printf("Bogus aead\n");
+		exit(1);
+	} 
+
+        ntp_RAND_bytes(c2s, NTS_MAX_KEYLEN);
+        ntp_RAND_bytes(s2c, NTS_MAX_KEYLEN);
+
+	clock_gettime(CLOCK_MONOTONIC, &start);
+	for (int i = 0; i < samplesize; i++) {
+		cookielength = nts_make_cookie(
+			cookie, aead, c2s, s2c, keylength);
+	}
+	clock_gettime(CLOCK_MONOTONIC, &stop);
+	fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+	printf("%12s  %2d %4d %6.0f %7.3f",
+	       name, keylength, cookielength, fast/samplesize,  fast/1E9);
+	printf("\n");
+}
+
+
+static void DoMakeCrypto(
+  const char *name,       /* name of aead */
+  int     aead,		  /* algorithm used to make cookie */
+  int     keylen          /* length of c2s and s2c */
+)
+{
+	uint8_t cookie[NTS_MAX_COOKIELEN];
+	uint8_t c2s[NTS_MAX_KEYLEN], s2c[NTS_MAX_KEYLEN];
+	struct timespec start, stop;
+	double fast;
+	int cookielength = 0;
+	int samplesize = SAMPLESIZE;
+
+        uint8_t plaintext[NTS_MAX_COOKIELEN];
+        uint8_t *nonce;
+        int used, plainlength;
+        int ok = 0;
+        uint8_t * finger;
+        uint32_t temp;  /* keep 4 byte alignment */
+        size_t left;
+
+	switch (aead) {
+	  case AEAD_AES_SIV_CMAC_256:
+		key_K_length = AEAD_AES_SIV_CMAC_256_KEYLEN;
+		break;
+	  case AEAD_AES_SIV_CMAC_384:
+		key_K_length = AEAD_AES_SIV_CMAC_384_KEYLEN;
+		break;
+	  case AEAD_AES_SIV_CMAC_512:
+		key_K_length = AEAD_AES_SIV_CMAC_512_KEYLEN;
+		break;
+	  default:
+		printf("Bogus aead\n");
+		exit(1);
+	} 
+
+        ntp_RAND_bytes(c2s, NTS_MAX_KEYLEN);
+        ntp_RAND_bytes(s2c, NTS_MAX_KEYLEN);
+
+        finger = plaintext;
+        temp = aead;
+        memcpy(finger, &temp, sizeof(temp));
+        finger += sizeof(temp);
+        memcpy(finger, c2s, keylen);
+        finger += keylen;
+        memcpy(finger, s2c, keylen);
+        finger += keylen;
+        plainlength = finger-plaintext;
+
+        /* collect associated data */
+        finger = cookie;
+
+        memcpy(finger, &key_I, sizeof(key_I));
+        finger += sizeof(key_I);
+
+        nonce = finger;
+        ntp_RAND_bytes(finger, NONCE_LENGTH);
+        finger += NONCE_LENGTH;
+
+        used = finger-cookie;
+        left = NTS_MAX_COOKIELEN-used;
+
+	clock_gettime(CLOCK_MONOTONIC, &start);
+	for (int i = 0; i < samplesize; i++) {
+          ok += AES_SIV_Encrypt(cookie_ctx,
+             finger, &left,   /* left: in: max out length, out: length used */
+             key_K, key_K_length,
+             nonce, NONCE_LENGTH,
+             plaintext, plainlength,
+             cookie, AD_LENGTH);
+	}
+	clock_gettime(CLOCK_MONOTONIC, &stop);
+
+        if (samplesize != ok) {
+                printf("NTS: nts_make_cookie - Error from AES_SIV_Encrypt\n");
+                exit(1);
+        }
+
+        used += left;
+        INSIST(used <= NTS_MAX_COOKIELEN);
+
+	cookielength = used;
+
+	fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+	printf("%12s  %2d %4d %6.0f %7.3f",
+	       name, keylen, cookielength, fast/samplesize,  fast/1E9);
+	printf("\n");
+}
+
+int main(int argc, char *argv[])
+{
+	char *ctimetxt;
+	time_t now;
+	char buff[256];
+
+	UNUSED_ARG(argc);
+	UNUSED_ARG(argv);
+
+	setlinebuf(stdout);
+
+	ssl_init();
+
+        ntp_RAND_bytes(key_K, NTS_MAX_KEYLEN);
+
+	now = time(NULL);
+	ctimetxt = ctime(&now);
+	ctimetxt[24] = 0;	/* Hack: smash return */
+	gethostname(buff, sizeof(buff));
+	printf("# %s on %s\n", ctimetxt, buff);
+	printf("# %s\n", OPENSSL_VERSION_TEXT);
+
+	printf("\n");
+	printf("#       bytes  ns/op sec/run\n");
+	DoLock();
+	DoNonce();
+
+	printf("\n");
+	printf("# wKL=sizeof(c2s), CL=sizeof(cookie)\n");
+	printf("# Make cookie    wKL   CL  ns/op sec/run\n");
+
+// Sample numbers using old cmac.h
+// run on a Dell 9020/MT with Intel i7-4790 @ 3.60GHz
+	/* 3rd arg is length of c2s and s2c */
+	DoMakeCookie("AES_SIV_CMAC_256", AEAD_AES_SIV_CMAC_256, 32);
+	DoMakeCookie("AES_SIV_CMAC_256", AEAD_AES_SIV_CMAC_256, 48);
+	DoMakeCookie("AES_SIV_CMAC_256", AEAD_AES_SIV_CMAC_256, 64);
+// AES_SIV_CMAC_256  32  104   3127   3.127
+// AES_SIV_CMAC_256  48  136   3186   3.186
+// AES_SIV_CMAC_256  64  168   3220   3.220
+	DoMakeCookie("AES_SIV_CMAC_512", AEAD_AES_SIV_CMAC_512, 32);
+	DoMakeCookie("AES_SIV_CMAC_512", AEAD_AES_SIV_CMAC_512, 48);
+	DoMakeCookie("AES_SIV_CMAC_512", AEAD_AES_SIV_CMAC_512, 64);
+// AES_SIV_CMAC_512  32  104   3183   3.183
+// AES_SIV_CMAC_512  48  136   3247   3.247
+// AES_SIV_CMAC_512  64  168   3303   3.303
+	printf("\n");
+
+	printf("# Cookie Crypto  wKL   CL  ns/op sec/run\n");
+	DoMakeCrypto("AES_SIV_CMAC_256", AEAD_AES_SIV_CMAC_256, 32);
+	DoMakeCrypto("AES_SIV_CMAC_256", AEAD_AES_SIV_CMAC_256, 48);
+	DoMakeCrypto("AES_SIV_CMAC_256", AEAD_AES_SIV_CMAC_256, 64);
+// AES_SIV_CMAC_256  32  104   2066   2.066
+// AES_SIV_CMAC_256  48  136   2119   2.119
+// AES_SIV_CMAC_256  64  168   2157   2.157
+
+	return 0;
+}


=====================================
attic/cmac-timing.c
=====================================
@@ -1,6 +1,8 @@
 /* Last modified on Sat Aug 28 14:30:11 PDT 1999 by murray */
 
 /* Hack to time various implementations of CMAC.
+ *
+ * Build with: cc cmac-timing.c -o cmac-timing -lcrypto
  *
  * This is just the CMAC timing.
  * It doesn't include the copy or compare or finding the right key.
@@ -12,14 +14,13 @@
  * Check /proc/cpuinfo flags for "aes" to see if you have it.
  */
 
-#define CMAC_VERSION_CUTOFF 0x10000003
-
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
+#include <unistd.h>
 
 /* Silence warnings from CMAC routines in OpenSSL 3.0.0 */
 #define OPENSSL_SUPPRESS_DEPRECATED 1
@@ -41,6 +42,7 @@
 int SAMPLESIZE = 1000000;
 
 #define PACKET_LENGTH 48
+#define MAX_PACKET_LENGTH 4096
 #define MAX_KEY_LENGTH 64
 
 CMAC_CTX *cmac;
@@ -48,6 +50,8 @@ CMAC_CTX *cmac;
 EVP_MAC_CTX *evp;
 #endif
 
+bool do_all = false;
+
 unsigned char answer[EVP_MAX_MD_SIZE];
 
 static void ssl_init(void)
@@ -133,27 +137,102 @@ static void DoCMAC(
 	struct timespec start, stop;
 	double fast;
 	unsigned long digestlength = 0;
+	int samplesize = SAMPLESIZE;
 
 	if (NULL == cipher) {
 		return;
 	}
+	if (pktlength > 1000) samplesize /= 10;
 
 	clock_gettime(CLOCK_MONOTONIC, &start);
-	for (int i = 0; i < SAMPLESIZE; i++) {
+	for (int i = 0; i < samplesize; i++) {
 		digestlength = One_CMAC(cipher, key, keylength, pkt, pktlength);
 		if (0 == digestlength)
 			break;
 	}
 	clock_gettime(CLOCK_MONOTONIC, &stop);
 	fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
-	printf("%12s  %2d %2d %2lu %6.0f  %6.3f",
-	       name, keylength, pktlength, digestlength, fast/SAMPLESIZE,  fast/1E9);
+	printf("%12s  %2d %4d %2lu %6.0f %7.3f",
+
+	       name, keylength, pktlength, digestlength, fast/samplesize,  fast/1E9);
 	PrintHex(answer, digestlength);
 	printf("\n");
 }
 
 #if OPENSSL_VERSION_NUMBER > 0x10101000L
 static size_t One_PKEY(
+  EVP_MD_CTX *ctx,        /* context  */
+  uint8_t *key,           /* key pointer */
+  int     keylength,      /* key length */
+  uint8_t *pkt,           /* packet pointer */
+  int     pktlength,      /* packet length */
+  const EVP_CIPHER *cipher
+) {
+	EVP_PKEY *pkey;
+	size_t len = EVP_MAX_MD_SIZE;
+	pkey = EVP_PKEY_new_CMAC_key(NULL, key, keylength, cipher);
+	if (NULL == pkey) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_PKEY_new_CMAC_key() failed\n    %s.\n", \
+			str);
+		return 0;
+	}
+	if (1 != EVP_DigestSignInit(ctx, NULL, NULL, NULL, pkey)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_DigestSignInit() failed:\n    %s.\n", str);
+		return 0;
+	}
+	EVP_DigestSign(ctx, answer, &len, pkt, pktlength);
+	EVP_PKEY_free(pkey);
+	return len;
+}
+
+
+static void DoPKEY(
+  const char *name,       /* name of cipher */
+  uint8_t *key,           /* key pointer */
+  int     keylength,      /* key length */
+  uint8_t *pkt,           /* packet pointer */
+  int     pktlength       /* packet length */
+)
+{
+	struct timespec start, stop;
+	double fast;
+	unsigned long digestlength = 0;
+	int samplesize = SAMPLESIZE;
+
+	const EVP_CIPHER *cipher = CheckCipher(name);
+	EVP_MD_CTX *ctx;
+
+	if (NULL == cipher) {
+		return;
+	}
+	if (pktlength > 1000) samplesize /= 10;
+
+	ctx = EVP_MD_CTX_new();
+	if (NULL == ctx) {
+		printf("## Oops, EVP_MD_CTX_new() failed.\n");
+		return;
+	}
+	EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_FINALISE);
+
+	clock_gettime(CLOCK_MONOTONIC, &start);
+	for (int i = 0; i < samplesize; i++) {
+		digestlength = One_PKEY(ctx, key, keylength, pkt, pktlength, cipher);
+	}
+
+	clock_gettime(CLOCK_MONOTONIC, &stop);
+	fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+	printf("%12s  %2d %4d %2lu %6.0f %7.3f",
+	       name, keylength, pktlength, digestlength, fast/samplesize,  fast/1E9);
+	PrintHex(answer, digestlength);
+	printf("\n");
+	EVP_MD_CTX_free(ctx);
+}
+
+static size_t One_PKEY2(
   EVP_PKEY *pkey,
   EVP_MD_CTX *ctx,          /* context  */
   uint8_t *pkt,             /* packet pointer */
@@ -171,7 +250,7 @@ static size_t One_PKEY(
 }
 
 
-static void DoPKEY(
+static void DoPKEY2(
   const char *name,       /* name of cipher */
   uint8_t *key,           /* key pointer */
   int     keylength,      /* key length */
@@ -182,6 +261,7 @@ static void DoPKEY(
 	struct timespec start, stop;
 	double fast;
 	unsigned long digestlength = 0;
+	int samplesize = SAMPLESIZE;
 
 	const EVP_CIPHER *cipher = CheckCipher(name);
 	EVP_PKEY *pkey;
@@ -190,6 +270,7 @@ static void DoPKEY(
 	if (NULL == cipher) {
 		return;
 	}
+	if (pktlength > 1000) samplesize /= 10;
 
 	pkey = EVP_PKEY_new_CMAC_key(NULL, key, keylength, cipher);
 	if (NULL == pkey) {
@@ -204,19 +285,17 @@ static void DoPKEY(
 		printf("## Oops, EVP_MD_CTX_new() failed.\n");
 		return;
 	}
-#ifdef EVP_MD_CTX_FLAG_FINALISE
 	EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_FINALISE);
-#endif
 
 	clock_gettime(CLOCK_MONOTONIC, &start);
-	for (int i = 0; i < SAMPLESIZE; i++) {
-		digestlength = One_PKEY(pkey, ctx, pkt, pktlength);
+	for (int i = 0; i < samplesize; i++) {
+		digestlength = One_PKEY2(pkey, ctx, pkt, pktlength);
 	}
 
 	clock_gettime(CLOCK_MONOTONIC, &stop);
 	fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
-	printf("%12s  %2d %2d %2lu %6.0f  %6.3f",
-	       name, keylength, pktlength, digestlength, fast/SAMPLESIZE,  fast/1E9);
+	printf("%12s  %2d %4d %2lu %6.0f %7.3f",
+	       name, keylength, pktlength, digestlength, fast/samplesize,  fast/1E9);
 	PrintHex(answer, digestlength);
 	printf("\n");
 	EVP_MD_CTX_free(ctx);
@@ -227,13 +306,24 @@ static void DoPKEY(
 #if OPENSSL_VERSION_NUMBER > 0x20000000L
 static size_t One_EVP_MAC(
   EVP_MAC_CTX *ctx,         /* context  */
+  char *name,               /* name of cipher (with -cbc) */
   uint8_t *key,             /* key pointer */
   int     keylength,        /* key length */
   uint8_t *pkt,             /* packet pointer */
   int     pktlength         /* packet length */
 ) {
+	OSSL_PARAM params[2];
 	size_t len = EVP_MAX_MD_SIZE;
 
+	params[0] =
+          OSSL_PARAM_construct_utf8_string("cipher", name, 0);
+	params[1] = OSSL_PARAM_construct_end();
+	if (0 == EVP_MAC_CTX_set_params(evp, params)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_CTX_set_params() failed: %s.\n", str);
+		return 0;
+	}
 	if (0 == EVP_MAC_init(ctx, key, keylength, NULL)) {
 		unsigned long err = ERR_get_error();
 		char * str = ERR_error_string(err, NULL);
@@ -269,55 +359,56 @@ static void Do_EVP_MAC(
 	double fast;
 	unsigned long digestlength = 0;
 	char cbc[100];
+	int samplesize = SAMPLESIZE;
 
 	if (NULL == cipher) {
 		return;
 	}
+	if (pktlength > 1000) samplesize /= 10;
 	snprintf(cbc, sizeof(cbc), "%s-CBC", name);
 
 
 	clock_gettime(CLOCK_MONOTONIC, &start);
-	for (int i = 0; i < SAMPLESIZE; i++) {
-		digestlength = One_EVP_MAC(evp, key, keylength, pkt, pktlength);
-if (0 == digestlength) break;
+	for (int i = 0; i < samplesize; i++) {
+		digestlength = One_EVP_MAC(evp, cbc, key, keylength, pkt, pktlength);
+		if (0 == digestlength) break;
 	}
 	clock_gettime(CLOCK_MONOTONIC, &stop);
 	fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
-	printf("%12s  %2d %2d %2lu %6.0f  %6.3f",
-	       name, keylength, pktlength, digestlength, fast/SAMPLESIZE,  fast/1E9);
+	printf("%12s  %2d %4d %2lu %6.0f %7.3f",
+	       name, keylength, pktlength, digestlength, fast/samplesize,  fast/1E9);
 	PrintHex(answer, digestlength);
 	printf("\n");
 }
+
+
 static size_t One_EVP_MAC2(
   EVP_MAC_CTX *ctx,         /* context  */
+  uint8_t *key,             /* key pointer */
+  int     keylength,        /* key length */
   uint8_t *pkt,             /* packet pointer */
   int     pktlength         /* packet length */
 ) {
-	EVP_MAC_CTX *dup;
 	size_t len = EVP_MAX_MD_SIZE;
 
-	// dup = ctx;
-	dup = EVP_MAC_CTX_dup(ctx);
-
-	if (0 == EVP_MAC_init(dup, NULL, 0, NULL)) {
+	if (0 == EVP_MAC_init(ctx, key, keylength, NULL)) {
 		unsigned long err = ERR_get_error();
 		char * str = ERR_error_string(err, NULL);
 		printf("## Oops, EVP_MAC_init() failed: %s.\n", str);
 		return 0;
 	}
-	if (0 == EVP_MAC_update(dup, pkt, pktlength)) {
+	if (0 == EVP_MAC_update(ctx, pkt, pktlength)) {
 		unsigned long err = ERR_get_error();
 		char * str = ERR_error_string(err, NULL);
 		printf("## Oops, EVP_MAC_update() failed: %s.\n", str);
 		return 0;
 	}
-	if (0 == EVP_MAC_final(dup, answer, &len, sizeof(answer))) {
+	if (0 == EVP_MAC_final(ctx, answer, &len, sizeof(answer))) {
 		unsigned long err = ERR_get_error();
 		char * str = ERR_error_string(err, NULL);
 		printf("## Oops, EVP_MAC_final() failed: %s.\n", str);
 		return 0;
 	}
-	EVP_MAC_CTX_free(dup);
 	return len;
 }
 
@@ -334,12 +425,89 @@ static void Do_EVP_MAC2(
 	double fast;
 	unsigned long digestlength = 0;
 	char cbc[100];
+	int samplesize = SAMPLESIZE;
+	const EVP_CIPHER *cipher = CheckCipher(name);
+	OSSL_PARAM params[3];
+
+	if (NULL == cipher) {
+		return;
+	}
+	if (pktlength > 1000) samplesize /= 10;
+	snprintf(cbc, sizeof(cbc), "%s-CBC", name);
+
+	params[0] =
+          OSSL_PARAM_construct_utf8_string("cipher", cbc, 0);
+	params[1] = OSSL_PARAM_construct_end();
+	if (0 == EVP_MAC_CTX_set_params(evp, params)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_CTX_set_params() failed: %s.\n", str);
+		return;
+	}
+
+	clock_gettime(CLOCK_MONOTONIC, &start);
+	for (int i = 0; i < samplesize; i++) {
+		digestlength = One_EVP_MAC2(evp, key, keylength, pkt, pktlength);
+if (0 == digestlength) break;
+	}
+	clock_gettime(CLOCK_MONOTONIC, &stop);
+	fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+	printf("%12s  %2d %4d %2lu %6.0f %7.3f",
+	       name, keylength, pktlength, digestlength, fast/samplesize,  fast/1E9);
+	PrintHex(answer, digestlength);
+	printf("\n");
+}
+
+
+static size_t One_EVP_MAC3(
+  EVP_MAC_CTX *ctx,         /* context  */
+  uint8_t *pkt,             /* packet pointer */
+  int     pktlength         /* packet length */
+) {
+	size_t len = EVP_MAX_MD_SIZE;
+
+	if (0 == EVP_MAC_init(ctx, NULL, 0, NULL)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_init() failed: %s.\n", str);
+		return 0;
+	}
+	if (0 == EVP_MAC_update(ctx, pkt, pktlength)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_update() failed: %s.\n", str);
+		return 0;
+	}
+	if (0 == EVP_MAC_final(ctx, answer, &len, sizeof(answer))) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		printf("## Oops, EVP_MAC_final() failed: %s.\n", str);
+		return 0;
+	}
+	return len;
+}
+
+
+static void Do_EVP_MAC3(
+  const char *name,       /* name of cipher */
+  uint8_t *key,           /* key pointer */
+  int     keylength,      /* key length */
+  uint8_t *pkt,           /* packet pointer */
+  int     pktlength       /* packet length */
+)
+{
+	struct timespec start, stop;
+	double fast;
+	unsigned long digestlength = 0;
+	char cbc[100];
+	int samplesize = SAMPLESIZE;
 	const EVP_CIPHER *cipher = CheckCipher(name);
 	OSSL_PARAM params[3];
 
 	if (NULL == cipher) {
 		return;
 	}
+	if (pktlength > 1000) samplesize /= 10;
 	snprintf(cbc, sizeof(cbc), "%s-CBC", name);
 
 	params[0] =
@@ -354,16 +522,15 @@ static void Do_EVP_MAC2(
 		return;
 	}
 
-
 	clock_gettime(CLOCK_MONOTONIC, &start);
-	for (int i = 0; i < SAMPLESIZE; i++) {
-		digestlength = One_EVP_MAC2(evp, pkt, pktlength);
+	for (int i = 0; i < samplesize; i++) {
+		digestlength = One_EVP_MAC3(evp, pkt, pktlength);
 if (0 == digestlength) break;
 	}
 	clock_gettime(CLOCK_MONOTONIC, &stop);
 	fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
-	printf("%12s  %2d %2d %2lu %6.0f  %6.3f",
-	       name, keylength, pktlength, digestlength, fast/SAMPLESIZE,  fast/1E9);
+	printf("%12s  %2d %4d %2lu %6.0f %7.3f",
+	       name, keylength, pktlength, digestlength, fast/samplesize,  fast/1E9);
 	PrintHex(answer, digestlength);
 	printf("\n");
 }
@@ -372,7 +539,10 @@ if (0 == digestlength) break;
 int main(int argc, char *argv[])
 {
 	uint8_t key[MAX_KEY_LENGTH];
-	uint8_t packet[PACKET_LENGTH];
+	uint8_t packet[MAX_PACKET_LENGTH];
+	char buff[256];
+	char *ctimetxt;
+	time_t now;
 
 	UNUSED_ARG(argc);
 	UNUSED_ARG(argv);
@@ -381,16 +551,29 @@ int main(int argc, char *argv[])
 
 	ssl_init();
 	RAND_bytes((unsigned char *)&key, MAX_KEY_LENGTH);
-	RAND_bytes((unsigned char *)&packet, PACKET_LENGTH);
+	RAND_bytes((unsigned char *)&packet, MAX_PACKET_LENGTH);
+	/* make things deterministic */
 	for (int i=0; i< MAX_KEY_LENGTH; i++) key[i]=i*i+0x23;
-	for (int i=0; i< PACKET_LENGTH; i++) packet[i]=i*i+0x31;
+	for (int i=0; i< MAX_PACKET_LENGTH; i++) packet[i]=i*i+0x31;
 
+	now = time(NULL);
+	ctimetxt = ctime(&now);
+	ctimetxt[24] = 0;	/* Hack: smash return */
+	gethostname(buff, sizeof(buff));
+	printf("# %s on %s\n", ctimetxt, buff);
 	printf("# %s\n", OPENSSL_VERSION_TEXT);
 
 	printf("\n");
 	printf("# KL=key length, PL=packet length, CL=CMAC length\n");
-	printf("# CMAC        KL PL CL  ns/op sec/run\n");
+	printf("# CMAC        KL   PL CL  ns/op sec/run\n");
+
+	DoCMAC("AES-128",      key, 16, packet, PACKET_LENGTH);
+	DoCMAC("AES-128",      key, 16, packet, PACKET_LENGTH*2);
+	DoCMAC("AES-128",      key, 16, packet, MAX_PACKET_LENGTH);
+	DoCMAC("AES-192",      key, 24, packet, PACKET_LENGTH);
+	DoCMAC("AES-256",      key, 32, packet, PACKET_LENGTH);
 
+if (do_all) {
 #if OPENSSL_VERSION_NUMBER < 0x20000000L
 /* Hangs on 3.0.0  Checking OPENSSL_NO_DES doesn't work. */
 	DoCMAC("DES",          key,  8, packet, PACKET_LENGTH);
@@ -400,21 +583,26 @@ int main(int argc, char *argv[])
 #ifndef OPENSSL_NO_SM4
 	DoCMAC("SM4",          key, 16, packet, PACKET_LENGTH);
 #endif
-	DoCMAC("AES-128",      key, 16, packet, PACKET_LENGTH);
-	DoCMAC("AES-192",      key, 24, packet, PACKET_LENGTH);
-	DoCMAC("AES-256",      key, 32, packet, PACKET_LENGTH);
 	DoCMAC("CAMELLIA-128", key, 16, packet, PACKET_LENGTH);
 	DoCMAC("CAMELLIA-192", key, 24, packet, PACKET_LENGTH);
 	DoCMAC("CAMELLIA-256", key, 32, packet, PACKET_LENGTH);
 	DoCMAC("ARIA-128",     key, 16, packet, PACKET_LENGTH);
 	DoCMAC("ARIA-192",     key, 24, packet, PACKET_LENGTH);
 	DoCMAC("ARIA-256",     key, 32, packet, PACKET_LENGTH);
+}
 
 #if OPENSSL_VERSION_NUMBER > 0x10101000L
 	printf("\n");
 	printf("# KL=key length, PL=packet length, CL=CMAC length\n");
-	printf("# PKEY        KL PL CL  ns/op sec/run\n");
+	printf("# PKEY        KL   PL CL  ns/op sec/run\n");
 
+	DoPKEY("AES-128",      key, 16, packet, PACKET_LENGTH);
+	DoPKEY("AES-128",      key, 16, packet, PACKET_LENGTH*2);
+	DoPKEY("AES-128",      key, 16, packet, MAX_PACKET_LENGTH);
+	DoPKEY("AES-192",      key, 24, packet, PACKET_LENGTH);
+	DoPKEY("AES-256",      key, 32, packet, PACKET_LENGTH);
+
+if (do_all) {
 #if OPENSSL_VERSION_NUMBER < 0x20000000L
 	DoPKEY("DES",          key,  8, packet, PACKET_LENGTH);
 #endif
@@ -423,54 +611,109 @@ int main(int argc, char *argv[])
 #ifndef OPENSSL_NO_SM4
 	DoPKEY("SM4",          key, 16, packet, PACKET_LENGTH);
 #endif
-	DoPKEY("AES-128",      key, 16, packet, PACKET_LENGTH);
-	DoPKEY("AES-192",      key, 24, packet, PACKET_LENGTH);
-	DoPKEY("AES-256",      key, 32, packet, PACKET_LENGTH);
 	DoPKEY("CAMELLIA-128", key, 16, packet, PACKET_LENGTH);
 	DoPKEY("CAMELLIA-192", key, 24, packet, PACKET_LENGTH);
 	DoPKEY("CAMELLIA-256", key, 32, packet, PACKET_LENGTH);
 	DoPKEY("ARIA-128",     key, 16, packet, PACKET_LENGTH);
 	DoPKEY("ARIA-192",     key, 24, packet, PACKET_LENGTH);
 	DoPKEY("ARIA-256",     key, 32, packet, PACKET_LENGTH);
+}
+	printf("\n");
+	printf("# KL=key length, PL=packet length, CL=CMAC length\n");
+	printf("# PKEY preload KL  PL CL  ns/op sec/run\n");
+
+	DoPKEY2("AES-128",      key, 16, packet, PACKET_LENGTH);
+	DoPKEY2("AES-128",      key, 16, packet, PACKET_LENGTH*2);
+	DoPKEY2("AES-128",      key, 16, packet, MAX_PACKET_LENGTH);
+	DoPKEY2("AES-192",      key, 24, packet, PACKET_LENGTH);
+	DoPKEY2("AES-256",      key, 32, packet, PACKET_LENGTH);
+
+if (do_all) {
+#if OPENSSL_VERSION_NUMBER < 0x20000000L
+	DoPKEY2("DES",          key,  8, packet, PACKET_LENGTH);
+#endif
+	DoPKEY2("DES-EDE",      key, 16, packet, PACKET_LENGTH);
+	DoPKEY2("DES-EDE3",     key, 24, packet, PACKET_LENGTH);
+#ifndef OPENSSL_NO_SM4
+	DoPKEY2("SM4",          key, 16, packet, PACKET_LENGTH);
+#endif
+	DoPKEY2("CAMELLIA-128", key, 16, packet, PACKET_LENGTH);
+	DoPKEY2("CAMELLIA-192", key, 24, packet, PACKET_LENGTH);
+	DoPKEY2("CAMELLIA-256", key, 32, packet, PACKET_LENGTH);
+	DoPKEY2("ARIA-128",     key, 16, packet, PACKET_LENGTH);
+	DoPKEY2("ARIA-192",     key, 24, packet, PACKET_LENGTH);
+	DoPKEY2("ARIA-256",     key, 32, packet, PACKET_LENGTH);
+}
 #endif
 
 #if OPENSSL_VERSION_NUMBER > 0x20000000L
 	printf("\n");
 	printf("# KL=key length, PL=packet length, CL=CMAC length\n");
-	printf("# EVP_MAC     KL PL CL  ns/op sec/run\n");
+	printf("# EVP_MAC     KL   PL CL  ns/op sec/run\n");
+
+	Do_EVP_MAC("AES-128",      key, 16, packet, PACKET_LENGTH);
+	Do_EVP_MAC("AES-128",      key, 16, packet, PACKET_LENGTH*2);
+	Do_EVP_MAC("AES-128",      key, 16, packet, MAX_PACKET_LENGTH);
+	Do_EVP_MAC("AES-192",      key, 24, packet, PACKET_LENGTH);
+	Do_EVP_MAC("AES-256",      key, 32, packet, PACKET_LENGTH);
 
+if (do_all) {
 	Do_EVP_MAC("DES-EDE",      key, 16, packet, PACKET_LENGTH);
 	Do_EVP_MAC("DES-EDE3",     key, 24, packet, PACKET_LENGTH);
 #ifndef OPENSSL_NO_SM4
 	Do_EVP_MAC("SM4",          key, 16, packet, PACKET_LENGTH);
 #endif
-	Do_EVP_MAC("AES-128",      key, 16, packet, PACKET_LENGTH);
-	Do_EVP_MAC("AES-192",      key, 24, packet, PACKET_LENGTH);
-	Do_EVP_MAC("AES-256",      key, 32, packet, PACKET_LENGTH);
 	Do_EVP_MAC("CAMELLIA-128", key, 16, packet, PACKET_LENGTH);
 	Do_EVP_MAC("CAMELLIA-192", key, 24, packet, PACKET_LENGTH);
 	Do_EVP_MAC("CAMELLIA-256", key, 32, packet, PACKET_LENGTH);
 	Do_EVP_MAC("ARIA-128",     key, 16, packet, PACKET_LENGTH);
 	Do_EVP_MAC("ARIA-192",     key, 24, packet, PACKET_LENGTH);
 	Do_EVP_MAC("ARIA-256",     key, 32, packet, PACKET_LENGTH);
+}
 
 	printf("\n");
-	printf("Preload cipher and key.\n");
+	printf("EVP_MAC Preload cipher.\n");
+	Do_EVP_MAC2("AES-128",      key, 16, packet, PACKET_LENGTH);
+	Do_EVP_MAC2("AES-128",      key, 16, packet, PACKET_LENGTH*2);
+	Do_EVP_MAC2("AES-128",      key, 16, packet, MAX_PACKET_LENGTH);
+	Do_EVP_MAC2("AES-192",      key, 24, packet, PACKET_LENGTH);
+	Do_EVP_MAC2("AES-256",      key, 32, packet, PACKET_LENGTH);
+
+if (do_all) {
 	Do_EVP_MAC2("DES-EDE",      key, 16, packet, PACKET_LENGTH);
 	Do_EVP_MAC2("DES-EDE3",     key, 24, packet, PACKET_LENGTH);
 #ifndef OPENSSL_NO_SM4
 	Do_EVP_MAC2("SM4",          key, 16, packet, PACKET_LENGTH);
 #endif
-	Do_EVP_MAC2("AES-128",      key, 16, packet, PACKET_LENGTH);
-	Do_EVP_MAC2("AES-192",      key, 24, packet, PACKET_LENGTH);
-	Do_EVP_MAC2("AES-256",      key, 32, packet, PACKET_LENGTH);
 	Do_EVP_MAC2("CAMELLIA-128", key, 16, packet, PACKET_LENGTH);
 	Do_EVP_MAC2("CAMELLIA-192", key, 24, packet, PACKET_LENGTH);
 	Do_EVP_MAC2("CAMELLIA-256", key, 32, packet, PACKET_LENGTH);
 	Do_EVP_MAC2("ARIA-128",     key, 16, packet, PACKET_LENGTH);
 	Do_EVP_MAC2("ARIA-192",     key, 24, packet, PACKET_LENGTH);
 	Do_EVP_MAC2("ARIA-256",     key, 32, packet, PACKET_LENGTH);
+}
+	printf("\n");
+	printf("EVP_MAC Preload cipher and key.\n");
+	Do_EVP_MAC3("AES-128",      key, 16, packet, PACKET_LENGTH);
+	Do_EVP_MAC3("AES-128",      key, 16, packet, PACKET_LENGTH*2);
+	Do_EVP_MAC3("AES-128",      key, 16, packet, MAX_PACKET_LENGTH);
+	Do_EVP_MAC3("AES-192",      key, 24, packet, PACKET_LENGTH);
+	Do_EVP_MAC3("AES-256",      key, 32, packet, PACKET_LENGTH);
+
+if (do_all) {
+	Do_EVP_MAC3("DES-EDE",      key, 16, packet, PACKET_LENGTH);
+	Do_EVP_MAC3("DES-EDE3",     key, 24, packet, PACKET_LENGTH);
+#ifndef OPENSSL_NO_SM4
+	Do_EVP_MAC3("SM4",          key, 16, packet, PACKET_LENGTH);
 #endif
+	Do_EVP_MAC3("CAMELLIA-128", key, 16, packet, PACKET_LENGTH);
+	Do_EVP_MAC3("CAMELLIA-192", key, 24, packet, PACKET_LENGTH);
+	Do_EVP_MAC3("CAMELLIA-256", key, 32, packet, PACKET_LENGTH);
+	Do_EVP_MAC3("ARIA-128",     key, 16, packet, PACKET_LENGTH);
+	Do_EVP_MAC3("ARIA-192",     key, 24, packet, PACKET_LENGTH);
+	Do_EVP_MAC3("ARIA-256",     key, 32, packet, PACKET_LENGTH);
+}
+#endif /* OPENSSL_VERSION_NUMBER > 0x20000000L */
 
 	return 0;
 }


=====================================
attic/random.c
=====================================
@@ -156,7 +156,7 @@ static int do_fastest(void) {
 
 	for (int i = 0; i < BATCHSIZE; i++) {
                 clock_gettime(CLOCK_REALTIME, &start);
-		/* coverity[dc,weak_crypto] */
+		/* coverity[DC.WEAK_CRYPTO] */
 		sum += random();
 		clock_gettime(CLOCK_REALTIME, &stop);
 		sec = (stop.tv_sec-start.tv_sec);


=====================================
attic/sht.c
=====================================
@@ -163,7 +163,7 @@ again:
 		else
 		{
 			time(&rcv_sec);
-			/* coverity[dc.weak_crypto] */
+			/* coverity[DC.WEAK_CRYPTO] */
 			rcv_frc = (unsigned int)random() % 1000000000U;
 		}
 		/* add a wobble of ~3.5msec to the clock time */


=====================================
attic/wscript
=====================================
@@ -1,15 +1,19 @@
 def build(ctx):
-    util = [	'sht',
-		'digest-find', 'clocks', "random",
-		'digest-timing', 'cmac-timing',
-		'backwards']
+    util = [    'sht',
+                'digest-find', 'clocks', "random",
+                'digest-timing', 'cmac-timing',
+                'backwards']
+
+    if not ctx.env.DISABLE_NTS:
+        util.append('aes-siv-timing')
 
     for name in util:
         ctx(
             target=name,
             features="c cprogram",
-            includes=[ctx.bldnode.parent.abspath(), "../include"],
+            includes=[ctx.bldnode.parent.abspath(), "../include", "../libaes_siv"],
             source=[name + ".c"],
-            use="ntp M CRYPTO RT PTHREAD",
+            use="ntp M CRYPTO RT PTHREAD aes_siv",
             install_path=None,
         )
+


=====================================
devel/ifdex-ignores
=====================================
@@ -160,7 +160,6 @@ HAVE_STRUCT_TIMEX_MODES
 HAVE_STRUCT_TIMEX_TIME_TICK
 HAVE_STRUCT_NTPTIMEVAL_TAI
 HAVE_STRUCT_NTPTIMEVAL_TIME_TV_NSEC
-CMAC_VERSION_CUTOFF	# Cruft from the attic
 DoSLOW			# Cruft from the attic
 
 # seccomp-related symbols that may not be available on all systems


=====================================
include/ntp_auth.h
=====================================
@@ -5,7 +5,6 @@
 #include "ntp_lists.h"
 
 #include <openssl/evp.h>
-#include <openssl/cmac.h>
 
 typedef enum {AUTH_NONE, AUTH_CMAC, AUTH_DIGEST} AUTH_Type;
 
@@ -23,7 +22,11 @@ struct auth_data {
 	uint8_t *	key;			/* shared secret */
 	unsigned short	key_size;		/* secret length */
 	const EVP_MD *	digest;			/* Digest mode only */
-	const EVP_CIPHER *cipher;		/* CMAC mode only */
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+	EVP_MAC_CTX *mac_ctx;			/* EVP CMAC mode only */
+#else
+	const EVP_CIPHER *cipher;		/* Old CMAC mode only */
+#endif
 };
 
 extern  void    auth_init       (void);
@@ -63,6 +66,12 @@ extern	unsigned long authcmacfail;	/* fails from cmac_decrypt*/
 extern	uptime_t auth_timereset;	/* current_time when stats reset */
 
 
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+extern EVP_MAC_CTX *evp_ctx;   /* used by authreadkeys and authkeys */
+/* For testing */
+extern EVP_MAC_CTX* Setup_MAC_CTX(const char *name, uint8_t *key, int keylen);
+#endif
+
 /* Not in CMAC API */
 #define CMAC_MAX_MAC_LENGTH 64
 


=====================================
libntp/authkeys.c
=====================================
@@ -14,6 +14,8 @@
 #include "ntp_stdlib.h"
 #include "ntp_auth.h"
 
+#include <openssl/err.h>
+
 
 /* define the payload region of auth_data beyond the list pointers */
 #define auth_info_payload	keyid
@@ -303,15 +305,27 @@ alloc_auth_info(
 	switch (type) {
 	  case AUTH_NONE:
 		auth->digest = NULL;
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+		auth->mac_ctx = NULL;
+#else
 		auth->cipher = NULL;
+#endif
 		break;
 	  case AUTH_DIGEST:
 		auth->digest = EVP_get_digestbyname(name);
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+		auth->mac_ctx = NULL;
+#else
 		auth->cipher = NULL;
+#endif
 		break;
 	  case AUTH_CMAC:
 		auth->digest = NULL;
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+		auth->mac_ctx = Setup_MAC_CTX(name, auth->key, auth->key_size);
+#else
 		auth->cipher = EVP_get_cipherbyname(name);
+#endif
 		break;
 	  default:
 		msyslog(LOG_ERR, "BUG: alloc_auth_info: bogus type %u", type);
@@ -340,6 +354,9 @@ free_auth_info(
 		free(auth->key);
                 auth->key = NULL;
 	}
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+	EVP_MAC_CTX_free(auth->mac_ctx);
+#endif
 	UNLINK_SLIST(unlinked, *bucket, auth, hlink, auth_info);
 	//ENSURE(sk == unlinked);
 	UNLINK_DLIST(auth, llink);
@@ -454,15 +471,29 @@ auth_setkey(
 			switch (type) {
 			  case AUTH_NONE:
 				auth->digest = NULL;
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+				auth->mac_ctx = NULL;
+#else
 				auth->cipher = NULL;
+#endif
 				break;
 			  case AUTH_DIGEST:
 				auth->digest = EVP_get_digestbyname(name);
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+				auth->mac_ctx = NULL;
+#else
 				auth->cipher = NULL;
+#endif
 				break;
 			  case AUTH_CMAC:
 				auth->digest = NULL;
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+				EVP_MAC_CTX_free(auth->mac_ctx);
+				auth->mac_ctx = Setup_MAC_CTX(name, \
+					auth->key, auth->key_size);
+#else
 				auth->cipher = EVP_get_cipherbyname(name);
+#endif
 				break;
 			  default:
 				msyslog(LOG_ERR, "BUG: auth_setkey: bogus type %u", type);
@@ -521,7 +552,11 @@ auth_delkeys(void)
 			auth->key_size = 0;
 			auth->type = AUTH_NONE;
 			auth->digest = NULL;
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+			auth->mac_ctx = NULL;
+#else
 			auth->cipher = NULL;
+#endif
 		} else {
 			free_auth_info(auth, &key_hash[KEYHASH(auth->keyid)]);
 		}
@@ -602,3 +637,33 @@ authdecrypt(
 	}
 	return false;
 }
+
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+/* Name needs "-CBC" already appended */
+EVP_MAC_CTX* Setup_MAC_CTX(const char *name, uint8_t *key, int keylen) {
+	OSSL_PARAM params[3];
+	char temp[100];		/* Hack: OSSL_PARAM doesn't like const */
+
+	EVP_MAC_CTX *ctx = EVP_MAC_CTX_dup(evp_ctx);
+	if (NULL == ctx) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		msyslog(LOG_ERR, "Setup_MAC_CTX: EVP_MAC_CTX_dup failed: %s", str);
+		exit(1);
+	}
+
+	strlcpy(temp, name, sizeof(temp));
+        params[0] = OSSL_PARAM_construct_utf8_string("cipher", temp, 0);
+        params[1] = OSSL_PARAM_construct_octet_string("key", key, keylen);
+	params[2] = OSSL_PARAM_construct_end();
+        if (0 == EVP_MAC_CTX_set_params(ctx, params)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		msyslog(LOG_ERR, "EVP_MAC_CTX_set_params() failed: %s: %s.",
+			str, name);
+		exit(1);
+	}
+	return ctx;
+}
+#endif
+


=====================================
libntp/authreadkeys.c
=====================================
@@ -1,7 +1,13 @@
 /*
  * authreadkeys.c - routines to support the reading of the key file
+ * See comment at top of macencrypt.c
  */
-#define OPENSSL_SUPPRESS_DEPRECATED 1
+
+
+/* FIXME: use Fetch
+ * shift to one ctx per crypto type rather than one per key
+ */
+// #warning "FIXME: fetch. preload"
 
 #include "config.h"
 #include <stdio.h>
@@ -15,8 +21,11 @@
 
 #include <openssl/objects.h>
 #include <openssl/evp.h>
+#include <openssl/err.h>
 
+#if OPENSSL_VERSION_NUMBER < 0x20000000L
 #include <openssl/cmac.h>
+#endif
 
 #define NAMEBUFSIZE 100
 
@@ -82,6 +91,7 @@ try_cmac(const char *upcased, char* namebuf) {
 	if (EVP_get_cipherbyname(namebuf) == NULL) {
 		return NULL;
 	}
+	/* FIXME: 3.0 needs a Fetch to be sure it really exists. */
 	return namebuf;
 }
 
@@ -105,22 +115,59 @@ static void
 check_digest_mac_length(
 	keyid_t keyno,
 	char *name) {
-	unsigned char digest[EVP_MAX_MD_SIZE];
 	unsigned int length = 0;
-	EVP_MD_CTX *ctx;
-	const EVP_MD *md;
 
-	md = EVP_get_digestbyname(name);
-	ctx = EVP_MD_CTX_create();
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+	const EVP_MD *md = EVP_get_digestbyname(name);
+	length = EVP_MD_get_size(md);
+#else
+	const EVP_MD *md = EVP_get_digestbyname(name);
+	EVP_MD_CTX *ctx = EVP_MD_CTX_create();
+	unsigned char digest[EVP_MAX_MD_SIZE];
 	EVP_DigestInit_ex(ctx, md, NULL);
 	EVP_DigestFinal_ex(ctx, digest, &length);
 	EVP_MD_CTX_destroy(ctx);
-
+#endif
 	if (MAX_BARE_MAC_LENGTH < length) {
 		msyslog(LOG_ERR, "AUTH: authreadkeys: digest for key %u, %s will be truncated.", keyno, name);
 	}
 }
 
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+static void
+check_cmac_mac_length(
+	keyid_t keyno,
+	char *name) {
+	size_t length = 0;
+	EVP_MAC_CTX *ctx = evp_ctx; 
+	OSSL_PARAM params[2];
+
+	params[0] = OSSL_PARAM_construct_utf8_string("cipher", name, 0);
+	params[1] = OSSL_PARAM_construct_end();
+	if (0 == EVP_MAC_CTX_set_params(ctx, params)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		msyslog(LOG_ERR, "EVP_MAC_CTX_set_params() failed: %s: %lu=>%s.\n",
+			str, (unsigned long)keyno, name);
+		exit(1);
+        }
+	length = EVP_MAC_CTX_get_mac_size(ctx);
+
+	/* CMAC_MAX_MAC_LENGTH isn't in the OpenSSL API
+	 * Check here to avoid buffer overrun in cmac_decrypt and cmac_encrypt
+	 */
+	if (CMAC_MAX_MAC_LENGTH < length) {
+		msyslog(LOG_ERR,
+			"AUTH: authreadkeys: CMAC for key %u, %s is too big: %lu",
+			keyno, name, (long unsigned int)length);
+		exit(1);
+	}
+
+	if (MAX_BARE_MAC_LENGTH < length) {
+		msyslog(LOG_ERR, "AUTH: authreadkeys: CMAC for key %u, %s will be truncated.", keyno, name);
+	}
+}
+#else
 static void
 check_cmac_mac_length(
 	keyid_t keyno,
@@ -157,6 +204,7 @@ check_cmac_mac_length(
 		msyslog(LOG_ERR, "AUTH: authreadkeys: CMAC for key %u, %s will be truncated.", keyno, name);
 	}
 }
+#endif
 
 /* check_mac_length - Check for CMAC/digest too long.
  * maybe should check for too short.
@@ -165,7 +213,7 @@ static void
 check_mac_length(
 	keyid_t keyno,
 	AUTH_Type type,
-	char * name,
+	char *name,
 	char *upcased) {
 	switch (type) {
 	    case AUTH_CMAC:


=====================================
libntp/macencrypt.c
=====================================
@@ -1,7 +1,46 @@
 /*
  *	CMAC and digest support for NTP
  */
-#define OPENSSL_SUPPRESS_DEPRECATED 1
+
+/*  Notes:
+ *
+ * This module covers the simple shared-key authentication.
+ * This is the working code that has to go fast.
+ * The setup code in authreadkeys is not time critical.
+ *
+ * There are 3 main options: MD5, SHA1, and AES.
+ * MD5 and SHA1 are digests.
+ *   https://en.wikipedia.org/wiki/Message_digest
+ * AES is a MAC.
+ *   https://en.wikipedia.org/wiki/Message_authentication_code
+ * OpenSSL has different APIs for them.
+ *
+ * Before OpenSSL 3, we (and many others) used the undocumented
+ * CMAC interface via openssl/cmac.h which is now (loudly) deprecated.
+ *
+ * The per packet operations all have this form:
+ *   EVP_MAC_init()
+ *   EVP_MAC_update()
+ *   EVP_MAC_final()
+ *
+ * The init step involves setting things up for the desired algorithm
+ * and key.  This can be an expensive step.  Some or much of the work
+ * can be pushed back to the one-time setup routines at the cost of
+ * more memory.  I call that preloading.
+ *
+ * This code now expects both the cipher and key to be preloaded.
+ * Just preloading the cipher will save a lot of memory if you
+ * are using a lot of keys.  The edit in this code is simple.
+ *
+ * Play with attic/cmac-timing for numbers.
+ *
+ *
+ * Modern CPUs come with support to speed up AES operations.
+ * On Intel, it's the aes capabilitiy.  You can see them
+ * under flags in /proc/cpuinfo
+ *
+ * Maybe more info in attic/cmac-timing and friends.
+ */
 
 #include "config.h"
 
@@ -10,6 +49,7 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include <openssl/err.h>
 #include <openssl/evp.h>	/* provides OpenSSL digest API */
 #include <openssl/md5.h>
 
@@ -18,15 +58,16 @@
 #include "ntp_auth.h"
 #include "ntp.h"
 
-#ifndef EVP_MD_CTX_reset
-/* Slightly older version of OpenSSL */
-/* Similar hack in ssl_init.c and attic/digest-timing.c */
-#define EVP_MD_CTX_reset(ctx) EVP_MD_CTX_init(ctx)
-#endif
-
 /* Need one per thread. */
 extern EVP_MD_CTX *digest_ctx;
+
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+#include <openssl/params.h>
+#else
+#include <openssl/cmac.h>
 extern CMAC_CTX *cmac_ctx;
+#endif
+
 
 /*
  * cmac_encrypt - generate CMAC authenticator
@@ -42,17 +83,39 @@ cmac_encrypt(
 {
 	uint8_t	mac[CMAC_MAX_MAC_LENGTH];
 	size_t	len;
-	CMAC_CTX *ctx = cmac_ctx;
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+        EVP_MAC_CTX *ctx = auth->mac_ctx;
 
+        if (0 == EVP_MAC_init(ctx, NULL, 0, NULL)) {
+                unsigned long err = ERR_get_error();
+                char * str = ERR_error_string(err, NULL);
+                msyslog(LOG_ERR, "encrypt: EVP_MAC_init() failed: %s.", str);
+                exit(1);
+        }
+        if (0 == EVP_MAC_update(ctx, (unsigned char *)pkt, length)) {
+                unsigned long err = ERR_get_error();
+                char * str = ERR_error_string(err, NULL);
+                msyslog(LOG_ERR, "encrypt: EVP_MAC_update() failed: %s.", str);
+                exit(1);
+        }
+        if (0 == EVP_MAC_final(ctx, mac, &len, sizeof(mac))) {
+                unsigned long err = ERR_get_error();
+                char * str = ERR_error_string(err, NULL);
+                msyslog(LOG_ERR, "encrypt: EVP_MAC_final() failed: %s.", str);
+                exit(1);
+        }
+#else
+	CMAC_CTX *ctx = cmac_ctx;
 	if (!CMAC_Init(ctx, auth->key, auth->key_size, auth->cipher, NULL)) {
 		/* Shouldn't happen.  Does if wrong key_size. */
 		msyslog(LOG_ERR,
-		    "MAC: encrypt: CMAC init failed, %u, %u",
+		    "encrypt: CMAC init failed, %u, %u",
 			auth->keyid, auth->key_size);
 		return (0);
 	}
 	CMAC_Update(ctx, (uint8_t *)pkt, (unsigned int)length);
 	CMAC_Final(ctx, mac, &len);
+#endif
 	if (MAX_BARE_MAC_LENGTH < len)
 		len = MAX_BARE_MAC_LENGTH;
 	memmove((uint8_t *)pkt + length + 4, mac, len);
@@ -75,19 +138,42 @@ cmac_decrypt(
 {
 	uint8_t	mac[CMAC_MAX_MAC_LENGTH];
 	size_t	len;
-	CMAC_CTX *ctx = cmac_ctx;
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+        EVP_MAC_CTX *ctx = auth->mac_ctx;
 
+        if (0 == EVP_MAC_init(ctx, NULL, 0, NULL)) {
+                unsigned long err = ERR_get_error();
+                char * str = ERR_error_string(err, NULL);
+                msyslog(LOG_ERR, "decrypt: EVP_MAC_init() failed: %s.", str);
+                return false;
+        }
+        if (0 == EVP_MAC_update(ctx, (unsigned char *)pkt, length)) {
+                unsigned long err = ERR_get_error();
+                char * str = ERR_error_string(err, NULL);
+                msyslog(LOG_ERR, "decrypt: EVP_MAC_update() failed: %s.", str);
+                return false;
+        }
+        if (0 == EVP_MAC_final(ctx, mac, &len, sizeof(mac))) {
+                unsigned long err = ERR_get_error();
+                char * str = ERR_error_string(err, NULL);
+                msyslog(LOG_ERR, "decrypt: EVP_MAC_final() failed: %s.", str);
+                return false;
+        }
+#else
+	CMAC_CTX *ctx = cmac_ctx;
 	if (!CMAC_Init(ctx, auth->key, auth->key_size, auth->cipher, NULL)) {
 		/* Shouldn't happen.  Does if wrong key_size. */
 		msyslog(LOG_ERR,
-		    "MAC: decrypt: CMAC init failed, %u, %u",
+		    "decrypt: CMAC init failed, %u, %u",
 			auth->keyid, auth->key_size);
 		return false;
 	}
 	CMAC_Update(ctx, (uint8_t *)pkt, (unsigned int)length);
 	CMAC_Final(ctx, mac, &len);
+#endif
 	if (MAX_BARE_MAC_LENGTH < len)
 		len = MAX_BARE_MAC_LENGTH;
+
 	if ((unsigned int)size != len + 4) {
 		/* Beware of DoS attack.
 		 * This indicates either the sender is broken
@@ -122,7 +208,6 @@ digest_encrypt(
 	 * key type and digest type have been verified when the key
 	 * was created.
 	 */
-	EVP_MD_CTX_reset(ctx);
 	if (!EVP_DigestInit_ex(ctx, auth->digest, NULL)) {
 		msyslog(LOG_ERR,
 		    "MAC: encrypt: digest init failed");
@@ -160,7 +245,6 @@ digest_decrypt(
 	 * key type and digest type have been verified when the key
 	 * was created.
 	 */
-	EVP_MD_CTX_reset(ctx);
 	if (!EVP_DigestInit_ex(ctx, auth->digest, NULL)) {
 		msyslog(LOG_ERR,
 		    "MAC: decrypt: digest init failed");


=====================================
libntp/pymodule-mac.c
=====================================
@@ -25,9 +25,6 @@
 #ifndef EVP_MD_CTX_new
 #define EVP_MD_CTX_new() EVP_MD_CTX_create()
 #endif
-#ifndef EVP_MD_CTX_reset
-#define EVP_MD_CTX_reset(ctx) EVP_MD_CTX_init(ctx)
-#endif
 
 /* Needed on OpenSSL < 1.1.0 */
 static void init_ssl(void) {
@@ -107,7 +104,6 @@ void do_mac(char *name,
 		unsigned int maclenint;
 		if (NULL == digest_ctx)
 			digest_ctx = EVP_MD_CTX_new();
-		EVP_MD_CTX_reset(digest_ctx);
 		if (!EVP_DigestInit_ex(digest_ctx, digest, NULL)) {
 			*maclen = 0;
 			return;


=====================================
libntp/ssl_init.c
=====================================
@@ -1,7 +1,6 @@
 /* ssl_init.c	Common OpenSSL initialization code
  * This is needed for crypto as well as NTS
  */
-#define OPENSSL_SUPPRESS_DEPRECATED 1
 
 #include "config.h"
 #include "ntp_stdlib.h"
@@ -10,7 +9,13 @@
 #include <stdbool.h>
 #include <openssl/ssl.h>
 #include <openssl/evp.h>
+
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+#include <openssl/params.h>
+#include <openssl/err.h>
+#else
 #include <openssl/cmac.h>
+#endif
 
 #ifndef EVP_MD_CTX_new
 /* Slightly older version of OpenSSL */
@@ -24,7 +29,11 @@ static void	atexit_ssl_cleanup(void);
 
 static bool ssl_init_done;
 EVP_MD_CTX *digest_ctx;
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+EVP_MAC_CTX *evp_ctx;
+#else
 CMAC_CTX *cmac_ctx;
+#endif
 
 void
 ssl_init(void)
@@ -50,7 +59,56 @@ ssl_init(void)
 	ntp_RAND_bytes(&dummy, 1);
 
 	digest_ctx = EVP_MD_CTX_new();
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+	{
+	EVP_MAC *mac = EVP_MAC_fetch(NULL, "cmac", NULL);
+	if (NULL == mac) {
+		msyslog(LOG_ERR, "ssl_init: EVP_MAC_fetch failed");
+		exit(1);
+	}
+	evp_ctx = EVP_MAC_CTX_new(mac);
+	if (NULL == evp_ctx) {
+		msyslog(LOG_ERR, "ssl_init: EVP_MAC_CTX_new failed");
+		exit(1);
+	}
+	// EVP_MAC_free(mac);
+	}
+/* Barf: EVP_MAC_CTX_dup doesn't work until src gets cipher and key */
+	{
+	EVP_MAC_CTX *ctx;
+	OSSL_PARAM params[3];
+	char key[16];
+	char copy[100];		/* OSSL_PARAM vs const */
+
+	ctx = EVP_MAC_CTX_dup(evp_ctx);
+	if (NULL != ctx ) {
+		/* Was failing: 2023-feb-20, OpenSSL 3.0.8 */
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		msyslog(LOG_ERR, "ssl_init: first dup worked: %s", str);
+	}
+
+	strlcpy(copy, "AES-128-CBC", sizeof(copy));
+	params[0] = OSSL_PARAM_construct_utf8_string("cipher", copy, 0);
+	params[1] = OSSL_PARAM_construct_octet_string("key", key, 16);
+	params[2] = OSSL_PARAM_construct_end();
+	if (0 == EVP_MAC_CTX_set_params(evp_ctx, params)) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		msyslog(LOG_ERR, "ssl_init: EVP_MAC_CTX_set_params() failed: %s", str);
+	}
+
+
+	ctx = EVP_MAC_CTX_dup(evp_ctx);
+	if (NULL == ctx ) {
+		unsigned long err = ERR_get_error();
+		char * str = ERR_error_string(err, NULL);
+		msyslog(LOG_ERR, "ssl_init: second dup failed: %s", str);
+	}
+	}
+#else
 	cmac_ctx = CMAC_CTX_new();
+#endif
 	ssl_init_done = true;
 }
 


=====================================
ntpd/ntp_control.c
=====================================
@@ -2582,7 +2582,7 @@ send_random_tag_value(
 	int	noise;
 	char	buf[32];
 
-	/* coverity[weak_crypto] */
+	/* coverity[DC.WEAK_CRYPTO] */
 	noise = random();
 	buf[0] = 'a' + noise % 26;
 	noise >>= 5;
@@ -3170,7 +3170,7 @@ send_ifstats_entry(
 	noisebits = 0;
 	while (remaining > 0) {
 		if (noisebits < 4) {
-			/* coverity[weak_crypto] */
+			/* coverity[DC.WEAK_CRYPTO] */
 			noise = (uint32_t)random();
 			noisebits = 31;
 		}
@@ -3348,7 +3348,7 @@ send_restrict_entry(
 	noisebits = 0;
 	while (remaining > 0) {
 		if (noisebits < 2) {
-			/* coverity[weak_crypto] */
+			/* coverity[DC.WEAK_CRYPTO] */
 			noise = (uint32_t)random();
 			noisebits = 31;
 		}


=====================================
ntpd/refclock_generic.c
=====================================
@@ -2557,15 +2557,19 @@ parse_start(
 	/*
 	 * Unit okay, attempt to open the device.
 	 */
-	if (peer->cfg.path)
+	if (peer->cfg.path) {
 	    path = peer->cfg.path;
-	else {
+	    /* parsedef (may?) get printed later.  Coverity */
+	    strlcpy(parsedev, path, sizeof(parsedev));
+	} else {
 	    (void) snprintf(parsedev, sizeof(parsedev), PARSEDEVICE, unit);
 	    path = parsedev;
 	}
-	if (peer->cfg.ppspath)
+	if (peer->cfg.ppspath) {
 	    ppspath = peer->cfg.ppspath;
-	else {
+	    /* parseppsdef (may?) get printed later.  Coverity */
+	    strlcpy(parseppsdev, ppspath, sizeof(parseppsdev));
+	} else {
 	    (void) snprintf(parseppsdev, sizeof(parsedev), PARSEPPSDEVICE, unit);
 	    ppspath = parseppsdev;
 	}


=====================================
ntpd/refclock_oncore.c
=====================================
@@ -1626,6 +1626,7 @@ oncore_get_timestamp(
 	char Msg[160];
 
 	peer = instance->peer;
+	strlcpy(Msg, "bug-coverity-uninitalized", sizeof(Msg));
 
 #if 1
 	/* If we are in SiteSurvey mode, then we are in 3D mode, and we fall through.


=====================================
tests/libntp/macencrypt.c
=====================================
@@ -2,6 +2,12 @@
 #include "ntp_stdlib.h"
 #include "ntp_auth.h"
 
+// Note that NTP doesn't use RFCs 1321 or 4631
+
+// RFC 4493: The AES-CMAC Algorithm
+//   https://www.rfc-editor.org/rfc/rfc4493
+
+
 #include "unity.h"
 #include "unity_fixture.h"
 
@@ -42,7 +48,11 @@ TEST(macencrypt, Encrypt) {
 	auth.keyid = 123;
 	auth.type = AUTH_DIGEST;
 	auth.digest = EVP_get_digestbyname("MD5");
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+	auth.mac_ctx = NULL;
+#else
 	auth.cipher = NULL;
+#endif
 	auth.key = (uint8_t *)MD5key;
 	auth.key_size = (unsigned short)strlen(MD5key);
 
@@ -80,11 +90,15 @@ TEST(macencrypt, CMAC_Encrypt) {
 	auth.keyid = 1234;
 	auth.type = AUTH_CMAC;
 	auth.digest = NULL;
-	auth.cipher = EVP_get_cipherbyname("AES-128-CBC");
 	auth.key = (uint8_t *)CMACkey;
 	auth.key_size = (unsigned short)strlen(CMACkey);
-
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+	auth.mac_ctx = Setup_MAC_CTX("AES-128-CBC", auth.key, auth.key_size);
+	TEST_ASSERT_NOT_NULL(auth.mac_ctx);
+#else
+	auth.cipher = EVP_get_cipherbyname("AES-128-CBC");
 	TEST_ASSERT_NOT_NULL(auth.cipher);
+#endif
 
 	int length = cmac_encrypt(&auth,
 				  (uint32_t*)packetPtr, packetLength);
@@ -162,7 +176,6 @@ TEST(macencrypt, IPv6AddressToRefId) {
 }
 
 TEST(macencrypt, null_trunc) {
-	const char *algo = "aes-128-cbc";
 	unsigned char key[] = {
 		0x0f, 0xd2, 0x28, 0x7c, 0x1e, 0x97, 0xa5, 0x0c,
 		0xb9, 0xd3, 0xcb, 0x9f, 0x80, 0xde, 0xbc, 0xb6,
@@ -192,15 +205,21 @@ TEST(macencrypt, null_trunc) {
 	auth.keyid = 100;
 	auth.type = AUTH_CMAC;
 	auth.digest = NULL;
-	auth.cipher = EVP_get_cipherbyname(algo);
 	auth.key = (uint8_t *)key;
 	auth.key_size = (unsigned short)strlen(CMACkey);
+
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+	auth.mac_ctx = Setup_MAC_CTX("AES-128-CBC", auth.key, auth.key_size);
+	TEST_ASSERT_NOT_NULL(auth.mac_ctx);
+#else
+	auth.cipher = EVP_get_cipherbyname("AES-128-CBC");
 	TEST_ASSERT_NOT_NULL(auth.cipher);
+#endif
 
 	int length = cmac_encrypt(&auth,
 				  (uint32_t*)sample, len_pack);
 
-	TEST_ASSERT_EQUAL(4+16, length);            /* aria-128 */
+	TEST_ASSERT_EQUAL(4+16, length);            /* AES-128 */
 
 	TEST_ASSERT_EQUAL_MEMORY(
 	    &(expected_sample[52]),
@@ -209,6 +228,85 @@ TEST(macencrypt, null_trunc) {
 	);
 }
 
+/* Test vectors from RFC 4493
+ * Note: All tests use the same message.
+ * Shorter tests only use the front part of it.
+ * The message gets copied into buffer because cmac_encrypt
+ * trashes the buffer by appending the MAC.
+ */
+TEST(macencrypt, CMAC_TestVectors) {
+	const unsigned char M[64] = {
+		0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+		0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+		0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+		0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+		0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+		0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
+		0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+		0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
+	};
+	unsigned char key[16] = {
+		0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+		0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
+	};
+	const unsigned char mac0[16] = {
+//    AES-CMAC       bb1d6929 e9593728 7fa37d12 9b756746
+		0xbb, 0x1d, 0x69, 0x29,  0xe9, 0x59, 0x37, 0x28,
+		0x7f, 0xa3, 0x7d, 0x12,  0x9b, 0x75, 0x67, 0x46
+	};
+	const unsigned char mac16[16] = {
+//    AES-CMAC       070a16b4 6b4d4144 f79bdd9d d04a287c
+		0x07, 0x0a, 0x16, 0xb4,  0x6b, 0x4d, 0x41, 0x44,
+		0xf7, 0x9b, 0xdd, 0x9d,  0xd0, 0x4a, 0x28, 0x7c
+	};
+	const unsigned char mac40[16] = {
+//    AES-CMAC       dfa66747 de9ae630 30ca3261 1497c827
+		0xdf, 0xa6, 0x67, 0x47,  0xde, 0x9a, 0xe6, 0x30,
+		0x30, 0xca, 0x32, 0x61,  0x14, 0x97, 0xc8, 0x27
+	};
+	const unsigned char mac64[16] = {
+//    AES-CMAC       51f0bebf 7e3b9d92 fc497417 79363cfe
+		0x51, 0xf0, 0xbe, 0xbf,  0x7e, 0x3b, 0x9d, 0x92,
+		0xfc, 0x49, 0x74, 0x17,  0x79, 0x36, 0x3c, 0xfe
+	};
+	unsigned char buffer[64+4+16];
+	int length;
+
+	auth.keyid = 100;
+	auth.type = AUTH_CMAC;
+	auth.digest = NULL;
+	auth.key = (uint8_t *)key;
+	auth.key_size = (unsigned short)sizeof(key);
+
+#if OPENSSL_VERSION_NUMBER > 0x20000000L
+	auth.mac_ctx = Setup_MAC_CTX("AES-128-CBC", auth.key, auth.key_size);
+	TEST_ASSERT_NOT_NULL(auth.mac_ctx);
+#else
+	auth.cipher = EVP_get_cipherbyname("AES-128-CBC");
+	TEST_ASSERT_NOT_NULL(auth.cipher);
+#endif
+
+	memcpy(buffer, M, 0);
+	length = cmac_encrypt(&auth, (uint32_t*)buffer, 0);
+	TEST_ASSERT_EQUAL(4+16, length);
+	TEST_ASSERT_EQUAL_MEMORY(mac0, buffer+0+4, 16);
+
+	memcpy(buffer, M, 16);
+	length = cmac_encrypt(&auth, (uint32_t*)buffer, 16);
+	TEST_ASSERT_EQUAL(4+16, length);
+	TEST_ASSERT_EQUAL_MEMORY(mac16, buffer+16+4, 16);
+
+	memcpy(buffer, M, 40);
+	length = cmac_encrypt(&auth, (uint32_t*)buffer, 40);
+	TEST_ASSERT_EQUAL(4+16, length);
+	TEST_ASSERT_EQUAL_MEMORY(mac40, buffer+40+4, 16);
+
+	memcpy(buffer, M, 64);
+	length = cmac_encrypt(&auth, (uint32_t*)buffer, 64);
+	TEST_ASSERT_EQUAL(4+16, length);
+	TEST_ASSERT_EQUAL_MEMORY(mac64, buffer+64+4, 16);
+}
+
 /* Both digest and CMAC tests share some global variables
  * that get setup by Encrypt or CMAC_Encrypt
  * Thus the tests must be run in the right order.
@@ -218,9 +316,11 @@ TEST_GROUP_RUNNER(macencrypt) {
 	RUN_TEST_CASE(macencrypt, DecryptValid);
 	RUN_TEST_CASE(macencrypt, DecryptInvalid);
 	RUN_TEST_CASE(macencrypt, CMAC_Encrypt);
+	RUN_TEST_CASE(macencrypt, CMAC_Encrypt);
 	RUN_TEST_CASE(macencrypt, DecryptValidCMAC);
 	RUN_TEST_CASE(macencrypt, DecryptInvalidCMAC);
 	RUN_TEST_CASE(macencrypt, IPv4AddressToRefId);
 	RUN_TEST_CASE(macencrypt, IPv6AddressToRefId);
-	RUN_TEST_CASE(macencrypt, null_trunc)
+	RUN_TEST_CASE(macencrypt, null_trunc);
+	RUN_TEST_CASE(macencrypt, CMAC_TestVectors);
 }



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/3418b33fc969af3bf9bb0fd91fec5080925853ed...cc4b750b6d86e131221982603106fc10906735a6

-- 
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/3418b33fc969af3bf9bb0fd91fec5080925853ed...cc4b750b6d86e131221982603106fc10906735a6
You're receiving this email because of your account on gitlab.com.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20230323/2d9faf25/attachment-0001.htm>


More information about the vc mailing list