Cumulative patch from commit 3f56a2b7460a57a2b68b48b936be134bf04aa36d

3f56a2b Ignore pmf=1 default if driver does not support PMF
fa38860 nl80211: Fix build with libnl 1.1
937403b Update copyright notices for the new year 2015
399e613 Add Suite B AKMs to key_mgmt capability list
5e3b519 Add Suite B 192-bit AKM
97ae35a Add HMAC-SHA384
98cd3d1 Preparations for variable length KCK and KEK
30bff1d Extend AES-CMAC routines to support 256-bit keys
86f9b1c nl80211: Fix default group key management index configuration
b5f045d Show supported group_mgmt capabilities
893e152 Interworking: More debug messages
f45bae5 Interworking: Add logging to track nai_realm_find_eap failures
5a5aab7 Interworking: Remove unnecessary NULL check
400de9b hostapd: Debug messages for dodgy RADIUS servers
ad905e4 wpa_gui: Sort frequency and signal numerically in the scan results dialog
c35e35e Add passive_scan configuration parameter
bff162a P2P: Fix NULL pointer dereference with SD query cancellation
630b323 nl80211: Increase netlink receive buffer size

Change-Id: I32d4bd934ad76e24c646e9925bb839b1ba2a148e
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/crypto/aes-omac1.c b/src/crypto/aes-omac1.c
index c2b0686..375db57 100644
--- a/src/crypto/aes-omac1.c
+++ b/src/crypto/aes-omac1.c
@@ -1,5 +1,5 @@
 /*
- * One-key CBC MAC (OMAC1) hash with AES-128
+ * One-key CBC MAC (OMAC1) hash with AES
  *
  * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
  *
@@ -27,8 +27,9 @@
 
 
 /**
- * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128
- * @key: 128-bit key for the hash operation
+ * omac1_aes_vector - One-Key CBC MAC (OMAC1) hash with AES
+ * @key: Key for the hash operation
+ * @key_len: Key length in octets
  * @num_elem: Number of elements in the data vector
  * @addr: Pointers to the data areas
  * @len: Lengths of the data blocks
@@ -39,15 +40,15 @@
  * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
  * (SP) 800-38B.
  */
-int omac1_aes_128_vector(const u8 *key, size_t num_elem,
-			 const u8 *addr[], const size_t *len, u8 *mac)
+int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
+		     const u8 *addr[], const size_t *len, u8 *mac)
 {
 	void *ctx;
 	u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
 	const u8 *pos, *end;
 	size_t i, e, left, total_len;
 
-	ctx = aes_encrypt_init(key, 16);
+	ctx = aes_encrypt_init(key, key_len);
 	if (ctx == NULL)
 		return -1;
 	os_memset(cbc, 0, AES_BLOCK_SIZE);
@@ -114,6 +115,26 @@
 
 
 /**
+ * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128
+ * @key: 128-bit key for the hash operation
+ * @num_elem: Number of elements in the data vector
+ * @addr: Pointers to the data areas
+ * @len: Lengths of the data blocks
+ * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
+ * Returns: 0 on success, -1 on failure
+ *
+ * This is a mode for using block cipher (AES in this case) for authentication.
+ * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
+ * (SP) 800-38B.
+ */
+int omac1_aes_128_vector(const u8 *key, size_t num_elem,
+			 const u8 *addr[], const size_t *len, u8 *mac)
+{
+	return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
+}
+
+
+/**
  * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
  * @key: 128-bit key for the hash operation
  * @data: Data buffer for which a MAC is determined
@@ -129,3 +150,21 @@
 {
 	return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
 }
+
+
+/**
+ * omac1_aes_256 - One-Key CBC MAC (OMAC1) hash with AES-256 (aka AES-CMAC)
+ * @key: 256-bit key for the hash operation
+ * @data: Data buffer for which a MAC is determined
+ * @data_len: Length of data buffer in bytes
+ * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
+ * Returns: 0 on success, -1 on failure
+ *
+ * This is a mode for using block cipher (AES in this case) for authentication.
+ * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
+ * (SP) 800-38B.
+ */
+int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
+{
+	return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
+}
diff --git a/src/crypto/aes_wrap.h b/src/crypto/aes_wrap.h
index 6b3727c..4a14209 100644
--- a/src/crypto/aes_wrap.h
+++ b/src/crypto/aes_wrap.h
@@ -2,7 +2,7 @@
  * AES-based functions
  *
  * - AES Key Wrap Algorithm (RFC3394)
- * - One-Key CBC MAC (OMAC1) hash with AES-128
+ * - One-Key CBC MAC (OMAC1) hash with AES-128 and AES-256
  * - AES-128 CTR mode encryption
  * - AES-128 EAX mode encryption/decryption
  * - AES-128 CBC
@@ -22,11 +22,16 @@
 			  u8 *cipher);
 int __must_check aes_unwrap(const u8 *kek, size_t kek_len, int n,
 			    const u8 *cipher, u8 *plain);
+int __must_check omac1_aes_vector(const u8 *key, size_t key_len,
+				  size_t num_elem, const u8 *addr[],
+				  const size_t *len, u8 *mac);
 int __must_check omac1_aes_128_vector(const u8 *key, size_t num_elem,
 				      const u8 *addr[], const size_t *len,
 				      u8 *mac);
 int __must_check omac1_aes_128(const u8 *key, const u8 *data, size_t data_len,
 			       u8 *mac);
+int __must_check omac1_aes_256(const u8 *key, const u8 *data, size_t data_len,
+			       u8 *mac);
 int __must_check aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out);
 int __must_check aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
 				     u8 *data, size_t data_len);
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index adb42a4..f79055c 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -1,6 +1,6 @@
 /*
  * Wrapper functions for OpenSSL libcrypto
- * Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -28,6 +28,7 @@
 #include "dh_group5.h"
 #include "sha1.h"
 #include "sha256.h"
+#include "sha384.h"
 #include "crypto.h"
 
 #if OPENSSL_VERSION_NUMBER < 0x00907000
@@ -786,6 +787,40 @@
 #endif /* CONFIG_SHA256 */
 
 
+#ifdef CONFIG_SHA384
+
+int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
+		       const u8 *addr[], const size_t *len, u8 *mac)
+{
+	HMAC_CTX ctx;
+	size_t i;
+	unsigned int mdlen;
+	int res;
+
+	HMAC_CTX_init(&ctx);
+	if (HMAC_Init_ex(&ctx, key, key_len, EVP_sha384(), NULL) != 1)
+		return -1;
+
+	for (i = 0; i < num_elem; i++)
+		HMAC_Update(&ctx, addr[i], len[i]);
+
+	mdlen = 32;
+	res = HMAC_Final(&ctx, mac, &mdlen);
+	HMAC_CTX_cleanup(&ctx);
+
+	return res == 1 ? 0 : -1;
+}
+
+
+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);
+}
+
+#endif /* CONFIG_SHA384 */
+
+
 int crypto_get_random(void *buf, size_t len)
 {
 	if (RAND_bytes(buf, len) != 1)
@@ -795,8 +830,8 @@
 
 
 #ifdef CONFIG_OPENSSL_CMAC
-int omac1_aes_128_vector(const u8 *key, size_t num_elem,
-			 const u8 *addr[], const size_t *len, u8 *mac)
+int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
+		     const u8 *addr[], const size_t *len, u8 *mac)
 {
 	CMAC_CTX *ctx;
 	int ret = -1;
@@ -806,8 +841,15 @@
 	if (ctx == NULL)
 		return -1;
 
-	if (!CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL))
+	if (key_len == 32) {
+		if (!CMAC_Init(ctx, key, 32, EVP_aes_256_cbc(), NULL))
+			goto fail;
+	} else if (key_len == 16) {
+		if (!CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL))
+			goto fail;
+	} else {
 		goto fail;
+	}
 	for (i = 0; i < num_elem; i++) {
 		if (!CMAC_Update(ctx, addr[i], len[i]))
 			goto fail;
@@ -822,10 +864,23 @@
 }
 
 
+int omac1_aes_128_vector(const u8 *key, size_t num_elem,
+			 const u8 *addr[], const size_t *len, u8 *mac)
+{
+	return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
+}
+
+
 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
 {
 	return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
 }
+
+
+int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
+{
+	return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
+}
 #endif /* CONFIG_OPENSSL_CMAC */
 
 
diff --git a/src/crypto/sha384.h b/src/crypto/sha384.h
new file mode 100644
index 0000000..e6a1fe4
--- /dev/null
+++ b/src/crypto/sha384.h
@@ -0,0 +1,19 @@
+/*
+ * SHA384 hash implementation and interface functions
+ * Copyright (c) 2015, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef SHA384_H
+#define SHA384_H
+
+#define SHA384_MAC_LEN 48
+
+int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
+		       const u8 *addr[], const size_t *len, u8 *mac);
+int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
+		size_t data_len, u8 *mac);
+
+#endif /* SHA384_H */