Source-Changes-HG archive

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

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



details:   https://anonhg.NetBSD.org/src-all/rev/eba823218eb3
branches:  trunk
changeset: 935255:eba823218eb3
user:      Taylor R Campbell <riastradh%NetBSD.org@localhost>
date:      Mon Jun 15 16:19:29 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   |    6 +
 sys/crypto/aes/aes_ct.c     |   91 ++++++++++++++++++++++++++++++
 sys/crypto/aes/aes_ct_dec.c |    8 ++
 sys/crypto/aes/aes_impl.c   |  133 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 238 insertions(+), 0 deletions(-)

diffs (290 lines):

diff -r 78047bd77555 -r eba823218eb3 sys/crypto/aes/aes_bear.h
--- a/sys/crypto/aes/aes_bear.h Mon Jun 15 20:06:11 2020 +0000
+++ b/sys/crypto/aes/aes_bear.h Mon Jun 15 16:19:29 2020 +0000
@@ -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 78047bd77555 -r eba823218eb3 sys/crypto/aes/aes_ct.c
--- a/sys/crypto/aes/aes_ct.c   Mon Jun 15 20:06:11 2020 +0000
+++ b/sys/crypto/aes/aes_ct.c   Mon Jun 15 16:19:29 2020 +0000
@@ -29,6 +29,8 @@
 
 #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 78047bd77555 -r eba823218eb3 sys/crypto/aes/aes_ct_dec.c
--- a/sys/crypto/aes/aes_ct_dec.c       Mon Jun 15 20:06:11 2020 +0000
+++ b/sys/crypto/aes/aes_ct_dec.c       Mon Jun 15 16:19:29 2020 +0000
@@ -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 78047bd77555 -r eba823218eb3 sys/crypto/aes/aes_impl.c
--- a/sys/crypto/aes/aes_impl.c Mon Jun 15 20:06:11 2020 +0000
+++ b/sys/crypto/aes/aes_impl.c Mon Jun 15 16:19:29 2020 +0000
@@ -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,
+               0x138e70b5, 0xe17d5a66, 0x4c823d4d, 0xc251f1a9,
+               0xa37bda74, 0x507e9c43, 0xa03318c8, 0x41ab969a,
+               0x1597a63c, 0xf2f32ad3, 0xadff672b, 0x8ed3cce4,
+               0xf3c45ff8, 0xf3054637, 0xf04d848b, 0xe1988e52,
+               0x9a4069de, 0xe7648cef, 0x5f0c4df8, 0x232cabcf,
+               0x1658d5ae, 0x00c119cf, 0x0348c2bc, 0x11d50ad9,
+               0xbd68c615, 0x7d24e531, 0xb868c117, 0x7c20e637,
+               0x0f85d77f, 0x1699cc61, 0x0389db73, 0x129dc865,
+               0xc940282a, 0xc04c2324, 0xc54c2426, 0xc4482720,
+               0x1d181f1a, 0x191c1b1e, 0x15101712, 0x11141316,
+               0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
+       };
+       static const struct {
+               unsigned        len;
+               unsigned        nr;
+               const uint32_t  *enc, *dec;
+       } C[] = {
+               { 16, AES_128_NROUNDS, rk128enc, rk128dec },
+               { 24, AES_192_NROUNDS, rk192enc, rk192dec },
+               { 32, AES_256_NROUNDS, rk256enc, rk256dec },
+       };
+       uint32_t rk[60];
+       unsigned i;
+
+       for (i = 0; i < __arraycount(C); i++) {
+               if (br_aes_ct_keysched_stdenc(rk, key, C[i].len) != C[i].nr)
+                       return -1;
+               if (memcmp(rk, C[i].enc, 4*(C[i].nr + 1)))
+                       return -1;
+               if (br_aes_ct_keysched_stddec(rk, key, C[i].len) != C[i].nr)
+                       return -1;
+               if (memcmp(rk, C[i].dec, 4*(C[i].nr + 1)))
+                       return -1;
+       }
+
+       return 0;
+}



Home | Main Index | Thread Index | Old Index