Source-Changes-HG archive

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

[src/trunk]: src/sys/crypto/aes Provide the standard AES key schedule.



details:   https://anonhg.NetBSD.org/src/rev/029ba5b3e0c6
branches:  trunk
changeset: 935309:029ba5b3e0c6
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Mon Jun 29 23:36:59 2020 +0000

description:
Provide the standard AES key schedule.

Different AES implementations prefer different variations on it, but
some of them -- notably VIA -- require the standard key schedule to
be available and don't provide hardware support for computing it
themselves.  So adapt BearSSL's logic to generate the standard key
schedule (and decryption keys, with InvMixColumns), rather than the
bitsliced key schedule that BearSSL uses natively.

diffstat:

 sys/crypto/aes/aes_bear.h   |    8 ++-
 sys/crypto/aes/aes_ct.c     |   95 +++++++++++++++++++++++++++++-
 sys/crypto/aes/aes_ct_dec.c |   12 +++-
 sys/crypto/aes/aes_impl.c   |  137 +++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 245 insertions(+), 7 deletions(-)

diffs (truncated from 337 to 300 lines):

diff -r ccdfdd33962d -r 029ba5b3e0c6 sys/crypto/aes/aes_bear.h
--- a/sys/crypto/aes/aes_bear.h Mon Jun 29 23:36:06 2020 +0000
+++ b/sys/crypto/aes/aes_bear.h Mon Jun 29 23:36:59 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: aes_bear.h,v 1.1 2020/06/29 23:27:52 riastradh Exp $   */
+/*     $NetBSD: aes_bear.h,v 1.2 2020/06/29 23:36:59 riastradh Exp $   */
 
 /*-
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -45,6 +45,12 @@
 void   br_aes_ct_bitslice_encrypt(unsigned, const uint32_t *, uint32_t *);
 void   br_aes_ct_bitslice_decrypt(unsigned, const uint32_t *, uint32_t *);
 
+/* NetBSD additions */
+
+void   br_aes_ct_inv_mix_columns(uint32_t *);
+u_int  br_aes_ct_keysched_stdenc(uint32_t *, const void *, size_t);
+u_int  br_aes_ct_keysched_stddec(uint32_t *, const void *, size_t);
+
 extern struct aes_impl aes_bear_impl;
 
 #endif /* _CRYPTO_AES_AES_BEAR_H */
diff -r ccdfdd33962d -r 029ba5b3e0c6 sys/crypto/aes/aes_ct.c
--- a/sys/crypto/aes/aes_ct.c   Mon Jun 29 23:36:06 2020 +0000
+++ b/sys/crypto/aes/aes_ct.c   Mon Jun 29 23:36:59 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: aes_ct.c,v 1.1 2020/06/29 23:27:52 riastradh Exp $     */
+/*     $NetBSD: aes_ct.c,v 1.2 2020/06/29 23:36:59 riastradh Exp $     */
 
 /*
  * Copyright (c) 2016 Thomas Pornin <pornin%bolet.org@localhost>
@@ -25,10 +25,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: aes_ct.c,v 1.1 2020/06/29 23:27:52 riastradh Exp $");
+__KERNEL_RCSID(1, "$NetBSD: aes_ct.c,v 1.2 2020/06/29 23:36:59 riastradh Exp $");
 
 #include <sys/types.h>
 
+#include <lib/libkern/libkern.h>
+
 #include <crypto/aes/aes_bear.h>
 
 /* see inner.h */
@@ -333,3 +335,92 @@
                skey[v + 1] = y | (y >> 1);
        }
 }
+
+/* NetBSD additions, for computing the standard AES key schedule */
+
+unsigned
+br_aes_ct_keysched_stdenc(uint32_t *skey, const void *key, size_t key_len)
+{
+       unsigned num_rounds;
+       int i, j, k, nk, nkf;
+       uint32_t tmp;
+
+       switch (key_len) {
+       case 16:
+               num_rounds = 10;
+               break;
+       case 24:
+               num_rounds = 12;
+               break;
+       case 32:
+               num_rounds = 14;
+               break;
+       default:
+               /* abort(); */
+               return 0;
+       }
+       nk = (int)(key_len >> 2);
+       nkf = (int)((num_rounds + 1) << 2);
+       tmp = 0;
+       for (i = 0; i < nk; i ++) {
+               tmp = br_dec32le((const unsigned char *)key + (i << 2));
+               skey[i] = tmp;
+       }
+       for (i = nk, j = 0, k = 0; i < nkf; i ++) {
+               if (j == 0) {
+                       tmp = (tmp << 24) | (tmp >> 8);
+                       tmp = sub_word(tmp) ^ Rcon[k];
+               } else if (nk > 6 && j == 4) {
+                       tmp = sub_word(tmp);
+               }
+               tmp ^= skey[i - nk];
+               skey[i] = tmp;
+               if (++ j == nk) {
+                       j = 0;
+                       k ++;
+               }
+       }
+       return num_rounds;
+}
+
+unsigned
+br_aes_ct_keysched_stddec(uint32_t *skey, const void *key, size_t key_len)
+{
+       uint32_t tkey[60];
+       uint32_t q[8];
+       unsigned num_rounds;
+       unsigned i;
+
+       num_rounds = br_aes_ct_keysched_stdenc(skey, key, key_len);
+       if (num_rounds == 0)
+               return 0;
+
+       tkey[0] = skey[4*num_rounds + 0];
+       tkey[1] = skey[4*num_rounds + 1];
+       tkey[2] = skey[4*num_rounds + 2];
+       tkey[3] = skey[4*num_rounds + 3];
+       for (i = 1; i < num_rounds; i++) {
+               q[2*0] = skey[4*i + 0];
+               q[2*1] = skey[4*i + 1];
+               q[2*2] = skey[4*i + 2];
+               q[2*3] = skey[4*i + 3];
+               q[1] = q[3] = q[5] = q[7] = 0;
+
+               br_aes_ct_ortho(q);
+               br_aes_ct_inv_mix_columns(q);
+               br_aes_ct_ortho(q);
+
+               tkey[4*(num_rounds - i) + 0] = q[2*0];
+               tkey[4*(num_rounds - i) + 1] = q[2*1];
+               tkey[4*(num_rounds - i) + 2] = q[2*2];
+               tkey[4*(num_rounds - i) + 3] = q[2*3];
+       }
+       tkey[4*num_rounds + 0] = skey[0];
+       tkey[4*num_rounds + 1] = skey[1];
+       tkey[4*num_rounds + 2] = skey[2];
+       tkey[4*num_rounds + 3] = skey[3];
+
+       memcpy(skey, tkey, 4*(num_rounds + 1)*sizeof(uint32_t));
+       explicit_memset(tkey, 0, 4*(num_rounds + 1)*sizeof(uint32_t));
+       return num_rounds;
+}
diff -r ccdfdd33962d -r 029ba5b3e0c6 sys/crypto/aes/aes_ct_dec.c
--- a/sys/crypto/aes/aes_ct_dec.c       Mon Jun 29 23:36:06 2020 +0000
+++ b/sys/crypto/aes/aes_ct_dec.c       Mon Jun 29 23:36:59 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: aes_ct_dec.c,v 1.1 2020/06/29 23:27:52 riastradh Exp $ */
+/*     $NetBSD: aes_ct_dec.c,v 1.2 2020/06/29 23:36:59 riastradh Exp $ */
 
 /*
  * Copyright (c) 2016 Thomas Pornin <pornin%bolet.org@localhost>
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: aes_ct_dec.c,v 1.1 2020/06/29 23:27:52 riastradh Exp $");
+__KERNEL_RCSID(1, "$NetBSD: aes_ct_dec.c,v 1.2 2020/06/29 23:36:59 riastradh Exp $");
 
 #include <sys/types.h>
 
@@ -175,3 +175,11 @@
        br_aes_ct_bitslice_invSbox(q);
        add_round_key(q, skey);
 }
+
+/* NetBSD addition, for generating compatible decryption keys */
+void
+br_aes_ct_inv_mix_columns(uint32_t *q)
+{
+
+       inv_mix_columns(q);
+}
diff -r ccdfdd33962d -r 029ba5b3e0c6 sys/crypto/aes/aes_impl.c
--- a/sys/crypto/aes/aes_impl.c Mon Jun 29 23:36:06 2020 +0000
+++ b/sys/crypto/aes/aes_impl.c Mon Jun 29 23:36:59 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: aes_impl.c,v 1.1 2020/06/29 23:27:52 riastradh Exp $   */
+/*     $NetBSD: aes_impl.c,v 1.2 2020/06/29 23:36:59 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.1 2020/06/29 23:27:52 riastradh Exp $");
+__KERNEL_RCSID(1, "$NetBSD: aes_impl.c,v 1.2 2020/06/29 23:36:59 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/kernel.h>
@@ -38,6 +38,8 @@
 #include <crypto/aes/aes.h>
 #include <crypto/aes/aes_bear.h> /* default implementation */
 
+static int aes_selftest_stdkeysched(void);
+
 static const struct aes_impl   *aes_md_impl    __read_mostly;
 static const struct aes_impl   *aes_impl       __read_mostly;
 
@@ -61,6 +63,9 @@
 
        KASSERT(aes_impl == NULL);
 
+       if (aes_selftest_stdkeysched())
+               panic("AES is busted");
+
        if (aes_md_impl) {
                if (aes_selftest(aes_md_impl))
                        aprint_error("aes: self-test failed: %s\n",
@@ -254,3 +259,131 @@
        aes_guarantee_selected();
        aes_impl->ai_xts_dec(dec, in, out, nbytes, tweak, nrounds);
 }
+
+/*
+ * Known-answer self-tests for the standard key schedule.
+ */
+static int
+aes_selftest_stdkeysched(void)
+{
+       static const uint8_t key[32] = {
+               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,
+       };
+       static const uint32_t rk128enc[] = {
+               0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
+               0xfd74aad6, 0xfa72afd2, 0xf178a6da, 0xfe76abd6,
+               0x0bcf92b6, 0xf1bd3d64, 0x00c59bbe, 0xfeb33068,
+               0x4e74ffb6, 0xbfc9c2d2, 0xbf0c596c, 0x41bf6904,
+               0xbcf7f747, 0x033e3595, 0xbc326cf9, 0xfd8d05fd,
+               0xe8a3aa3c, 0xeb9d9fa9, 0x57aff350, 0xaa22f6ad,
+               0x7d0f395e, 0x9692a6f7, 0xc13d55a7, 0x6b1fa30a,
+               0x1a70f914, 0x8ce25fe3, 0x4ddf0a44, 0x26c0a94e,
+               0x35874347, 0xb9651ca4, 0xf4ba16e0, 0xd27abfae,
+               0xd1329954, 0x685785f0, 0x9ced9310, 0x4e972cbe,
+               0x7f1d1113, 0x174a94e3, 0x8ba707f3, 0xc5302b4d,
+       };
+       static const uint32_t rk192enc[] = {
+               0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
+               0x13121110, 0x17161514, 0xf9f24658, 0xfef4435c,
+               0xf5fe4a54, 0xfaf04758, 0xe9e25648, 0xfef4435c,
+               0xb349f940, 0x4dbdba1c, 0xb843f048, 0x42b3b710,
+               0xab51e158, 0x55a5a204, 0x41b5ff7e, 0x0c084562,
+               0xb44bb52a, 0xf6f8023a, 0x5da9e362, 0x080c4166,
+               0x728501f5, 0x7e8d4497, 0xcac6f1bd, 0x3c3ef387,
+               0x619710e5, 0x699b5183, 0x9e7c1534, 0xe0f151a3,
+               0x2a37a01e, 0x16095399, 0x779e437c, 0x1e0512ff,
+               0x880e7edd, 0x68ff2f7e, 0x42c88f60, 0x54c1dcf9,
+               0x235f9f85, 0x3d5a8d7a, 0x5229c0c0, 0x3ad6efbe,
+               0x781e60de, 0x2cdfbc27, 0x0f8023a2, 0x32daaed8,
+               0x330a97a4, 0x09dc781a, 0x71c218c4, 0x5d1da4e3,
+       };
+       static const uint32_t rk256enc[] = {
+               0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
+               0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c,
+               0x9fc273a5, 0x98c476a1, 0x93ce7fa9, 0x9cc072a5,
+               0xcda85116, 0xdabe4402, 0xc1a45d1a, 0xdeba4006,
+               0xf0df87ae, 0x681bf10f, 0xfbd58ea6, 0x6715fc03,
+               0x48f1e16d, 0x924fa56f, 0x53ebf875, 0x8d51b873,
+               0x7f8256c6, 0x1799a7c9, 0xec4c296f, 0x8b59d56c,
+               0x753ae23d, 0xe7754752, 0xb49ebf27, 0x39cf0754,
+               0x5f90dc0b, 0x48097bc2, 0xa44552ad, 0x2f1c87c1,
+               0x60a6f545, 0x87d3b217, 0x334d0d30, 0x0a820a64,
+               0x1cf7cf7c, 0x54feb4be, 0xf0bbe613, 0xdfa761d2,
+               0xfefa1af0, 0x7929a8e7, 0x4a64a5d7, 0x40e6afb3,
+               0x71fe4125, 0x2500f59b, 0xd5bb1388, 0x0a1c725a,
+               0x99665a4e, 0xe04ff2a9, 0xaa2b577e, 0xeacdf8cd,
+               0xcc79fc24, 0xe97909bf, 0x3cc21a37, 0x36de686d,
+       };
+       static const uint32_t rk128dec[] = {
+               0x7f1d1113, 0x174a94e3, 0x8ba707f3, 0xc5302b4d,
+               0xbe29aa13, 0xf6af8f9c, 0x80f570f7, 0x03bff700,
+               0x63a46213, 0x4886258f, 0x765aff6b, 0x834a87f7,
+               0x74fc828d, 0x2b22479c, 0x3edcdae4, 0xf510789c,
+               0x8d09e372, 0x5fdec511, 0x15fe9d78, 0xcbcca278,
+               0x2710c42e, 0xd2d72663, 0x4a205869, 0xde323f00,
+               0x04f5a2a8, 0xf5c7e24d, 0x98f77e0a, 0x94126769,
+               0x91e3c6c7, 0xf13240e5, 0x6d309c47, 0x0ce51963,
+               0x9902dba0, 0x60d18622, 0x9c02dca2, 0x61d58524,
+               0xf0df568c, 0xf9d35d82, 0xfcd35a80, 0xfdd75986,
+               0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
+       };
+       static const uint32_t rk192dec[] = {
+               0x330a97a4, 0x09dc781a, 0x71c218c4, 0x5d1da4e3,
+               0x0dbdbed6, 0x49ea09c2, 0x8073b04d, 0xb91b023e,
+               0xc999b98f, 0x3968b273, 0x9dd8f9c7, 0x728cc685,
+               0xc16e7df7, 0xef543f42, 0x7f317853, 0x4457b714,
+               0x90654711, 0x3b66cf47, 0x8dce0e9b, 0xf0f10bfc,
+               0xb6a8c1dc, 0x7d3f0567, 0x4a195ccc, 0x2e3a42b5,
+               0xabb0dec6, 0x64231e79, 0xbe5f05a4, 0xab038856,
+               0xda7c1bdd, 0x155c8df2, 0x1dab498a, 0xcb97c4bb,
+               0x08f7c478, 0xd63c8d31, 0x01b75596, 0xcf93c0bf,
+               0x10efdc60, 0xce249529, 0x15efdb62, 0xcf20962f,
+               0xdbcb4e4b, 0xdacf4d4d, 0xc7d75257, 0xdecb4949,
+               0x1d181f1a, 0x191c1b1e, 0xd7c74247, 0xdecb4949,
+               0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
+       };
+       static const uint32_t rk256dec[] = {
+               0xcc79fc24, 0xe97909bf, 0x3cc21a37, 0x36de686d,
+               0xffd1f134, 0x2faacebf, 0x5fe2e9fc, 0x6e015825,
+               0xeb48165e, 0x0a354c38, 0x46b77175, 0x84e680dc,
+               0x8005a3c8, 0xd07b3f8b, 0x70482743, 0x31e3b1d9,



Home | Main Index | Thread Index | Old Index