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