From: Brian Inglis Date: Fri, 26 May 2017 18:28:01 +0000 (+0100) Subject: libntp/a_md5encrypt.c: add AES128CMAC and better OpenSSL support, X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=725183cc604e0d6a38174e901e9ce3175ee3ae80;p=thirdparty%2Fntp.git libntp/a_md5encrypt.c: add AES128CMAC and better OpenSSL support, libntp/authreadkeys.c: add AES128CMAC support, ports/winnt/ntpd/nt_ppsimpl.c: fix environment termination bk: 592873b1qV7ecxAsoeNFMcPJxoZuXQ --- diff --git a/libntp/a_md5encrypt.c b/libntp/a_md5encrypt.c index 7394d0d27..01956b3f8 100644 --- a/libntp/a_md5encrypt.c +++ b/libntp/a_md5encrypt.c @@ -11,6 +11,12 @@ #include "ntp.h" #include "ntp_md5.h" /* provides OpenSSL digest API */ #include "isc/string.h" + +#ifdef OPENSSL +# include "openssl/cmac.h" +# define CMAC "AES128CMAC" +#endif + /* * MD5authencrypt - generate message digest * @@ -26,7 +32,7 @@ MD5authencrypt( { u_char digest[EVP_MAX_MD_SIZE]; u_int len; - EVP_MD_CTX *ctx; +/* EVP_MD_CTX *ctx; */ /* * Compute digest of key concatenated with packet. Note: the @@ -34,7 +40,81 @@ MD5authencrypt( * was creaded. */ INIT_SSL(); - ctx = EVP_MD_CTX_new(); +#ifdef OPENSSL + /* Check if CMAC key type specific code required */ + if (cache_type == NID_cmac) { + CMAC_CTX * ctx; + + if (debug) { + fprintf(stderr, "%s:%d:%s():%s:nid\n", + __FILE__, __LINE__, __func__, CMAC); + } + + if (!(ctx = CMAC_CTX_new())) { + fprintf(stderr, "MAC encrypt: CMAC %s CTX new failed.\n", CMAC); + msyslog(LOG_ERR, "MAC encrypt: CMAC %s CTX new failed.", CMAC); + len = 0; + } else + if (!CMAC_Init(ctx, key, (u_int)cache_secretsize, + EVP_aes_128_cbc(), NULL)) { + fprintf(stderr, "MAC encrypt: CMAC %s Init failed.\n", CMAC); + msyslog(LOG_ERR, "MAC encrypt: CMAC %s Init failed.", CMAC); + len = 0; + } else + if (!CMAC_Update(ctx, (u_char *)pkt, (u_int)length)) { + fprintf(stderr, "MAC encrypt: CMAC %s Update failed.\n", CMAC); + msyslog(LOG_ERR, "MAC encrypt: CMAC %s Update failed.", CMAC); + len = 0; + } else + if (!CMAC_Final(ctx, digest, &len)) { + fprintf(stderr, "MAC encrypt: CMAC %s Final failed.\n", CMAC); + msyslog(LOG_ERR, "MAC encrypt: CMAC %s Final failed.", CMAC); + len = 0; + } + + CMAC_CTX_cleanup(ctx); + } else { /* generic MAC handling */ +#endif + EVP_MD_CTX * ctx; + + if (!(ctx = EVP_MD_CTX_new())) { + fprintf(stderr, "MAC encrypt: MAC %s Digest CTX new failed.\n", + OBJ_nid2sn(type)); + msyslog(LOG_ERR, "MAC encrypt: MAC %s Digest CTX new failed.", + OBJ_nid2sn(type)); + len = 0; + } +#ifdef OPENSSL /* OpenSSL 1 supports return codes 0 fail, 1 okay */ + else + if (!EVP_DigestInit(ctx, EVP_get_digestbynid(type))) { + fprintf(stderr, "MAC encrypt: MAC %s Digest Init failed.\n", + OBJ_nid2sn(type)); + msyslog(LOG_ERR, "MAC encrypt: MAC %s Digest Init failed.", + OBJ_nid2sn(type)); + len = 0; + } else + if (!EVP_DigestUpdate(ctx, key, (u_int)cache_secretsize)) { + fprintf(stderr, "MAC encrypt: MAC %s Digest Update key failed.\n", + OBJ_nid2sn(type)); + msyslog(LOG_ERR, "MAC encrypt: MAC %s Digest Update key failed.", + OBJ_nid2sn(type)); + len = 0; + } else + if (!EVP_DigestUpdate(ctx, (u_char *)pkt, (u_int)length)) { + fprintf(stderr, "MAC encrypt: MAC %s Digest Update data failed.\n", + OBJ_nid2sn(type)); + msyslog(LOG_ERR, "MAC encrypt: MAC %s Digest Update data failed.", + OBJ_nid2sn(type)); + len = 0; + } else + if (!EVP_DigestFinal(ctx, digest, &len)) { + fprintf(stderr, "MAC encrypt: MAC %s Digest Final failed.\n", + OBJ_nid2sn(type)); + msyslog(LOG_ERR, "MAC encrypt: MAC %s Digest Final failed.", + OBJ_nid2sn(type)); + len = 0; + } +#else /* !OPENSSL */ if (!(ctx && EVP_DigestInit(ctx, EVP_get_digestbynid(type)))) { msyslog(LOG_ERR, "MAC encrypt: digest init failed"); @@ -44,7 +124,11 @@ MD5authencrypt( EVP_DigestUpdate(ctx, key, cache_secretsize); EVP_DigestUpdate(ctx, (u_char *)pkt, length); EVP_DigestFinal(ctx, digest, &len); +#endif EVP_MD_CTX_free(ctx); +#ifdef OPENSSL + } +#endif /* If the MAC is longer than the MAX then truncate it. */ if (len > MAX_MAC_LEN - 4) len = MAX_MAC_LEN - 4; @@ -69,7 +153,7 @@ MD5authdecrypt( { u_char digest[EVP_MAX_MD_SIZE]; u_int len; - EVP_MD_CTX *ctx; +/* EVP_MD_CTX *ctx; */ /* * Compute digest of key concatenated with packet. Note: the @@ -77,17 +161,96 @@ MD5authdecrypt( * was created. */ INIT_SSL(); - ctx = EVP_MD_CTX_new(); - if (!(ctx && EVP_DigestInit(ctx, EVP_get_digestbynid(type)))) { - msyslog(LOG_ERR, - "MAC decrypt: digest init failed"); - EVP_MD_CTX_free(ctx); - return (0); +#ifdef OPENSSL + /* Check if CMAC key type specific code required */ + if (cache_type == NID_cmac) { + CMAC_CTX * ctx; + + + if (debug) { + fprintf(stderr, "%s:%d:%s():%s:nid\n", + __FILE__, __LINE__, __func__, CMAC); + } + + if (!(ctx = CMAC_CTX_new())) { + fprintf(stderr, "MAC decrypt: CMAC %s CTX new failed.\n", CMAC); + msyslog(LOG_ERR, "MAC decrypt: CMAC %s CTX new failed.", CMAC); + len = 0; + } else + if (!CMAC_Init(ctx, key, (u_int)cache_secretsize, + EVP_aes_128_cbc(), NULL)) { + fprintf(stderr, "MAC decrypt: CMAC %s Init failed.\n", CMAC); + msyslog(LOG_ERR, "MAC decrypt: CMAC %s Init failed.", CMAC); + len = 0; + } else + if (!CMAC_Update(ctx, (u_char *)pkt, (u_int)length)) { + fprintf(stderr, "MAC decrypt: CMAC %s Update failed.\n", CMAC); + msyslog(LOG_ERR, "MAC decrypt: CMAC %s Update failed.", CMAC); + len = 0; + } else + if (!CMAC_Final(ctx, digest, &len)) { + fprintf(stderr, "MAC decrypt: CMAC %s Final failed.\n", CMAC); + msyslog(LOG_ERR, "MAC decrypt: CMAC %s Final failed.", CMAC); + len = 0; + } + + CMAC_CTX_cleanup(ctx); + } else { /* generic MAC handling */ +#endif + EVP_MD_CTX * ctx; + + if (!(ctx = EVP_MD_CTX_new())) { + fprintf(stderr, "MAC decrypt: MAC %s Digest CTX new failed.\n", + OBJ_nid2sn(type)); + msyslog(LOG_ERR, "MAC decrypt: MAC %s Digest CTX new failed.", + OBJ_nid2sn(type)); + len = 0; + } +#ifdef OPENSSL /* OpenSSL 1 supports return codes 0 fail, 1 okay */ + else + if (!EVP_DigestInit(ctx, EVP_get_digestbynid(type))) { + fprintf(stderr, "MAC decrypt: MAC %s Digest Init failed.\n", + OBJ_nid2sn(type)); + msyslog(LOG_ERR, "MAC decrypt: MAC %s Digest Init failed.", + OBJ_nid2sn(type)); + len = 0; + } else + if (!EVP_DigestUpdate(ctx, key, (u_int)cache_secretsize)) { + fprintf(stderr, "MAC decrypt: MAC %s Digest Update key failed.\n", + OBJ_nid2sn(type)); + msyslog(LOG_ERR, "MAC decrypt: MAC %s Digest Update key failed.", + OBJ_nid2sn(type)); + len = 0; + } else + if (!EVP_DigestUpdate(ctx, (u_char *)pkt, (u_int)length)) { + fprintf(stderr, "MAC decrypt: MAC %s Digest Update data failed.\n", + OBJ_nid2sn(type)); + msyslog(LOG_ERR, "MAC decrypt: MAC %s Digest Update data failed.", + OBJ_nid2sn(type)); + len = 0; + } else + if (!EVP_DigestFinal(ctx, digest, &len)) { + fprintf(stderr, "MAC decrypt: MAC %s Digest Final failed.\n", + OBJ_nid2sn(type)); + msyslog(LOG_ERR, "MAC decrypt: MAC %s Digest Final failed.", + OBJ_nid2sn(type)); + len = 0; + } +#else /* !OPENSSL */ + if (!(ctx && EVP_DigestInit(ctx, EVP_get_digestbynid(type)))) { + msyslog(LOG_ERR, + "MAC decrypt: digest init failed"); + EVP_MD_CTX_free(ctx); + return (0); + } + EVP_DigestUpdate(ctx, key, cache_secretsize); + EVP_DigestUpdate(ctx, (u_char *)pkt, (u_int)length); + EVP_DigestFinal(ctx, digest, &len); +#endif + EVP_MD_CTX_free(ctx); +#ifdef OPENSSL } - EVP_DigestUpdate(ctx, key, cache_secretsize); - EVP_DigestUpdate(ctx, (u_char *)pkt, length); - EVP_DigestFinal(ctx, digest, &len); - EVP_MD_CTX_free(ctx); +#endif /* If the MAC is longer than the MAX then truncate it. */ if (len > MAX_MAC_LEN - 4) len = MAX_MAC_LEN - 4; diff --git a/libntp/authreadkeys.c b/libntp/authreadkeys.c index e9273ad61..faa880bfa 100644 --- a/libntp/authreadkeys.c +++ b/libntp/authreadkeys.c @@ -220,7 +220,8 @@ authreadkeys( log_maybe(NULL, "authreadkeys: invalid type for key %d", keyno); - } else if (EVP_get_digestbynid(keytype) == NULL) { + } else if (NID_cmac != keytype && + EVP_get_digestbynid(keytype) == NULL) { log_maybe(NULL, "authreadkeys: no algorithm for key %d", keyno); diff --git a/ports/winnt/ntpd/nt_ppsimpl.c b/ports/winnt/ntpd/nt_ppsimpl.c index 2a7c0d88f..1ed3634cd 100644 --- a/ports/winnt/ntpd/nt_ppsimpl.c +++ b/ports/winnt/ntpd/nt_ppsimpl.c @@ -359,8 +359,9 @@ regfail: *op++ = *cp; } } - cp[0] = '\0'; - cp[1] = '\0'; + + *op++ = '\0'; + *op = '\0'; return s_Value; envfail: