Source-Changes-HG archive

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

[src/trunk]: src/sys/crypto/aes Implement AES-CCM with BearSSL's bitsliced 32...



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

description:
Implement AES-CCM with BearSSL's bitsliced 32-bit aes_ct.

diffstat:

 sys/crypto/aes/aes_bear.c |  221 +++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 219 insertions(+), 2 deletions(-)

diffs (247 lines):

diff -r c9ee5f219094 -r 1ae0d2b17233 sys/crypto/aes/aes_bear.c
--- a/sys/crypto/aes/aes_bear.c Sat Jul 25 22:27:53 2020 +0000
+++ b/sys/crypto/aes/aes_bear.c Sat Jul 25 22:28:27 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: aes_bear.c,v 1.3 2020/07/25 22:12:57 riastradh Exp $   */
+/*     $NetBSD: aes_bear.c,v 1.4 2020/07/25 22:28:27 riastradh Exp $   */
 
 /*-
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: aes_bear.c,v 1.3 2020/07/25 22:12:57 riastradh Exp $");
+__KERNEL_RCSID(1, "$NetBSD: aes_bear.c,v 1.4 2020/07/25 22:28:27 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/endian.h>
@@ -597,6 +597,220 @@
        explicit_memset(q, 0, sizeof q);
 }
 
+static void
+aesbear_cbcmac_update1(const struct aesenc *enc, const uint8_t in[static 16],
+    size_t nbytes, uint8_t auth[static 16], uint32_t nrounds)
+{
+       uint32_t sk_exp[120];
+       uint32_t q[8];
+
+       KASSERT(nbytes);
+       KASSERT(nbytes % 16 == 0);
+
+       /* Expand round keys for bitslicing.  */
+       br_aes_ct_skey_expand(sk_exp, nrounds, enc->aese_aes.aes_rk);
+
+       /* Initialize garbage block.  */
+       q[1] = q[3] = q[5] = q[7] = 0;
+
+       /* Load initial authenticator.  */
+       q[2*0] = le32dec(auth + 4*0);
+       q[2*1] = le32dec(auth + 4*1);
+       q[2*2] = le32dec(auth + 4*2);
+       q[2*3] = le32dec(auth + 4*3);
+
+       for (; nbytes; nbytes -= 16, in += 16) {
+               /* Combine input block.  */
+               q[2*0] ^= le32dec(in + 4*0);
+               q[2*1] ^= le32dec(in + 4*1);
+               q[2*2] ^= le32dec(in + 4*2);
+               q[2*3] ^= le32dec(in + 4*3);
+
+               /* Transform to bitslice, encrypt, transform from bitslice.  */
+               br_aes_ct_ortho(q);
+               br_aes_ct_bitslice_encrypt(nrounds, sk_exp, q);
+               br_aes_ct_ortho(q);
+       }
+
+       /* Store updated authenticator.  */
+       le32enc(auth + 4*0, q[2*0]);
+       le32enc(auth + 4*1, q[2*1]);
+       le32enc(auth + 4*2, q[2*2]);
+       le32enc(auth + 4*3, q[2*3]);
+
+       /* Paranoia: Zero temporary buffers.  */
+       explicit_memset(sk_exp, 0, sizeof sk_exp);
+       explicit_memset(q, 0, sizeof q);
+}
+
+static void
+aesbear_ccm_enc1(const struct aesenc *enc, const uint8_t *in, uint8_t *out,
+    size_t nbytes, uint8_t authctr[32], uint32_t nrounds)
+{
+       uint32_t sk_exp[120];
+       uint32_t q[8];
+       uint32_t c0, c1, c2, c3;
+
+       KASSERT(nbytes);
+       KASSERT(nbytes % 16 == 0);
+
+       /* Expand round keys for bitslicing.  */
+       br_aes_ct_skey_expand(sk_exp, nrounds, enc->aese_aes.aes_rk);
+
+       /* Set first block to authenticator.  */
+       q[2*0] = le32dec(authctr + 4*0);
+       q[2*1] = le32dec(authctr + 4*1);
+       q[2*2] = le32dec(authctr + 4*2);
+       q[2*3] = le32dec(authctr + 4*3);
+
+       /* Load initial counter block, big-endian so we can increment it.  */
+       c0 = le32dec(authctr + 16 + 4*0);
+       c1 = le32dec(authctr + 16 + 4*1);
+       c2 = le32dec(authctr + 16 + 4*2);
+       c3 = be32dec(authctr + 16 + 4*3);
+
+       for (; nbytes; nbytes -= 16, in += 16, out += 16) {
+               /* Update authenticator.  */
+               q[2*0] ^= le32dec(in + 4*0);
+               q[2*1] ^= le32dec(in + 4*1);
+               q[2*2] ^= le32dec(in + 4*2);
+               q[2*3] ^= le32dec(in + 4*3);
+
+               /* Increment 32-bit counter.  */
+               q[2*0 + 1] = c0;
+               q[2*1 + 1] = c1;
+               q[2*2 + 1] = c2;
+               q[2*3 + 1] = bswap32(++c3);
+
+               /* Encrypt authenticator and counter.  */
+               br_aes_ct_ortho(q);
+               br_aes_ct_bitslice_encrypt(nrounds, sk_exp, q);
+               br_aes_ct_ortho(q);
+
+               /* Encrypt with CTR output.  */
+               le32enc(out + 4*0, le32dec(in + 4*0) ^ q[2*0 + 1]);
+               le32enc(out + 4*1, le32dec(in + 4*1) ^ q[2*1 + 1]);
+               le32enc(out + 4*2, le32dec(in + 4*2) ^ q[2*2 + 1]);
+               le32enc(out + 4*3, le32dec(in + 4*3) ^ q[2*3 + 1]);
+       }
+
+       /* Update authenticator.  */
+       le32enc(authctr + 4*0, q[2*0]);
+       le32enc(authctr + 4*1, q[2*1]);
+       le32enc(authctr + 4*2, q[2*2]);
+       le32enc(authctr + 4*3, q[2*3]);
+
+       /* Update counter.  */
+       be32enc(authctr + 16 + 4*3, c3);
+
+       /* Paranoia: Zero temporary buffers.  */
+       explicit_memset(sk_exp, 0, sizeof sk_exp);
+       explicit_memset(q, 0, sizeof q);
+}
+
+static void
+aesbear_ccm_dec1(const struct aesenc *enc, const uint8_t *in, uint8_t *out,
+    size_t nbytes, uint8_t authctr[32], uint32_t nrounds)
+{
+       uint32_t sk_exp[120];
+       uint32_t q[8];
+       uint32_t c0, c1, c2, c3;
+       uint32_t b0, b1, b2, b3;
+
+       KASSERT(nbytes);
+       KASSERT(nbytes % 16 == 0);
+
+       /* Expand round keys for bitslicing.  */
+       br_aes_ct_skey_expand(sk_exp, nrounds, enc->aese_aes.aes_rk);
+
+       /* Load initial counter block, big-endian so we can increment it.  */
+       c0 = le32dec(authctr + 16 + 4*0);
+       c1 = le32dec(authctr + 16 + 4*1);
+       c2 = le32dec(authctr + 16 + 4*2);
+       c3 = be32dec(authctr + 16 + 4*3);
+
+       /* Increment 32-bit counter.  */
+       q[2*0] = c0;
+       q[2*1] = c1;
+       q[2*2] = c2;
+       q[2*3] = bswap32(++c3);
+
+       /*
+        * Set the second block to garbage -- we don't have any
+        * plaintext to authenticate yet.
+        */
+       q[1] = q[3] = q[5] = q[7] = 0;
+
+       /* Encrypt first CTR.  */
+       br_aes_ct_ortho(q);
+       br_aes_ct_bitslice_encrypt(nrounds, sk_exp, q);
+       br_aes_ct_ortho(q);
+
+       /* Load the initial authenticator.  */
+       q[2*0 + 1] = le32dec(authctr + 4*0);
+       q[2*1 + 1] = le32dec(authctr + 4*1);
+       q[2*2 + 1] = le32dec(authctr + 4*2);
+       q[2*3 + 1] = le32dec(authctr + 4*3);
+
+       for (;; in += 16, out += 16) {
+               /* Decrypt the block.  */
+               b0 = le32dec(in + 4*0) ^ q[2*0];
+               b1 = le32dec(in + 4*1) ^ q[2*1];
+               b2 = le32dec(in + 4*2) ^ q[2*2];
+               b3 = le32dec(in + 4*3) ^ q[2*3];
+
+               /* Update authenticator.  */
+               q[2*0 + 1] ^= b0;
+               q[2*1 + 1] ^= b1;
+               q[2*2 + 1] ^= b2;
+               q[2*3 + 1] ^= b3;
+
+               /* Store plaintext.  */
+               le32enc(out + 4*0, b0);
+               le32enc(out + 4*1, b1);
+               le32enc(out + 4*2, b2);
+               le32enc(out + 4*3, b3);
+
+               /* If this is the last block, stop.  */
+               if ((nbytes -= 16) == 0)
+                       break;
+
+               /* Increment 32-bit counter.  */
+               q[2*0] = c0;
+               q[2*1] = c1;
+               q[2*2] = c2;
+               q[2*3] = bswap32(++c3);
+
+               /* Authenticate previous plaintext, encrypt next CTR.  */
+               br_aes_ct_ortho(q);
+               br_aes_ct_bitslice_encrypt(nrounds, sk_exp, q);
+               br_aes_ct_ortho(q);
+       }
+
+       /*
+        * Authenticate last plaintext.  We're only doing this for the
+        * authenticator, not for the counter, so don't bother to
+        * initialize q[2*i].  (Even for the sake of sanitizers,
+        * they're already initialized to something by now.)
+        */
+       br_aes_ct_ortho(q);
+       br_aes_ct_bitslice_encrypt(nrounds, sk_exp, q);
+       br_aes_ct_ortho(q);
+
+       /* Update authenticator.  */
+       le32enc(authctr + 4*0, q[2*0 + 1]);
+       le32enc(authctr + 4*1, q[2*1 + 1]);
+       le32enc(authctr + 4*2, q[2*2 + 1]);
+       le32enc(authctr + 4*3, q[2*3 + 1]);
+
+       /* Update counter.  */
+       be32enc(authctr + 16 + 4*3, c3);
+
+       /* Paranoia: Zero temporary buffers.  */
+       explicit_memset(sk_exp, 0, sizeof sk_exp);
+       explicit_memset(q, 0, sizeof q);
+}
+
 static int
 aesbear_probe(void)
 {
@@ -624,4 +838,7 @@
        .ai_cbc_dec = aesbear_cbc_dec,
        .ai_xts_enc = aesbear_xts_enc,
        .ai_xts_dec = aesbear_xts_dec,
+       .ai_cbcmac_update1 = aesbear_cbcmac_update1,
+       .ai_ccm_enc1 = aesbear_ccm_enc1,
+       .ai_ccm_dec1 = aesbear_ccm_dec1,
 };



Home | Main Index | Thread Index | Old Index