From patchwork Fri Feb 3 19:25:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 93317 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp740059qgi; Fri, 3 Feb 2017 11:26:25 -0800 (PST) X-Received: by 10.98.100.69 with SMTP id y66mr19833617pfb.174.1486149985892; Fri, 03 Feb 2017 11:26:25 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s19si26278317pfd.78.2017.02.03.11.26.25; Fri, 03 Feb 2017 11:26:25 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-wireless-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-wireless-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752067AbdBCT0Y (ORCPT + 1 other); Fri, 3 Feb 2017 14:26:24 -0500 Received: from mail-wm0-f50.google.com ([74.125.82.50]:34231 "EHLO mail-wm0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752012AbdBCT0W (ORCPT ); Fri, 3 Feb 2017 14:26:22 -0500 Received: by mail-wm0-f50.google.com with SMTP id 196so17449733wmm.1 for ; Fri, 03 Feb 2017 11:26:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Ia1C1UW3GLYLySXjo0I9+iug7I/2Ok3GLTpLxDLzGBk=; b=FSHE85g0GZx+R7lgmkM33AdQ1wdbJ+81TVQGOLUN9mD23JpEkUUowxht8RFcLUIN35 lFRKKsyOcY8qe4odhLTFwBJC5kJQpVcgoqDJTd3i37PgWRYaHQJaQmUomkZ1JL4sBB2z e2hLxFDpbFLlloxMTrHdVnlLmMFX+YBblSYwI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Ia1C1UW3GLYLySXjo0I9+iug7I/2Ok3GLTpLxDLzGBk=; b=uHiF2SwVDiHehuI1g28WAqw7456ttZgZdmMcz10HH356TPDDKP/dUjIwpxn+5tOtR9 8yrwhZCKuNbQkm09S7QN2BfI9oAHXRbMb9ueSdqNtM1E45sRGAFZW9lo0SZa82KvMP9Q 5xd8NgNQaBJTM12XjKqwSITo2g1MrJdahi+eD2mIij/S+S8kyBsvcdfLGRpg7LNHDVfy mXqctFsYFdIfCl78DiTlj0fna166HZ7rVS+P6+SAC9fY81xYfiMYgGZncRd0IPVchyVB 6ED9rq3cfTfLVEWmYJVlKhOcDPFrnxUXSjK6FeIV+g+e6SUhht2rX1VliATJGglzDZ2L 0dww== X-Gm-Message-State: AMke39mWshhEDaIP3FGlts0u36YC/vXMACYxzHZsUU0vBvu72vTd3yu8G+Q2DcQJxIHdEE+K X-Received: by 10.28.45.213 with SMTP id t204mr2781606wmt.113.1486149980942; Fri, 03 Feb 2017 11:26:20 -0800 (PST) Received: from localhost.localdomain ([197.130.95.80]) by smtp.gmail.com with ESMTPSA id 17sm46598030wru.16.2017.02.03.11.26.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 03 Feb 2017 11:26:20 -0800 (PST) From: Ard Biesheuvel To: johannes@sipsolutions.net, linux-wireless@vger.kernel.org Cc: davem@davemloft.net, netdev@vger.kernel.org, jouni@qca.qualcomm.com, Ard Biesheuvel Subject: [RFC PATCH 1/2] mac80211: fils_aead: clone shared CMAC functions into private version Date: Fri, 3 Feb 2017 19:25:54 +0000 Message-Id: <1486149955-11825-2-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1486149955-11825-1-git-send-email-ard.biesheuvel@linaro.org> References: <1486149955-11825-1-git-send-email-ard.biesheuvel@linaro.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Before reworking the AES CMAC mac80211 code, clone the routines that it shares with the FILS AEAD driver into its own source file, and remove the external declaration from aes_cmac.h. This will allow us to carry over one user at a time from the open coded CMAC code to the crypto API. Signed-off-by: Ard Biesheuvel --- net/mac80211/aes_cmac.h | 4 -- net/mac80211/fils_aead.c | 68 ++++++++++++++++++++ 2 files changed, 68 insertions(+), 4 deletions(-) -- 2.7.4 diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h index c827e1d5de8b..3702041f44fd 100644 --- a/net/mac80211/aes_cmac.h +++ b/net/mac80211/aes_cmac.h @@ -11,10 +11,6 @@ #include -void gf_mulx(u8 *pad); -void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem, - const u8 *addr[], const size_t *len, u8 *mac, - size_t mac_len); struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], size_t key_len); void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, diff --git a/net/mac80211/fils_aead.c b/net/mac80211/fils_aead.c index ecfdd97758a3..ec493e68957c 100644 --- a/net/mac80211/fils_aead.c +++ b/net/mac80211/fils_aead.c @@ -15,6 +15,74 @@ #include "aes_cmac.h" #include "fils_aead.h" +static void gf_mulx(u8 *pad) +{ + int i, carry; + + carry = pad[0] & 0x80; + for (i = 0; i < AES_BLOCK_SIZE - 1; i++) + pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); + pad[AES_BLOCK_SIZE - 1] <<= 1; + if (carry) + pad[AES_BLOCK_SIZE - 1] ^= 0x87; +} + +static void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem, + const u8 *addr[], const size_t *len, u8 *mac, + size_t mac_len) +{ + u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE]; + const u8 *pos, *end; + size_t i, e, left, total_len; + + memset(cbc, 0, AES_BLOCK_SIZE); + + total_len = 0; + for (e = 0; e < num_elem; e++) + total_len += len[e]; + left = total_len; + + e = 0; + pos = addr[0]; + end = pos + len[0]; + + while (left >= AES_BLOCK_SIZE) { + for (i = 0; i < AES_BLOCK_SIZE; i++) { + cbc[i] ^= *pos++; + if (pos >= end) { + e++; + pos = addr[e]; + end = pos + len[e]; + } + } + if (left > AES_BLOCK_SIZE) + crypto_cipher_encrypt_one(tfm, cbc, cbc); + left -= AES_BLOCK_SIZE; + } + + memset(pad, 0, AES_BLOCK_SIZE); + crypto_cipher_encrypt_one(tfm, pad, pad); + gf_mulx(pad); + + if (left || total_len == 0) { + for (i = 0; i < left; i++) { + cbc[i] ^= *pos++; + if (pos >= end) { + e++; + pos = addr[e]; + end = pos + len[e]; + } + } + cbc[left] ^= 0x80; + gf_mulx(pad); + } + + for (i = 0; i < AES_BLOCK_SIZE; i++) + pad[i] ^= cbc[i]; + crypto_cipher_encrypt_one(tfm, pad, pad); + memcpy(mac, pad, mac_len); +} + static int aes_s2v(struct crypto_cipher *tfm, size_t num_elem, const u8 *addr[], size_t len[], u8 *v) { From patchwork Fri Feb 3 19:25:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 93318 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp740086qgi; Fri, 3 Feb 2017 11:26:29 -0800 (PST) X-Received: by 10.84.231.143 with SMTP id g15mr23412476plk.1.1486149989655; Fri, 03 Feb 2017 11:26:29 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s19si26278317pfd.78.2017.02.03.11.26.29; Fri, 03 Feb 2017 11:26:29 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-wireless-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-wireless-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752078AbdBCT01 (ORCPT + 1 other); Fri, 3 Feb 2017 14:26:27 -0500 Received: from mail-wm0-f45.google.com ([74.125.82.45]:35512 "EHLO mail-wm0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752058AbdBCT0Z (ORCPT ); Fri, 3 Feb 2017 14:26:25 -0500 Received: by mail-wm0-f45.google.com with SMTP id b65so44495828wmf.0 for ; Fri, 03 Feb 2017 11:26:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TXN7hHPhwwqFEU8qwLECV/1rgYypqL/8UmhzwDQXWMk=; b=axsTOsDwkJ3LjTvGtHMNKEO+5+lkniawGjIPvkWxHlXk/RqfS2UI5XBvD3HSPiK1hv zTJ5OsWvvnnmrd31g5XEmvMX57dTCUtr7clBl1MuQUTcfnALQlQxp/5oRgw6hxWpR0sF JopVoFjgabiJ4L+0KGztVHIUQ8TO+oEy6Q1+U= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TXN7hHPhwwqFEU8qwLECV/1rgYypqL/8UmhzwDQXWMk=; b=qr1RDqHthFM+w0t0+bw0ktNAOR6cO3QxhZO+d126AsoC8mQ3Q2NpZ5Ap+qvfjufn1s AEgJLmzKMbz8FFUsgBtXzJODRpZochjXim63M0qvg6uN3X3Yz6FisVpRo197+YxSVPek 8mvWQm7xN4tW2tFFx0IVNYsIP081MNomMoSCvNCs+qPqZunThKm1atL5959YMEnELqij sdDksuQIvH+WbBUbfJEY2U/L5bSYA/4Lwt1UgJrdnBn52jvE8eWqnyIPw0ygyVvtsO0y 65q/YI5fXIja77E+xnfB7M5PxFSJDN6sq9E8Q3UMAUJzPmMkWuP6q4aPGzcwDH+yZ/Sm cRrQ== X-Gm-Message-State: AMke39lFxG7t+2xTm72rXI85HD3wvdqk9mr/WgAr1WdsAmgfPO5ppzTWt5Zfea9iU7PrA4qC X-Received: by 10.28.211.200 with SMTP id k191mr2636370wmg.137.1486149983555; Fri, 03 Feb 2017 11:26:23 -0800 (PST) Received: from localhost.localdomain ([197.130.95.80]) by smtp.gmail.com with ESMTPSA id 17sm46598030wru.16.2017.02.03.11.26.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 03 Feb 2017 11:26:23 -0800 (PST) From: Ard Biesheuvel To: johannes@sipsolutions.net, linux-wireless@vger.kernel.org Cc: davem@davemloft.net, netdev@vger.kernel.org, jouni@qca.qualcomm.com, Ard Biesheuvel Subject: [RFC PATCH 2/2] mac80211: aes-cmac: switch to shash CMAC driver Date: Fri, 3 Feb 2017 19:25:55 +0000 Message-Id: <1486149955-11825-3-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1486149955-11825-1-git-send-email-ard.biesheuvel@linaro.org> References: <1486149955-11825-1-git-send-email-ard.biesheuvel@linaro.org> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Instead of open coding the CMAC algorithm in the mac80211 driver using byte wide xors and calls into the crypto layer for each block of data, instantiate a cmac(aes) synchronous hash and pass all the data into it directly. This does not only simplify the code, it also allows the use of more efficient and more secure implementations, especially on platforms where SIMD ciphers have considerable setup time. Signed-off-by: Ard Biesheuvel --- net/mac80211/Kconfig | 1 + net/mac80211/aes_cmac.c | 137 +++++--------------- net/mac80211/aes_cmac.h | 11 +- net/mac80211/key.h | 2 +- 4 files changed, 42 insertions(+), 109 deletions(-) -- 2.7.4 diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 3891cbd2adea..76e30f4797fb 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -6,6 +6,7 @@ config MAC80211 select CRYPTO_AES select CRYPTO_CCM select CRYPTO_GCM + select CRYPTO_CMAC select CRC32 ---help--- This option enables the hardware independent IEEE 802.11 diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c index d0bd5fff5f0a..fc004720e77c 100644 --- a/net/mac80211/aes_cmac.c +++ b/net/mac80211/aes_cmac.c @@ -22,126 +22,57 @@ #define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */ #define AAD_LEN 20 +static const u8 zero[CMAC_TLEN_256]; -void gf_mulx(u8 *pad) +void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, + const u8 *data, size_t data_len, u8 *mic) { - int i, carry; - - carry = pad[0] & 0x80; - for (i = 0; i < AES_BLOCK_SIZE - 1; i++) - pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); - pad[AES_BLOCK_SIZE - 1] <<= 1; - if (carry) - pad[AES_BLOCK_SIZE - 1] ^= 0x87; -} + struct shash_desc *desc; + u8 buf[sizeof(*desc) + crypto_shash_descsize(tfm)] CRYPTO_MINALIGN_ATTR; + u8 out[crypto_shash_digestsize(tfm)]; -void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem, - const u8 *addr[], const size_t *len, u8 *mac, - size_t mac_len) -{ - u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE]; - const u8 *pos, *end; - size_t i, e, left, total_len; - - memset(cbc, 0, AES_BLOCK_SIZE); - - total_len = 0; - for (e = 0; e < num_elem; e++) - total_len += len[e]; - left = total_len; - - e = 0; - pos = addr[0]; - end = pos + len[0]; - - while (left >= AES_BLOCK_SIZE) { - for (i = 0; i < AES_BLOCK_SIZE; i++) { - cbc[i] ^= *pos++; - if (pos >= end) { - e++; - pos = addr[e]; - end = pos + len[e]; - } - } - if (left > AES_BLOCK_SIZE) - crypto_cipher_encrypt_one(tfm, cbc, cbc); - left -= AES_BLOCK_SIZE; - } - - memset(pad, 0, AES_BLOCK_SIZE); - crypto_cipher_encrypt_one(tfm, pad, pad); - gf_mulx(pad); - - if (left || total_len == 0) { - for (i = 0; i < left; i++) { - cbc[i] ^= *pos++; - if (pos >= end) { - e++; - pos = addr[e]; - end = pos + len[e]; - } - } - cbc[left] ^= 0x80; - gf_mulx(pad); - } - - for (i = 0; i < AES_BLOCK_SIZE; i++) - pad[i] ^= cbc[i]; - crypto_cipher_encrypt_one(tfm, pad, pad); - memcpy(mac, pad, mac_len); -} + desc = (struct shash_desc *)buf; + desc->tfm = tfm; + crypto_shash_init(desc); + crypto_shash_update(desc, aad, AAD_LEN); + crypto_shash_update(desc, data, data_len - CMAC_TLEN); + crypto_shash_finup(desc, zero, CMAC_TLEN, out); -void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, - const u8 *data, size_t data_len, u8 *mic) -{ - const u8 *addr[3]; - size_t len[3]; - u8 zero[CMAC_TLEN]; - - memset(zero, 0, CMAC_TLEN); - addr[0] = aad; - len[0] = AAD_LEN; - addr[1] = data; - len[1] = data_len - CMAC_TLEN; - addr[2] = zero; - len[2] = CMAC_TLEN; - - aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN); + memcpy(mic, out, CMAC_TLEN); } -void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad, +void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, const u8 *data, size_t data_len, u8 *mic) { - const u8 *addr[3]; - size_t len[3]; - u8 zero[CMAC_TLEN_256]; - - memset(zero, 0, CMAC_TLEN_256); - addr[0] = aad; - len[0] = AAD_LEN; - addr[1] = data; - len[1] = data_len - CMAC_TLEN_256; - addr[2] = zero; - len[2] = CMAC_TLEN_256; - - aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN_256); + struct shash_desc *desc; + u8 buf[sizeof(*desc) + crypto_shash_descsize(tfm)] CRYPTO_MINALIGN_ATTR; + u8 out[crypto_shash_digestsize(tfm)]; + + desc = (struct shash_desc *)buf; + desc->tfm = tfm; + + crypto_shash_init(desc); + crypto_shash_update(desc, aad, AAD_LEN); + crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); + crypto_shash_finup(desc, zero, CMAC_TLEN_256, out); + + memcpy(mic, out, CMAC_TLEN_256); } -struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], - size_t key_len) +struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], + size_t key_len) { - struct crypto_cipher *tfm; + struct crypto_shash *tfm; - tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); + tfm = crypto_alloc_shash("cmac(aes)", 0, 0); if (!IS_ERR(tfm)) - crypto_cipher_setkey(tfm, key, key_len); + crypto_shash_setkey(tfm, key, key_len); return tfm; } - -void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm) +void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm) { - crypto_free_cipher(tfm); + crypto_free_shash(tfm); } diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h index 3702041f44fd..fef531f42003 100644 --- a/net/mac80211/aes_cmac.h +++ b/net/mac80211/aes_cmac.h @@ -10,13 +10,14 @@ #define AES_CMAC_H #include +#include -struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], - size_t key_len); -void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, +struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], + size_t key_len); +void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, const u8 *data, size_t data_len, u8 *mic); -void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad, +void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, const u8 *data, size_t data_len, u8 *mic); -void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); +void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm); #endif /* AES_CMAC_H */ diff --git a/net/mac80211/key.h b/net/mac80211/key.h index 4aa20cef0859..ebdb80b85dc3 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h @@ -93,7 +93,7 @@ struct ieee80211_key { } ccmp; struct { u8 rx_pn[IEEE80211_CMAC_PN_LEN]; - struct crypto_cipher *tfm; + struct crypto_shash *tfm; u32 replays; /* dot11RSNAStatsCMACReplays */ u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ } aes_cmac;