From 1ee81e5854e05d13e2820a7585eccd7acf5ece82 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 27 Dec 2014 23:20:28 +0100 Subject: [PATCH] core: Add support for AES-CMAC hashing function --- Makefile.am | 1 + src/aes.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/aes.h | 26 +++++++++++ 3 files changed, 157 insertions(+) create mode 100644 src/aes.c create mode 100644 src/aes.h diff --git a/Makefile.am b/Makefile.am index 45faa670..28b4e54e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -43,6 +43,7 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h linux/kdbus.h \ src/kdbus.h src/kdbus.c \ src/netdev.h src/netdev.c \ src/wiphy.h src/wiphy.c \ + src/aes.h src/aes.c \ src/md5.h src/md5.c \ src/sha1.h src/sha1.c \ src/sha256.h src/sha256.c \ diff --git a/src/aes.c b/src/aes.c new file mode 100644 index 00000000..e6ad5230 --- /dev/null +++ b/src/aes.c @@ -0,0 +1,130 @@ +/* + * + * Wireless daemon for Linux + * + * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _GNU_SOURCE +#include +#include +#include +#include + +#ifndef PF_ALG +#include + +struct sockaddr_alg { + __u16 salg_family; + __u8 salg_type[14]; + __u32 salg_feat; + __u32 salg_mask; + __u8 salg_name[64]; +}; + +#define ALG_SET_KEY 1 + +#define PF_ALG 38 /* Algorithm sockets. */ +#define AF_ALG PF_ALG +#else +#include +#endif + +#ifndef SOL_ALG +#define SOL_ALG 279 +#endif + +#include "src/aes.h" + +/* Maximum message length that can be passed to aes_cmac */ +#define CMAC_MSG_MAX 80 + +static int cmac_aes_setup(void) +{ + struct sockaddr_alg salg; + int fd; + + fd = socket(PF_ALG, SOCK_SEQPACKET | SOCK_CLOEXEC, 0); + if (fd < 0) + return -1; + + memset(&salg, 0, sizeof(salg)); + salg.salg_family = AF_ALG; + strcpy((char *) salg.salg_type, "hash"); + strcpy((char *) salg.salg_name, "cmac(aes)"); + + if (bind(fd, (struct sockaddr *) &salg, sizeof(salg)) < 0) { + close(fd); + return -1; + } + + return fd; +} + +static int alg_new(int fd, const void *keyval, socklen_t keylen) +{ + if (setsockopt(fd, SOL_ALG, ALG_SET_KEY, keyval, keylen) < 0) + return -1; + + return accept4(fd, NULL, 0, SOCK_CLOEXEC); +} + +bool cmac_aes(const void *key, size_t key_len, + const void *msg, size_t msg_len, void *tag, size_t size) +{ + ssize_t len; + int fd, alg_fd; + bool result; + + if (msg_len > CMAC_MSG_MAX) + return false; + + alg_fd = cmac_aes_setup(); + if (alg_fd < 0) + return false; + + fd = alg_new(alg_fd, key, key_len); + if (fd < 0) { + close(alg_fd); + return false; + } + + len = send(fd, msg, msg_len, 0); + if (len < 0) { + result = false; + goto done; + } + + len = read(fd, tag, size); + if (len < 0) { + result = false; + goto done; + } + + result = true; + +done: + close(fd); + close(alg_fd); + + return result; +} diff --git a/src/aes.h b/src/aes.h new file mode 100644 index 00000000..0bfb347d --- /dev/null +++ b/src/aes.h @@ -0,0 +1,26 @@ +/* + * + * Wireless daemon for Linux + * + * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +bool cmac_aes(const void *key, size_t key_len, + const void *msg, size_t msg_len, void *tag, size_t size);