Two Message Authentication Code (MAC) libraries will be added: nettle and 
gnutls.
This patch introduces the nettle mac library along with all functions required
including initialization/deinitialization of mac context using key data and
generating the digest/mac/icv

Signed-off-by: Clay Kaiser <clay.kai...@ibm.com>
---
 incdefs.sh    |  27 +++++++++
 makefile      |   5 ++
 sad_nettle.c  | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++
 sad_private.h |  13 +++++
 4 files changed, 196 insertions(+)
 create mode 100644 sad_nettle.c

diff --git a/incdefs.sh b/incdefs.sh
index a9e94f7..5bbc7bc 100755
--- a/incdefs.sh
+++ b/incdefs.sh
@@ -50,6 +50,33 @@ user_flags()
                        fi
                done
        done
+
+       # Look for nettle support.
+       for d in $dirs; do
+               sdirs=$(find $d -type d -name "nettle")
+               for s in $sdirs; do
+                       have_nettle_meta="0"
+                       files=$(find $s -type f -name nettle-meta.h)
+                       for f in $files; do
+                               if grep -q nettle_get_macs $f; then
+                                       have_nettle_meta="1"
+                                       break 1;
+                               fi
+                       done
+                       have_hmac="0"
+                       files=$(find $s -type f -name hmac.h)
+                       for f in $files; do
+                               if grep -q hmac_sha256_set_key $f; then
+                                       have_hmac="1"
+                                       break 1;
+                               fi
+                       done
+                       if [ $have_nettle_meta = "1" ] && [ $have_nettle_meta = 
"1" ]; then
+                               printf " -DHAVE_NETTLE"
+                               break 2
+                       fi
+               done
+       done
 }
 
 #
diff --git a/makefile b/makefile
index 581cca4..fc14ee1 100644
--- a/makefile
+++ b/makefile
@@ -44,6 +44,11 @@ incdefs := $(shell $(srcdir)/incdefs.sh)
 version := $(shell $(srcdir)/version.sh $(srcdir))
 VPATH  = $(srcdir)
 
+ifneq (,$(findstring -DHAVE_NETTLE, $(incdefs)))
+LDLIBS += -lnettle
+SECURITY += sad_nettle.o
+endif
+
 prefix = /usr/local
 sbindir        = $(prefix)/sbin
 mandir = $(prefix)/man
diff --git a/sad_nettle.c b/sad_nettle.c
new file mode 100644
index 0000000..6335800
--- /dev/null
+++ b/sad_nettle.c
@@ -0,0 +1,151 @@
+/**
+ * @file sad.c
+ * @brief Security Association Database nettle functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <nettle/hmac.h>
+#include <nettle/nettle-meta.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/queue.h>
+
+#include "print.h"
+#include "sad.h"
+#include "sad_private.h"
+
+struct mac_data {
+       const struct nettle_mac *nettle_mac;
+       void *context;
+};
+
+struct mac_data *sad_init_mac(integrity_alg_type algorithm,
+                             const unsigned char *key, int key_len)
+{
+       int i, length;
+       const char *name;
+       const struct nettle_mac *mac_algorithm;
+       struct mac_data *mac_data;
+
+       /* verify key length */
+       if (key_len <= 0) {
+               return NULL;
+       }
+
+       /* retrieve mac algorithm */
+       switch (algorithm) {
+       case HMAC_SHA256_128:
+       case HMAC_SHA256:
+               name = "hmac_sha256";
+               break;
+       case CMAC_AES128:
+               name = "cmac_aes128";
+               break;
+       case CMAC_AES256:
+               name = "cmac_aes256";
+               break;
+       default:
+               return NULL;
+       }
+       for (i = 0; nettle_macs[i]; i++) {
+               if (!strcmp(name, nettle_macs[i]->name)) {
+                       mac_algorithm = nettle_macs[i];
+                       break;
+               }
+
+       }
+       if (!mac_algorithm || !mac_algorithm->context_size || 
!mac_algorithm->set_key)
+               return NULL;
+
+       /* retrieve mac key length */
+       length = mac_algorithm->key_size;
+       if (length < 0) {
+               return NULL;
+       }
+       /* verify key length matches for cmac only */
+       switch (algorithm) {
+       case CMAC_AES128:
+       case CMAC_AES256:
+               if (key_len != length) {
+                       return NULL;
+               }
+               break;
+       default:
+               break;
+       }
+
+       /* initialize mac_data and context */
+       mac_data = calloc(1, sizeof(*mac_data));
+       if (!mac_data) {
+               return NULL;
+       }
+       mac_data->nettle_mac = mac_algorithm;
+       mac_data->context = calloc(1, mac_data->nettle_mac->context_size);
+       if (!mac_data->context) {
+               free(mac_data);
+               return NULL;
+       }
+       /* set key */
+       switch (algorithm) {
+       case HMAC_SHA256_128:
+       case HMAC_SHA256:
+               /* not able to use mac abstraction AND any length sha key */
+               hmac_sha256_set_key(mac_data->context, key_len, key);
+               break;
+       case CMAC_AES128:
+       case CMAC_AES256:
+               mac_data->nettle_mac->set_key(mac_data->context, key);
+               break;
+       default:
+               sad_deinit_mac(mac_data);
+               return NULL;
+       }
+
+       return mac_data;
+}
+
+void sad_deinit_mac(struct mac_data *mac_data)
+{
+       free(mac_data->context);
+       free(mac_data);
+}
+
+int sad_hash(struct mac_data *mac_data,
+            const void *data, int data_len,
+            unsigned char *mac, int mac_len)
+{
+       int digest_len;
+
+       /* verify data and mac length */
+       if (data_len < 0 || mac_len < 0) {
+               return 0;
+       }
+
+       /* confirm mac length is within library support */
+       digest_len = mac_data->nettle_mac->digest_size;
+       if (mac_len > digest_len) {
+               mac_len = digest_len;
+       }
+
+       if (mac_len > MAX_DIGEST_LENGTH) {
+               return 0;
+       }
+
+       /* update data and retrieve mac */
+       mac_data->nettle_mac->update(mac_data->context, data_len, data);
+       mac_data->nettle_mac->digest(mac_data->context, mac_len, mac);
+
+       return mac_len;
+}
diff --git a/sad_private.h b/sad_private.h
index 141970c..8e39bc2 100644
--- a/sad_private.h
+++ b/sad_private.h
@@ -19,6 +19,8 @@
 #ifndef HAVE_SAD_PRIVATE_H
 #define HAVE_SAD_PRIVATE_H
 
+#define MAX_DIGEST_LENGTH 32
+
 #include <sys/queue.h>
 
 #include "pdt.h"
@@ -45,6 +47,16 @@ struct security_association_key {
        UInteger32 key_id;        /* symmetric key ID */
 };
 
+#if defined (HAVE_NETTLE)
+int sad_hash(struct mac_data *parms,
+            const void *data, int data_len,
+            unsigned char *mac, int mac_len);
+
+struct mac_data *sad_init_mac(integrity_alg_type algorithm,
+                             const unsigned char *key, int key_len);
+
+void sad_deinit_mac(struct mac_data *parms);
+#else
 int sad_hash(struct mac_data *mac_data,
             const void *data, int data_len,
             unsigned char *mac, int mac_len)
@@ -65,5 +77,6 @@ void sad_deinit_mac(struct mac_data *mac_data)
        pr_debug("security configured but not supported");
        return;
 }
+#endif
 
 #endif
-- 
2.42.1



_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to