]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add HMAC-SHA384 with internal crypto
authorJouni Malinen <j@w1.fi>
Thu, 16 Feb 2017 18:37:19 +0000 (20:37 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 16 Feb 2017 20:15:29 +0000 (22:15 +0200)
This is a copy of the internal HMAC-SHA256 implementation with the hash
block size and output length updated to match SHA384 parameters.

Signed-off-by: Jouni Malinen <j@w1.fi>
hostapd/Android.mk
hostapd/Makefile
src/crypto/sha384.c [new file with mode: 0644]
wpa_supplicant/Android.mk
wpa_supplicant/Makefile

index 2c5925b8624e86eccd391693645efd0eba001b13..2118c8b0c4d691da62e65cc189a9746b2f6616cb 100644 (file)
@@ -836,6 +836,9 @@ endif
 endif
 ifdef NEED_SHA384
 L_CFLAGS += -DCONFIG_SHA384
+ifneq ($(CONFIG_TLS), openssl)
+OBJS += src/crypto/sha384.c
+endif
 OBJS += src/crypto/sha384-prf.c
 endif
 
index 75d841ec7d25232f563d4704f6cc95abd51c012c..d4dde89d7df181e25febb4fc67cbcc1a8ba6f257 100644 (file)
@@ -875,6 +875,9 @@ endif
 endif
 ifdef NEED_SHA384
 CFLAGS += -DCONFIG_SHA384
+ifneq ($(CONFIG_TLS), openssl)
+OBJS += ../src/crypto/sha384.o
+endif
 OBJS += ../src/crypto/sha384-prf.o
 endif
 
diff --git a/src/crypto/sha384.c b/src/crypto/sha384.c
new file mode 100644 (file)
index 0000000..ee136ce
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * SHA-384 hash implementation and interface functions
+ * Copyright (c) 2003-2017, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "sha384.h"
+#include "crypto.h"
+
+
+/**
+ * hmac_sha384_vector - HMAC-SHA384 over data vector (RFC 2104)
+ * @key: Key for HMAC operations
+ * @key_len: Length of the key in bytes
+ * @num_elem: Number of elements in the data vector
+ * @addr: Pointers to the data areas
+ * @len: Lengths of the data blocks
+ * @mac: Buffer for the hash (48 bytes)
+ * Returns: 0 on success, -1 on failure
+ */
+int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
+                      const u8 *addr[], const size_t *len, u8 *mac)
+{
+       unsigned char k_pad[128]; /* padding - key XORd with ipad/opad */
+       unsigned char tk[48];
+       const u8 *_addr[6];
+       size_t _len[6], i;
+
+       if (num_elem > 5) {
+               /*
+                * Fixed limit on the number of fragments to avoid having to
+                * allocate memory (which could fail).
+                */
+               return -1;
+       }
+
+       /* if key is longer than 128 bytes reset it to key = SHA384(key) */
+       if (key_len > 128) {
+               if (sha384_vector(1, &key, &key_len, tk) < 0)
+                       return -1;
+               key = tk;
+               key_len = 48;
+       }
+
+       /* the HMAC_SHA384 transform looks like:
+        *
+        * SHA384(K XOR opad, SHA384(K XOR ipad, text))
+        *
+        * where K is an n byte key
+        * ipad is the byte 0x36 repeated 128 times
+        * opad is the byte 0x5c repeated 128 times
+        * and text is the data being protected */
+
+       /* start out by storing key in ipad */
+       os_memset(k_pad, 0, sizeof(k_pad));
+       os_memcpy(k_pad, key, key_len);
+       /* XOR key with ipad values */
+       for (i = 0; i < 128; i++)
+               k_pad[i] ^= 0x36;
+
+       /* perform inner SHA384 */
+       _addr[0] = k_pad;
+       _len[0] = 128;
+       for (i = 0; i < num_elem; i++) {
+               _addr[i + 1] = addr[i];
+               _len[i + 1] = len[i];
+       }
+       if (sha384_vector(1 + num_elem, _addr, _len, mac) < 0)
+               return -1;
+
+       os_memset(k_pad, 0, sizeof(k_pad));
+       os_memcpy(k_pad, key, key_len);
+       /* XOR key with opad values */
+       for (i = 0; i < 128; i++)
+               k_pad[i] ^= 0x5c;
+
+       /* perform outer SHA384 */
+       _addr[0] = k_pad;
+       _len[0] = 128;
+       _addr[1] = mac;
+       _len[1] = SHA384_MAC_LEN;
+       return sha384_vector(2, _addr, _len, mac);
+}
+
+
+/**
+ * hmac_sha384 - HMAC-SHA384 over data buffer (RFC 2104)
+ * @key: Key for HMAC operations
+ * @key_len: Length of the key in bytes
+ * @data: Pointers to the data area
+ * @data_len: Length of the data area
+ * @mac: Buffer for the hash (48 bytes)
+ * Returns: 0 on success, -1 on failure
+ */
+int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
+               size_t data_len, u8 *mac)
+{
+       return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
+}
index 9ff9b99896242e2444da6496031944cf6d43cc0f..f150ef2bfabe266fa8aed4a36d10b5c81e41e44d 100644 (file)
@@ -1285,6 +1285,9 @@ OBJS += $(SHA256OBJS)
 endif
 ifdef NEED_SHA384
 L_CFLAGS += -DCONFIG_SHA384
+ifneq ($(CONFIG_TLS), openssl)
+OBJS += src/crypto/sha384.c
+endif
 OBJS += src/crypto/sha384-prf.c
 endif
 
index 4455dca1ab109f5b0c7a81220ad84be1f3f1b9fd..91ea4d294278fc5ddd1949ec006b07c4a9e7b4f0 100644 (file)
@@ -1330,6 +1330,9 @@ endif
 OBJS += $(SHA256OBJS)
 endif
 ifdef NEED_SHA384
+ifneq ($(CONFIG_TLS), openssl)
+OBJS += ../src/crypto/sha384.o
+endif
 CFLAGS += -DCONFIG_SHA384
 OBJS += ../src/crypto/sha384-prf.o
 endif