]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
libntp/a_md5encrypt.c: add AES128CMAC and better OpenSSL support,
authorBrian Inglis <bwi@ntp.org>
Fri, 26 May 2017 18:28:01 +0000 (19:28 +0100)
committerBrian Inglis <bwi@ntp.org>
Fri, 26 May 2017 18:28:01 +0000 (19:28 +0100)
libntp/authreadkeys.c: add AES128CMAC support,
ports/winnt/ntpd/nt_ppsimpl.c: fix environment termination

bk: 592873b1qV7ecxAsoeNFMcPJxoZuXQ

libntp/a_md5encrypt.c
libntp/authreadkeys.c
ports/winnt/ntpd/nt_ppsimpl.c

index 7394d0d27b357d59cd8b4fa36ff2f615ad69a23f..01956b3f88d8dcaddba156446e6585d50e1b8789 100644 (file)
 #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;
index e9273ad61dbe5af3bbfde613f144a4080af00258..faa880bfab7660551592c5e04398e397f1053a65 100644 (file)
@@ -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);
index 2a7c0d88f1d94bc641411c2e50c494dd73f2a326..1ed3634cd5deb0b5fe7e46d937f08ceb90cfc64d 100644 (file)
@@ -359,8 +359,9 @@ regfail:
                        *op++ = *cp;
                }
        }
-       cp[0] = '\0';
-       cp[1] = '\0';
+       
+       *op++ = '\0';
+       *op = '\0';
        return s_Value;
 
 envfail: