From 872c0e803a95b9211f55cd4c8d6af09424343fcb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 27 Dec 2014 06:58:28 +0100 Subject: [PATCH] core: Add support for HMAC SHA256 helper function --- Makefile.am | 1 + src/sha256.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/sha256.h | 26 +++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 src/sha256.c create mode 100644 src/sha256.h diff --git a/Makefile.am b/Makefile.am index 8cb3b37c..e7e13c51 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,6 +45,7 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h linux/kdbus.h \ src/wiphy.h src/wiphy.c \ src/md5.h src/md5.c \ src/sha1.h src/sha1.c \ + src/sha256.h src/sha256.c \ src/ie.h src/ie.c \ src/dbus.h src/dbus.c \ src/manager.h src/manager.c \ diff --git a/src/sha256.c b/src/sha256.c new file mode 100644 index 00000000..de1dffaf --- /dev/null +++ b/src/sha256.c @@ -0,0 +1,93 @@ +/* + * + * 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 + +#include +#include + +#include "src/sha256.h" + +#define SHA256_MAC_LEN 32 + +static void __hmac_sha256(struct l_checksum *checksum, + const void *key, size_t key_len, + const void *data, size_t data_len, void *output) +{ + unsigned char ipad[64]; + unsigned char opad[64]; + unsigned char digest[SHA256_MAC_LEN]; + int i; + + /* if key is longer than 64 bytes reset it to key=SHA256(key) */ + if (key_len > 64) { + l_checksum_update(checksum, key, key_len); + l_checksum_get_digest(checksum, digest, SHA256_MAC_LEN); + + l_checksum_reset(checksum); + + key = digest; + key_len = SHA256_MAC_LEN; + } + + /* start out by storing key in pads */ + memset(ipad, 0, sizeof(ipad)); + memset(opad, 0, sizeof(opad)); + memcpy(ipad, key, key_len); + memcpy(opad, key, key_len); + + /* XOR key with ipad and opad values */ + for (i = 0; i < 64; i++) { + ipad[i] ^= 0x36; + opad[i] ^= 0x5c; + } + + /* perform inner SHA256 */ + l_checksum_update(checksum, ipad, sizeof(ipad)); + l_checksum_update(checksum, data, data_len); + l_checksum_get_digest(checksum, digest, SHA256_MAC_LEN); + + l_checksum_reset(checksum); + + /* perform outer SHA256 */ + l_checksum_update(checksum, opad, sizeof(opad)); + l_checksum_update(checksum, digest, SHA256_MAC_LEN); + l_checksum_get_digest(checksum, output, SHA256_MAC_LEN); + + l_checksum_reset(checksum); +} + +bool hmac_sha256(const void *key, size_t key_len, + const void *data, size_t data_len, void *output, size_t size) +{ + struct l_checksum *checksum; + + checksum = l_checksum_new(L_CHECKSUM_SHA256); + + __hmac_sha256(checksum, key, key_len, data, data_len, output); + + l_checksum_free(checksum); + + return true; +} diff --git a/src/sha256.h b/src/sha256.h new file mode 100644 index 00000000..3faa33d5 --- /dev/null +++ b/src/sha256.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 hmac_sha256(const void *key, size_t key_len, + const void *data, size_t data_len, void *output, size_t size);