Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Convert ieee80211_crypto_ccmp.c to new aes_ccm API.
details: https://anonhg.NetBSD.org/src/rev/2d5647e9ac6e
branches: trunk
changeset: 974141:2d5647e9ac6e
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sat Jul 25 22:26:23 2020 +0000
description:
Convert ieee80211_crypto_ccmp.c to new aes_ccm API.
This will make it easier to provide better hardware acceleration
without fpu enabling/disabling overhead for each block of data.
diffstat:
sys/conf/files | 4 +-
sys/net80211/ieee80211_crypto_ccmp.c | 362 +++++++---------------------------
2 files changed, 75 insertions(+), 291 deletions(-)
diffs (truncated from 482 to 300 lines):
diff -r bc04732dba07 -r 2d5647e9ac6e sys/conf/files
--- a/sys/conf/files Sat Jul 25 22:15:55 2020 +0000
+++ b/sys/conf/files Sat Jul 25 22:26:23 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files,v 1.1271 2020/06/29 23:44:01 riastradh Exp $
+# $NetBSD: files,v 1.1272 2020/07/25 22:26:23 riastradh Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
version 20171118
@@ -454,7 +454,7 @@
define ether
define ieee1394
define sppp
-define wlan: rijndael
+define wlan: aes
define crypto
# TPM
diff -r bc04732dba07 -r 2d5647e9ac6e sys/net80211/ieee80211_crypto_ccmp.c
--- a/sys/net80211/ieee80211_crypto_ccmp.c Sat Jul 25 22:15:55 2020 +0000
+++ b/sys/net80211/ieee80211_crypto_ccmp.c Sat Jul 25 22:26:23 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ieee80211_crypto_ccmp.c,v 1.15 2018/09/03 16:29:36 riastradh Exp $ */
+/* $NetBSD: ieee80211_crypto_ccmp.c,v 1.16 2020/07/25 22:26:23 riastradh Exp $ */
/*
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@@ -36,7 +36,7 @@
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_ccmp.c,v 1.7 2005/07/11 03:06:23 sam Exp $");
#endif
#ifdef __NetBSD__
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_ccmp.c,v 1.15 2018/09/03 16:29:36 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_ccmp.c,v 1.16 2020/07/25 22:26:23 riastradh Exp $");
#endif
/*
@@ -60,13 +60,15 @@
#include <net80211/ieee80211_var.h>
-#include <crypto/rijndael/rijndael.h>
+#include <crypto/aes/aes.h>
+#include <crypto/aes/aes_ccm.h>
+#include <crypto/aes/aes_ccm_mbuf.h>
#define AES_BLOCK_LEN 16
struct ccmp_ctx {
struct ieee80211com *cc_ic; /* for diagnostics */
- rijndael_ctx cc_aes;
+ struct aesenc cc_aes;
};
static void *ccmp_attach(struct ieee80211com *, struct ieee80211_key *);
@@ -133,7 +135,7 @@
return 0;
}
if (k->wk_flags & IEEE80211_KEY_SWCRYPT)
- rijndael_set_key(&ctx->cc_aes, k->wk_key, k->wk_keylen*NBBY);
+ aes_setenckey128(&ctx->cc_aes, k->wk_key);
return 1;
}
@@ -287,261 +289,100 @@
*/
static void
-ccmp_init_blocks(rijndael_ctx *ctx, struct ieee80211_frame *wh,
- u_int64_t pn, size_t dlen,
- uint8_t b0[AES_BLOCK_LEN], uint8_t aad[2 * AES_BLOCK_LEN],
- uint8_t auth[AES_BLOCK_LEN], uint8_t s0[AES_BLOCK_LEN])
+ccmp_init_blocks(struct aesenc *ctx, struct ieee80211_frame *wh,
+ u_int64_t pn, size_t data_len, struct aes_ccm *aes_ccm)
{
+ uint8_t nonce[13];
+ uint8_t ad[32];
+ uint8_t qos;
+ size_t adlen;
+
#define IS_4ADDRESS(wh) \
((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
#define IS_QOS_DATA(wh) ieee80211_has_qos(wh)
- /* CCM Initial Block:
- * Flag (Include authentication header, M=3 (8-octet MIC),
- * L=1 (2-octet Dlen))
- * Nonce: 0x00 | A2 | PN
- * Dlen */
- b0[0] = 0x59;
- /* NB: b0[1] set below */
- IEEE80211_ADDR_COPY(b0 + 2, wh->i_addr2);
- b0[8] = pn >> 40;
- b0[9] = pn >> 32;
- b0[10] = pn >> 24;
- b0[11] = pn >> 16;
- b0[12] = pn >> 8;
- b0[13] = pn >> 0;
- b0[14] = (dlen >> 8) & 0xff;
- b0[15] = dlen & 0xff;
+ /* nonce[0] is qos, determined later */
+ IEEE80211_ADDR_COPY(nonce + 1, wh->i_addr2);
+ nonce[7] = pn >> 40;
+ nonce[8] = pn >> 32;
+ nonce[9] = pn >> 24;
+ nonce[10] = pn >> 16;
+ nonce[11] = pn >> 8;
+ nonce[12] = pn >> 0;
- /* AAD:
- * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
- * A1 | A2 | A3
- * SC with bits 4..15 (seq#) masked to zero
- * A4 (if present)
- * QC (if present)
- */
- aad[0] = 0; /* AAD length >> 8 */
- /* NB: aad[1] set below */
- aad[2] = wh->i_fc[0] & 0x8f; /* XXX magic #s */
- aad[3] = wh->i_fc[1] & 0xc7; /* XXX magic #s */
+ ad[0] = wh->i_fc[0] & 0x8f; /* XXX magic #s */
+ ad[1] = wh->i_fc[1] & 0xc7; /* XXX magic #s */
/* NB: we know 3 addresses are contiguous */
- memcpy(aad + 4, wh->i_addr1, 3 * IEEE80211_ADDR_LEN);
- aad[22] = wh->i_seq[0] & IEEE80211_SEQ_FRAG_MASK;
- aad[23] = 0; /* all bits masked */
+ memcpy(ad + 2, wh->i_addr1, 3 * IEEE80211_ADDR_LEN);
+ ad[20] = wh->i_seq[0] & IEEE80211_SEQ_FRAG_MASK;
+ ad[21] = 0; /* all bits masked */
+
/*
* Construct variable-length portion of AAD based
* on whether this is a 4-address frame/QOS frame.
- * We always zero-pad to 32 bytes before running it
- * through the cipher.
*
* We also fill in the priority bits of the CCM
* initial block as we know whether or not we have
* a QOS frame.
*/
if (IS_4ADDRESS(wh)) {
- IEEE80211_ADDR_COPY(aad + 24,
- ((struct ieee80211_frame_addr4 *)wh)->i_addr4);
+ IEEE80211_ADDR_COPY(ad + 22,
+ ((const struct ieee80211_frame_addr4 *)wh)->i_addr4);
if (IS_QOS_DATA(wh)) {
- struct ieee80211_qosframe_addr4 *qwh4 =
- (struct ieee80211_qosframe_addr4 *) wh;
- aad[30] = qwh4->i_qos[0] & 0x0f;/* just priority bits */
- aad[31] = 0;
- b0[1] = aad[30];
- aad[1] = 22 + IEEE80211_ADDR_LEN + 2;
+ const struct ieee80211_qosframe_addr4 *qwh4 =
+ (const struct ieee80211_qosframe_addr4 *)wh;
+ qos = qwh4->i_qos[0] & 0x0f; /* just priority bits */
+ ad[28] = qos;
+ ad[29] = 0;
+ adlen = 22 + IEEE80211_ADDR_LEN + 2;
} else {
- *(u_int16_t *)&aad[30] = 0;
- b0[1] = 0;
- aad[1] = 22 + IEEE80211_ADDR_LEN;
+ qos = 0;
+ adlen = 22 + IEEE80211_ADDR_LEN;
}
} else {
if (IS_QOS_DATA(wh)) {
- struct ieee80211_qosframe *qwh =
- (struct ieee80211_qosframe*) wh;
- aad[24] = qwh->i_qos[0] & 0x0f; /* just priority bits */
- aad[25] = 0;
- b0[1] = aad[24];
- aad[1] = 22 + 2;
+ const struct ieee80211_qosframe *qwh =
+ (const struct ieee80211_qosframe *)wh;
+ qos = qwh->i_qos[0] & 0x0f; /* just priority bits */
+ ad[22] = qos;
+ ad[23] = 0;
+ adlen = 22 + 2;
} else {
- *(u_int16_t *)&aad[24] = 0;
- b0[1] = 0;
- aad[1] = 22;
+ qos = 0;
+ adlen = 22;
}
- *(u_int16_t *)&aad[26] = 0;
- *(u_int32_t *)&aad[28] = 0;
}
+ nonce[0] = qos;
- /* Start with the first block and AAD */
- rijndael_encrypt(ctx, b0, auth);
- xor_block(auth, aad, AES_BLOCK_LEN);
- rijndael_encrypt(ctx, auth, auth);
- xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
- rijndael_encrypt(ctx, auth, auth);
- b0[0] &= 0x07;
- b0[14] = b0[15] = 0;
- rijndael_encrypt(ctx, b0, s0);
+ aes_ccm_init(aes_ccm, AES_128_NROUNDS, ctx, 2 /* L, counter octets */,
+ IEEE80211_WEP_MICLEN, nonce, sizeof nonce, ad, adlen, data_len);
+
#undef IS_QOS_DATA
#undef IS_4ADDRESS
}
-#define CCMP_ENCRYPT(_i, _b, _b0, _pos, _e, _len) do { \
- /* Authentication */ \
- xor_block(_b, _pos, _len); \
- rijndael_encrypt(&ctx->cc_aes, _b, _b); \
- /* Encryption, with counter */ \
- _b0[14] = (_i >> 8) & 0xff; \
- _b0[15] = _i & 0xff; \
- rijndael_encrypt(&ctx->cc_aes, _b0, _e); \
- xor_block(_pos, _e, _len); \
-} while (0)
-
static int
-ccmp_encrypt(struct ieee80211_key *key, struct mbuf *m0, int hdrlen)
+ccmp_encrypt(struct ieee80211_key *key, struct mbuf *m, int hdrlen)
{
struct ccmp_ctx *ctx = key->wk_private;
struct ieee80211_frame *wh;
- struct mbuf *m = m0;
- int data_len, i, space;
- uint8_t aad[2 * AES_BLOCK_LEN], b0[AES_BLOCK_LEN], b[AES_BLOCK_LEN],
- e[AES_BLOCK_LEN], s0[AES_BLOCK_LEN];
- uint8_t *pos;
+ struct aes_ccm aes_ccm;
+ size_t data_len;
+ uint8_t mic[IEEE80211_WEP_MICLEN];
+
+ KASSERT(hdrlen >= 0);
+ KASSERT(hdrlen < m->m_pkthdr.len);
+ KASSERT(ccmp.ic_header <= m->m_pkthdr.len - hdrlen);
ctx->cc_ic->ic_stats.is_crypto_ccmp++;
wh = mtod(m, struct ieee80211_frame *);
data_len = m->m_pkthdr.len - (hdrlen + ccmp.ic_header);
- ccmp_init_blocks(&ctx->cc_aes, wh, key->wk_keytsc,
- data_len, b0, aad, b, s0);
-
- i = 1;
- pos = mtod(m, uint8_t *) + hdrlen + ccmp.ic_header;
- /* NB: assumes header is entirely in first mbuf */
- space = m->m_len - (hdrlen + ccmp.ic_header);
- for (;;) {
- if (space > data_len)
- space = data_len;
-
- /*
- * Do full blocks.
- */
- while (space >= AES_BLOCK_LEN) {
- CCMP_ENCRYPT(i, b, b0, pos, e, AES_BLOCK_LEN);
- pos += AES_BLOCK_LEN, space -= AES_BLOCK_LEN;
- data_len -= AES_BLOCK_LEN;
- i++;
- }
- if (data_len <= 0) /* no more data */
- break;
-
- m = m->m_next;
- if (m == NULL) { /* last buffer */
- if (space != 0) {
- /*
- * Short last block.
- */
- CCMP_ENCRYPT(i, b, b0, pos, e, space);
- }
- break;
- }
- if (space != 0) {
- uint8_t *pos_next;
- int space_next;
- int len, dl, sp;
- struct mbuf *n;
+ ccmp_init_blocks(&ctx->cc_aes, wh, key->wk_keytsc, data_len, &aes_ccm);
+ aes_ccm_enc_mbuf(&aes_ccm, m, hdrlen + ccmp.ic_header, data_len, mic);
- /*
- * Block straddles one or more mbufs, gather data
- * into the block buffer b, apply the cipher, then
- * scatter the results back into the mbuf chain.
- * The buffer will automatically get space bytes
- * of data at offset 0 copied in+out by the
- * CCMP_ENCRYPT request so we must take care of
- * the remaining data.
- */
- n = m;
- dl = data_len;
- sp = space;
- for (;;) {
- pos_next = mtod(n, uint8_t *);
- len = uimin(dl, AES_BLOCK_LEN);
- space_next = len > sp ? len - sp : 0;
- if (n->m_len >= space_next) {
- /*
- * This mbuf has enough data; just grab
Home |
Main Index |
Thread Index |
Old Index