Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/crypto/aes Push CBC-MAC and CCM block updates into the a...



details:   https://anonhg.NetBSD.org/src/rev/c9ee5f219094
branches:  trunk
changeset: 936310:c9ee5f219094
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sat Jul 25 22:27:53 2020 +0000

description:
Push CBC-MAC and CCM block updates into the aes_impl API.

This should help reduce the setup and teardown overhead (enabling and
disabling fpu, or expanding bitsliced keys) for CCM, as used in
802.11 WPA2 CCMP.  But all the fiddly formatting details remain in
aes_ccm.c to reduce the effort of implementing it -- at the cost of a
handful additional setups and teardowns per message.

Not yet implemented by any of the aes_impls, so leave a fallback that
just calls aes_enc for now.  This should be removed when all of the
aes_impls provide CBC-MAC and CCM block updates.

diffstat:

 sys/crypto/aes/aes_ccm.c      |   49 +++++--------
 sys/crypto/aes/aes_impl.c     |   88 +++++++++++++++++++++++-
 sys/crypto/aes/aes_impl.h     |   19 +++++-
 sys/crypto/aes/aes_selftest.c |  151 +++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 272 insertions(+), 35 deletions(-)

diffs (truncated from 423 to 300 lines):

diff -r b50a370bddf0 -r c9ee5f219094 sys/crypto/aes/aes_ccm.c
--- a/sys/crypto/aes/aes_ccm.c  Sat Jul 25 22:27:05 2020 +0000
+++ b/sys/crypto/aes/aes_ccm.c  Sat Jul 25 22:27:53 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: aes_ccm.c,v 1.1 2020/07/25 22:15:55 riastradh Exp $    */
+/*     $NetBSD: aes_ccm.c,v 1.2 2020/07/25 22:27:53 riastradh Exp $    */
 
 /*-
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: aes_ccm.c,v 1.1 2020/07/25 22:15:55 riastradh Exp $");
+__KERNEL_RCSID(1, "$NetBSD: aes_ccm.c,v 1.2 2020/07/25 22:27:53 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -45,6 +45,7 @@
 
 #include <crypto/aes/aes.h>
 #include <crypto/aes/aes_ccm.h>
+#include <crypto/aes/aes_impl.h>
 
 static inline void
 xor(uint8_t *x, const uint8_t *a, const uint8_t *b, size_t n)
@@ -54,13 +55,6 @@
                *x++ = *a++ ^ *b++;
 }
 
-static inline void
-xor16(uint8_t *x, const uint8_t *a, const uint8_t *b)
-{
-
-       xor(x, a, b, 16);
-}
-
 /* RFC 3610, §2.2 Authentication */
 #define        CCM_AFLAGS_ADATA        __BIT(6)
 #define        CCM_AFLAGS_M            __BITS(5,3)
@@ -157,9 +151,10 @@
                aes_enc(enc, C->auth, C->auth, C->nr);
 
                /* If there was anything more, process 16 bytes at a time.  */
-               for (; adlen >= 16; adp += 16, adlen -= 16) {
-                       xor16(C->auth, C->auth, adp);
-                       aes_enc(enc, C->auth, C->auth, C->nr);
+               if (adlen - (adlen % 16)) {
+                       aes_cbcmac_update1(enc, adp, adlen - (adlen % 16),
+                           C->auth, C->nr);
+                       adlen %= 16;
                }
 
                /*
@@ -217,15 +212,12 @@
        }
 
        /* Process 16 bytes at a time.  */
-       for (; nbytes >= 16; p += 16, q += 16, nbytes -= 16) {
-               /* authenticate */
-               xor16(C->auth, C->auth, p);
-               aes_enc(C->enc, C->auth, C->auth, C->nr);
-
-               /* encrypt */
-               aes_ccm_inc(C);
-               aes_enc(C->enc, C->in, C->out, C->nr);
-               xor16(q, C->out, p);
+       if (nbytes - (nbytes % 16)) {
+               aes_ccm_enc1(C->enc, p, q, nbytes - (nbytes % 16), C->auth,
+                   C->nr);
+               p += nbytes - (nbytes % 16);
+               q += nbytes - (nbytes % 16);
+               nbytes %= 16;
        }
 
        /* Incorporate any <16-byte unit as a partial block.  */
@@ -278,15 +270,12 @@
        }
 
        /* Process 16 bytes at a time.  */
-       for (; nbytes >= 16; p += 16, q += 16, nbytes -= 16) {
-               /* decrypt */
-               aes_ccm_inc(C);
-               aes_enc(C->enc, C->in, C->out, C->nr);
-               xor16(q, C->out, p);
-
-               /* authenticate */
-               xor16(C->auth, C->auth, q);
-               aes_enc(C->enc, C->auth, C->auth, C->nr);
+       if (nbytes - (nbytes % 16)) {
+               aes_ccm_dec1(C->enc, p, q, nbytes - (nbytes % 16), C->auth,
+                   C->nr);
+               p += nbytes - (nbytes % 16);
+               q += nbytes - (nbytes % 16);
+               nbytes %= 16;
        }
 
        /* Incorporate any <16-byte unit as a partial block.  */
diff -r b50a370bddf0 -r c9ee5f219094 sys/crypto/aes/aes_impl.c
--- a/sys/crypto/aes/aes_impl.c Sat Jul 25 22:27:05 2020 +0000
+++ b/sys/crypto/aes/aes_impl.c Sat Jul 25 22:27:53 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: aes_impl.c,v 1.5 2020/07/25 22:14:35 riastradh Exp $   */
+/*     $NetBSD: aes_impl.c,v 1.6 2020/07/25 22:27:53 riastradh Exp $   */
 
 /*-
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: aes_impl.c,v 1.5 2020/07/25 22:14:35 riastradh Exp $");
+__KERNEL_RCSID(1, "$NetBSD: aes_impl.c,v 1.6 2020/07/25 22:27:53 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/kernel.h>
@@ -288,6 +288,90 @@
        aes_impl->ai_xts_dec(dec, in, out, nbytes, tweak, nrounds);
 }
 
+static void
+xor16(uint8_t *x, const uint8_t *a, const uint8_t *b)
+{
+
+       le32enc(x + 4*0, le32dec(a + 4*0) ^ le32dec(b + 4*0));
+       le32enc(x + 4*1, le32dec(a + 4*1) ^ le32dec(b + 4*1));
+       le32enc(x + 4*2, le32dec(a + 4*2) ^ le32dec(b + 4*2));
+       le32enc(x + 4*3, le32dec(a + 4*3) ^ le32dec(b + 4*3));
+}
+
+void
+aes_cbcmac_update1(const struct aesenc *enc, const uint8_t in[static 16],
+    size_t nbytes, uint8_t auth[static 16], uint32_t nrounds)
+{
+
+       KASSERT(nbytes);
+       KASSERT(nbytes % 16 == 0);
+
+       aes_guarantee_selected();
+       if (aes_impl->ai_cbcmac_update1) {
+               aes_impl->ai_cbcmac_update1(enc, in, nbytes, auth, nrounds);
+               return;
+       }
+
+       for (; nbytes; in += 16, nbytes -= 16) {
+               xor16(auth, auth, in);
+               aes_enc(enc, auth, auth, nrounds);
+       }
+}
+
+void
+aes_ccm_enc1(const struct aesenc *enc, const uint8_t in[static 16],
+    uint8_t out[static 16], size_t nbytes, uint8_t authctr[static 32],
+    uint32_t nrounds)
+{
+       uint8_t *auth = authctr;
+       uint8_t *ctr = authctr + 16;
+
+       KASSERT(nbytes);
+       KASSERT(nbytes % 16 == 0);
+
+       aes_guarantee_selected();
+       if (aes_impl->ai_ccm_enc1) {
+               aes_impl->ai_ccm_enc1(enc, in, out, nbytes, auth, nrounds);
+               return;
+       }
+
+       for (; nbytes; in += 16, out += 16, nbytes -= 16) {
+               xor16(auth, auth, in);
+               aes_enc(enc, auth, auth, nrounds);
+
+               be32enc(ctr + 12, 1 + be32dec(ctr + 12));
+               aes_enc(enc, ctr, out, nrounds);
+               xor16(out, out, in);
+       }
+}
+
+void
+aes_ccm_dec1(const struct aesenc *enc, const uint8_t in[static 16],
+    uint8_t out[static 16], size_t nbytes, uint8_t authctr[static 32],
+    uint32_t nrounds)
+{
+       uint8_t *auth = authctr;
+       uint8_t *ctr = authctr + 16;
+
+       KASSERT(nbytes);
+       KASSERT(nbytes % 16 == 0);
+
+       aes_guarantee_selected();
+       if (aes_impl->ai_ccm_dec1) {
+               aes_impl->ai_ccm_dec1(enc, in, out, nbytes, auth, nrounds);
+               return;
+       }
+
+       for (; nbytes >= 16; in += 16, out += 16, nbytes -= 16) {
+               be32enc(ctr + 12, 1 + be32dec(ctr + 12));
+               aes_enc(enc, ctr, out, nrounds);
+               xor16(out, out, in);
+
+               xor16(auth, auth, out);
+               aes_enc(enc, auth, auth, nrounds);
+       }
+}
+
 /*
  * Known-answer self-tests for the standard key schedule.
  */
diff -r b50a370bddf0 -r c9ee5f219094 sys/crypto/aes/aes_impl.h
--- a/sys/crypto/aes/aes_impl.h Sat Jul 25 22:27:05 2020 +0000
+++ b/sys/crypto/aes/aes_impl.h Sat Jul 25 22:27:53 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: aes_impl.h,v 1.1 2020/07/25 22:12:57 riastradh Exp $   */
+/*     $NetBSD: aes_impl.h,v 1.2 2020/07/25 22:27:53 riastradh Exp $   */
 
 /*-
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -51,10 +51,27 @@
                    uint8_t[static 16], size_t, uint8_t[static 16], uint32_t);
        void    (*ai_xts_dec)(const struct aesdec *, const uint8_t[static 16],
                    uint8_t[static 16], size_t, uint8_t[static 16], uint32_t);
+       void    (*ai_cbcmac_update1)(const struct aesenc *,
+                   const uint8_t[static 16], size_t, uint8_t[static 16],
+                   uint32_t);
+       void    (*ai_ccm_enc1)(const struct aesenc *,
+                   const uint8_t[static 16], uint8_t[static 16],
+                   size_t, uint8_t[static 32], uint32_t);
+       void    (*ai_ccm_dec1)(const struct aesenc *,
+                   const uint8_t[static 16], uint8_t[static 16],
+                   size_t, uint8_t[static 32], uint32_t);
 };
 
 void   aes_md_init(const struct aes_impl *);
 
 int    aes_selftest(const struct aes_impl *);
 
+/* Internal subroutines dispatched to implementation for AES-CCM.  */
+void   aes_cbcmac_update1(const struct aesenc *, const uint8_t[static 16],
+           size_t, uint8_t[static 16], uint32_t);
+void   aes_ccm_enc1(const struct aesenc *, const uint8_t[static 16],
+           uint8_t[static 16], size_t, uint8_t[static 32], uint32_t);
+void   aes_ccm_dec1(const struct aesenc *, const uint8_t[static 16],
+           uint8_t[static 16], size_t, uint8_t[static 32], uint32_t);
+
 #endif /* _CRYPTO_AES_AES_IMPL_H */
diff -r b50a370bddf0 -r c9ee5f219094 sys/crypto/aes/aes_selftest.c
--- a/sys/crypto/aes/aes_selftest.c     Sat Jul 25 22:27:05 2020 +0000
+++ b/sys/crypto/aes/aes_selftest.c     Sat Jul 25 22:27:53 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: aes_selftest.c,v 1.3 2020/07/25 22:12:57 riastradh Exp $       */
+/*     $NetBSD: aes_selftest.c,v 1.4 2020/07/25 22:27:53 riastradh Exp $       */
 
 /*-
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: aes_selftest.c,v 1.3 2020/07/25 22:12:57 riastradh Exp $");
+__KERNEL_RCSID(1, "$NetBSD: aes_selftest.c,v 1.4 2020/07/25 22:27:53 riastradh Exp $");
 
 #ifdef _KERNEL
 
@@ -400,6 +400,149 @@
        return 0;
 }
 
+static int
+aes_selftest_cbcmac(const struct aes_impl *impl)
+{
+       static const uint8_t m[48] = {
+               0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07,
+               0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
+               0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17,
+               0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
+               0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27,
+               0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f,
+       };
+       static uint8_t auth16[16] = {
+               0x7a,0xca,0x0f,0xd9, 0xbc,0xd6,0xec,0x7c,
+               0x9f,0x97,0x46,0x66, 0x16,0xe6,0xa2,0x82,
+       };
+       static uint8_t auth48[16] = {
+               0x26,0x9a,0xe5,0xfc, 0x8c,0x53,0x0f,0xf7,
+               0x6b,0xd9,0xec,0x05, 0x40,0xf7,0x35,0x13,
+       };
+       static const uint8_t key[16];
+       struct aesenc enc;
+       uint8_t auth[16];
+       const unsigned nr = AES_128_NROUNDS;
+
+       if (impl->ai_cbcmac_update1 == NULL)
+               return 0;
+
+       memset(auth, 0, sizeof auth);
+
+       impl->ai_setenckey(&enc, key, nr);
+       impl->ai_cbcmac_update1(&enc, m, 16, auth, nr);
+       if (memcmp(auth, auth16, 16))
+               return aes_selftest_fail(impl, auth, auth16, 16,
+                   "AES-128 CBC-MAC (16)");



Home | Main Index | Thread Index | Old Index