[Git][NTPsec/ntpsec][master] 2 commits: Add CMAC timing to attic/digest-timing.c
Hal Murray
gitlab at mg.gitlab.com
Fri Mar 2 08:46:49 UTC 2018
Hal Murray pushed to branch master at NTPsec / ntpsec
Commits:
86f85050 by Hal Murray at 2018-03-02T08:46:14Z
Add CMAC timing to attic/digest-timing.c
- - - - -
b01f1d65 by Hal Murray at 2018-03-02T08:46:14Z
Truncate digests longer than 20 bytes.
- - - - -
6 changed files:
- attic/digest-timing.c
- docs/authentic.txt
- docs/includes/ntp.keys-body.txt
- include/ntp_types.h
- libntp/authreadkeys.c
- libntp/macencrypt.c
Changes:
=====================================
attic/digest-timing.c
=====================================
--- a/attic/digest-timing.c
+++ b/attic/digest-timing.c
@@ -6,6 +6,10 @@
* It doesn't include the copy or compare or finding the right key.
*
* Beware of overflows in the timing computations.
+ *
+ * Disable AES-NI (Intel hardware: NI == New Instruction) with:
+ * OPENSSL_ia32cap="~0x200000200000000"
+ * Check /proc/cpuinfo flags for "aes" to see if you have it.
*/
#include <stdint.h>
@@ -14,6 +18,7 @@
#include <time.h>
#include <openssl/err.h>
+#include <openssl/cmac.h>
#include <openssl/evp.h>
#include <openssl/md5.h>
#include <openssl/rand.h>
@@ -39,18 +44,20 @@ int NUM = 1000000;
/* Nothing magic about these key lengths.
* ntpkeygen just happens to label things this way.
*/
+#define AES_KEY_LENGTH 16
#define MD5_KEY_LENGTH 16
#define SHA1_KEY_LENGTH 20
#define MAX_KEY_LENGTH 64
EVP_MD_CTX *ctx;
+CMAC_CTX *cmac;
-void ssl_init(void);
-void ssl_init(void)
+static void ssl_init(void)
{
ERR_load_crypto_strings();
OpenSSL_add_all_digests();
ctx = EVP_MD_CTX_new();
+ cmac = CMAC_CTX_new();
}
static unsigned int SSL_Digest(
@@ -89,7 +96,23 @@ static unsigned int SSL_DigestSlow(
return len;
}
-static void DoOne(
+static size_t SSL_CMAC(
+ const EVP_CIPHER *cipher, /* cipher algorithm */
+ uint8_t *key, /* key pointer */
+ int keylength, /* key size */
+ uint8_t *pkt, /* packet pointer */
+ int pktlength /* packet length */
+) {
+ unsigned char answer[EVP_MAX_MD_SIZE];
+ size_t len;
+ CMAC_resume(cmac);
+ CMAC_Init(cmac, key, keylength, cipher, NULL);
+ CMAC_Update(cmac, pkt, pktlength);
+ CMAC_Final(cmac, answer, &len);
+ return len;
+}
+
+static void DoDigest(
const char *name, /* type of digest */
uint8_t *key, /* key pointer */
int keylength, /* key size */
@@ -128,6 +151,34 @@ static void DoOne(
printf("\n");
}
+static void DoCMAC(
+ const char *name, /* name of cipher */
+ const EVP_CIPHER *cipher,
+ uint8_t *key, /* key pointer */
+ int keylength, /* key length */
+ uint8_t *pkt, /* packet pointer */
+ int pktlength /* packet length */
+)
+{
+ struct timespec start, stop;
+ int i;
+ double fast;
+ unsigned long digestlength = 0;
+
+ if (NULL == cipher) return;
+
+ clock_gettime(CLOCK_MONOTONIC, &start);
+ for (i = 0; i < NUM; i++) {
+ digestlength = SSL_CMAC(cipher, key, keylength, pkt, pktlength);
+ }
+ clock_gettime(CLOCK_MONOTONIC, &stop);
+ fast = (stop.tv_sec-start.tv_sec)*1E9 + (stop.tv_nsec-start.tv_nsec);
+ printf("%10s %2d %2d %2lu %6.0f %6.3f",
+ name, keylength, pktlength, digestlength, fast/NUM, fast/1E9);
+
+ printf("\n");
+}
+
int main(int argc, char *argv[])
@@ -146,25 +197,37 @@ int main(int argc, char *argv[])
printf("# KL=key length, PL=packet length, DL=digest length\n");
printf("# Digest KL PL DL ns/op sec/run slow %% diff\n");
- DoOne("MD5", key, MD5_KEY_LENGTH, packet, PACKET_LENGTH);
- DoOne("MD5", key, MD5_KEY_LENGTH-1, packet, PACKET_LENGTH);
- DoOne("MD5", key, SHA1_KEY_LENGTH, packet, PACKET_LENGTH);
- DoOne("SHA1", key, MD5_KEY_LENGTH, packet, PACKET_LENGTH);
- DoOne("SHA1", key, SHA1_KEY_LENGTH, packet, PACKET_LENGTH);
- DoOne("SHA1", key, SHA1_KEY_LENGTH-1, packet, PACKET_LENGTH);
- DoOne("SHA224", key, 16, packet, PACKET_LENGTH);
- DoOne("SHA224", key, 20, packet, PACKET_LENGTH);
- DoOne("SHA256", key, 16, packet, PACKET_LENGTH);
- DoOne("SHA256", key, 20, packet, PACKET_LENGTH);
- DoOne("SHA384", key, 16, packet, PACKET_LENGTH);
- DoOne("SHA384", key, 20, packet, PACKET_LENGTH);
- DoOne("SHA512", key, 16, packet, PACKET_LENGTH);
- DoOne("SHA512", key, 20, packet, PACKET_LENGTH);
- DoOne("SHA512", key, 24, packet, PACKET_LENGTH);
- DoOne("SHA512", key, 32, packet, PACKET_LENGTH);
- DoOne("RIPEMD160", key, 16, packet, PACKET_LENGTH);
- DoOne("RIPEMD160", key, 20, packet, PACKET_LENGTH);
- DoOne("RIPEMD160", key, 32, packet, PACKET_LENGTH);
+ DoDigest("MD5", key, MD5_KEY_LENGTH, packet, PACKET_LENGTH);
+ DoDigest("MD5", key, MD5_KEY_LENGTH-1, packet, PACKET_LENGTH);
+ DoDigest("MD5", key, SHA1_KEY_LENGTH, packet, PACKET_LENGTH);
+ DoDigest("SHA1", key, MD5_KEY_LENGTH, packet, PACKET_LENGTH);
+ DoDigest("SHA1", key, SHA1_KEY_LENGTH, packet, PACKET_LENGTH);
+ DoDigest("SHA1", key, SHA1_KEY_LENGTH-1, packet, PACKET_LENGTH);
+ DoDigest("SHA224", key, 16, packet, PACKET_LENGTH);
+ DoDigest("SHA224", key, 20, packet, PACKET_LENGTH);
+ DoDigest("SHA256", key, 16, packet, PACKET_LENGTH);
+ DoDigest("SHA256", key, 20, packet, PACKET_LENGTH);
+ DoDigest("SHA384", key, 16, packet, PACKET_LENGTH);
+ DoDigest("SHA384", key, 20, packet, PACKET_LENGTH);
+ DoDigest("SHA512", key, 16, packet, PACKET_LENGTH);
+ DoDigest("SHA512", key, 20, packet, PACKET_LENGTH);
+ DoDigest("SHA512", key, 24, packet, PACKET_LENGTH);
+ DoDigest("SHA512", key, 32, packet, PACKET_LENGTH);
+ DoDigest("RIPEMD160", key, 16, packet, PACKET_LENGTH);
+ DoDigest("RIPEMD160", key, 20, packet, PACKET_LENGTH);
+ DoDigest("RIPEMD160", key, 32, packet, PACKET_LENGTH);
+
+ printf("\n");
+ printf("# KL=key length, PL=packet length, CL=CMAC length\n");
+ printf("# CMAC KL PL CL ns/op sec/run\n");
+
+ DoCMAC("DES", EVP_des_cbc(), key, 8, packet, PACKET_LENGTH);
+ DoCMAC("AES-128", EVP_aes_128_cbc(), key, 16, packet, PACKET_LENGTH);
+ DoCMAC("AES-192", EVP_aes_192_cbc(), key, 24, packet, PACKET_LENGTH);
+ DoCMAC("AES-256", EVP_aes_256_cbc(), key, 32, packet, PACKET_LENGTH);
+ DoCMAC("CAM-128", EVP_camellia_128_cbc(), key, 16, packet, PACKET_LENGTH);
+ DoCMAC("CAM-192", EVP_camellia_192_cbc(), key, 24, packet, PACKET_LENGTH);
+ DoCMAC("CAM-256", EVP_camellia_256_cbc(), key, 32, packet, PACKET_LENGTH);
return 0;
=====================================
docs/authentic.txt
=====================================
--- a/docs/authentic.txt
+++ b/docs/authentic.txt
@@ -111,7 +111,8 @@ program.
== Algorithms ==
The NTP standards include symmetric (private-key) authentication using
-any message digest algorithm supported by the OpenSSL package
+any message digest algorithm supported by the OpenSSL package.
+Digests longer than 20 bytes will be truncated.
This algorithm computes a message digest or one-way hash
which can be used to verify the client has the same message digest as
the server.
=====================================
docs/includes/ntp.keys-body.txt
=====================================
--- a/docs/includes/ntp.keys-body.txt
+++ b/docs/includes/ntp.keys-body.txt
@@ -24,6 +24,8 @@ where `keyno` is a positive integer (between 1 and 65534),
The file does not need to be sorted by `keyno`.
`type` can be any digest type supported by your OpenSSL package.
+Digests longer than 20 bytes will be trucnated.
+
You can probably get a list from `man 1 dgst` or `openssl help`.
(As of Jan 2018, they lie. Be sure to try it. {ntpdman} will
print an error on startup if a selected type isn't supported.)
=====================================
include/ntp_types.h
=====================================
--- a/include/ntp_types.h
+++ b/include/ntp_types.h
@@ -68,6 +68,9 @@ typedef uint16_t associd_t; /* association ID */
typedef uint32_t keyid_t; /* cryptographic key ID */
#define NTP_MAXKEY 0xffff /* max authentication key number */
+/* Max digest length in non-extension MACs, add 4 for keyID */
+#define MAX_BARE_DIGEST_LENGTH 20
+
/*
* Ordinary double has only 53 bits of precision in IEEE754. But l_fp
* needs 64 bits of precision, arguably 65 bits after 2026. Thus, to have
=====================================
libntp/authreadkeys.c
=====================================
--- a/libntp/authreadkeys.c
+++ b/libntp/authreadkeys.c
@@ -60,6 +60,28 @@ nexttok(
}
+static void
+check_digest_length(
+ keyid_t keyno,
+ int keytype,
+ char *name) {
+ unsigned char digest[EVP_MAX_MD_SIZE];
+ unsigned int length = 0;
+ EVP_MD_CTX *ctx;
+ const EVP_MD *md;
+
+ md = EVP_get_digestbynid(keytype);
+ ctx = EVP_MD_CTX_create();
+ EVP_DigestInit_ex(ctx, md, NULL);
+ EVP_DigestFinal_ex(ctx, digest, &length);
+ EVP_MD_CTX_destroy(ctx);
+
+ if (MAX_BARE_DIGEST_LENGTH < length) {
+ msyslog(LOG_ERR, "AUTH: authreadkeys: digest for key %u, %s will be truncated.", keyno, name);
+ }
+}
+
+
/*
* authreadkeys - (re)read keys from a file.
*/
@@ -177,13 +199,21 @@ msyslog(LOG_ERR, "AUTH: authreadkeys: reading %s", file);
}
len = strlen(token);
if (len <= 20) { /* Bug 2537 */
+ check_digest_length(keyno, keytype, upcased);
mac_setkey(keyno, keytype, (uint8_t *)token, len);
keys++;
} else {
char hex[] = "0123456789abcdef";
size_t jlim;
- jlim = min(len, 2 * sizeof(keystr));
+ jlim = len;
+ if ((2*sizeof(keystr)) < jlim) {
+ jlim = 2 * sizeof(keystr);
+ msyslog(LOG_ERR,
+ "AUTH: authreadkeys: key %u trucated to %u bytes",
+ keyno, (unsigned int)jlim);
+
+ }
for (j = 0; j < jlim; j++) {
char *ptr = strchr(hex, tolower((unsigned char)token[j]));
if (ptr == NULL)
@@ -200,6 +230,7 @@ msyslog(LOG_ERR, "AUTH: authreadkeys: reading %s", file);
keyno);
continue;
}
+ check_digest_length(keyno, keytype, upcased);
mac_setkey(keyno, keytype, keystr, jlim / 2);
keys++;
}
=====================================
libntp/macencrypt.c
=====================================
--- a/libntp/macencrypt.c
+++ b/libntp/macencrypt.c
@@ -9,6 +9,7 @@
#include <stdint.h>
#include <openssl/evp.h> /* provides OpenSSL digest API */
+#include <openssl/md5.h>
#include "ntp_fp.h"
#include "ntp_stdlib.h"
@@ -77,6 +78,8 @@ mac_authencrypt(
EVP_DigestUpdate(ctx, key, key_size);
EVP_DigestUpdate(ctx, (uint8_t *)pkt, (unsigned int)length);
EVP_DigestFinal_ex(ctx, digest, &len);
+ if (MAX_BARE_DIGEST_LENGTH < len)
+ len = MAX_BARE_DIGEST_LENGTH;
memmove((uint8_t *)pkt + length + 4, digest, len);
return (int)(len + 4);
}
@@ -115,6 +118,8 @@ mac_authdecrypt(
EVP_DigestUpdate(ctx, key, key_size);
EVP_DigestUpdate(ctx, (uint8_t *)pkt, (unsigned int)length);
EVP_DigestFinal_ex(ctx, digest, &len);
+ if (MAX_BARE_DIGEST_LENGTH < len)
+ len = MAX_BARE_DIGEST_LENGTH;
if ((unsigned int)size != len + 4) {
msyslog(LOG_ERR,
"MAC: decrypt: MAC length error");
@@ -133,7 +138,7 @@ mac_authdecrypt(
uint32_t
addr2refid(sockaddr_u *addr)
{
- uint8_t digest[20];
+ uint8_t digest[MD5_DIGEST_LENGTH];
uint32_t addr_refid;
EVP_MD_CTX *ctx;
unsigned int len;
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/7c3e7805922797d671d594d17ba262d8e61b8cb4...b01f1d658b11c4e8c24b307a7a79e8307364fbc2
---
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/7c3e7805922797d671d594d17ba262d8e61b8cb4...b01f1d658b11c4e8c24b307a7a79e8307364fbc2
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/20180302/a6fc8639/attachment.html>
More information about the vc
mailing list