Re: [RFC PATCH] fscrypt-crypt-util: add HCTR2 tests

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



On Tue, Apr 12, 2022 at 5:29 PM Eric Biggers <ebiggers@xxxxxxxxxx> wrote:
>
> On Tue, Apr 12, 2022 at 02:48:07PM -0500, Nathan Huckleberry wrote:
> > This patch is not intended to be accepted yet.  It is reliant on HCTR2
> > support in the kernel which has not yet been accepted.  See the HCTR2
> > patch here:
> > https://lore.kernel.org/all/20220412172816.917723-1-nhuck@xxxxxxxxxx/
> >
> > HCTR2 is a new wide-block encryption mode that can used for filename
> > encryption in fscrypt.  This patch adds tests for fscrypt policies using
> > HCTR2 for filename encryption.
> >
> > More information on HCTR2 can be found here:
> > Length-preserving encryption with HCTR2
> > https://ia.cr/2021/1441
> >
> > Signed-off-by: Nathan Huckleberry <nhuck@xxxxxxxxxx>
> > ---
> >  common/encrypt           |   2 +
> >  src/fscrypt-crypt-util.c | 452 ++++++++++++++++++++++++++++++++++-----
> >  tests/generic/678        |  24 +++
> >  tests/generic/678.out    |   5 +
> >  tests/generic/679        |  26 +++
> >  tests/generic/679.out    |   6 +
> >  tests/generic/680        |  26 +++
> >  tests/generic/680.out    |   6 +
> >  tests/generic/681        |  26 +++
> >  tests/generic/681.out    |   6 +
> >  10 files changed, 523 insertions(+), 56 deletions(-)
> >  create mode 100755 tests/generic/678
> >  create mode 100644 tests/generic/678.out
> >  create mode 100755 tests/generic/679
> >  create mode 100644 tests/generic/679.out
> >  create mode 100755 tests/generic/680
> >  create mode 100644 tests/generic/680.out
> >  create mode 100755 tests/generic/681
> >  create mode 100644 tests/generic/681.out
>
> Please Cc linux-fscrypt@xxxxxxxxxxxxxxx for all encryption xfstests updates.
>
> The subject line "fscrypt-crypt-util:" is a bit misleading, as it makes it sound
> like this patch just updates the fscrypt-crypt-util helper program.  Actually it
> adds new test scripts too.  I recommend splitting the test scripts into a
> separate patch.
>
> This patch doesn't apply to the master branch of xfstests anymore, since someone
> already created tests with numbers 678-679.  To avoid these types of conflicts,
> usually people use other unused test numbers in xfstests patches, like 900-910,
> and the xfstests maintainer renumbers the tests when applying the patch.
>
> > @@ -54,7 +55,8 @@ static void usage(FILE *fp)
> >  "resulting ciphertext (or plaintext) to stdout.\n"
> >  "\n"
> >  "CIPHER can be AES-256-XTS, AES-256-CTS-CBC, AES-128-CBC-ESSIV, AES-128-CTS-CBC,\n"
> > -"or Adiantum.  MASTER_KEY must be a hex string long enough for the cipher.\n"
> > +"Adiantum, or AES-256-HCTR2.  MASTER_KEY must be a hex string long enough for\n"
> > +"the cipher."
>
> There should be a newline at the end of the above line.
>
> > +#include <linux/if_alg.h>
> > +#include <sys/socket.h>
> > +#define SOL_ALG 279
> > +static void af_alg_crypt(int algfd, int op, const u8 *key, size_t keylen,
> > +                      const u8 *iv, size_t ivlen,
> > +                      const u8 *src, u8 *dst, size_t datalen)
> > +{
> > +     size_t controllen = CMSG_SPACE(sizeof(int)) +
> > +                         CMSG_SPACE(sizeof(struct af_alg_iv) + ivlen);
> > +     u8 *control = xmalloc(controllen);
> > +     struct iovec iov = { .iov_base = (u8 *)src, .iov_len = datalen };
> > +     struct msghdr msg = {
> > +             .msg_iov = &iov,
> > +             .msg_iovlen = 1,
> > +             .msg_control = control,
> > +             .msg_controllen = controllen,
> > +     };
> > +     struct cmsghdr *cmsg;
> > +     struct af_alg_iv *algiv;
> > +     int reqfd;
> > +
> > +     memset(control, 0, controllen);
> > +
> > +     cmsg = CMSG_FIRSTHDR(&msg);
> > +     cmsg->cmsg_len = CMSG_LEN(sizeof(int));
> > +     cmsg->cmsg_level = SOL_ALG;
> > +     cmsg->cmsg_type = ALG_SET_OP;
> > +     *(int *)CMSG_DATA(cmsg) = op;
> > +
> > +     cmsg = CMSG_NXTHDR(&msg, cmsg);
> > +     cmsg->cmsg_len = CMSG_LEN(sizeof(struct af_alg_iv) + ivlen);
> > +     cmsg->cmsg_level = SOL_ALG;
> > +     cmsg->cmsg_type = ALG_SET_IV;
> > +     algiv = (struct af_alg_iv *)CMSG_DATA(cmsg);
> > +     algiv->ivlen = ivlen;
> > +     memcpy(algiv->iv, iv, ivlen);
> > +
> > +     if (setsockopt(algfd, SOL_ALG, ALG_SET_KEY, key, keylen) != 0)
> > +             die_errno("can't set key on AF_ALG socket");
> > +
> > +     reqfd = accept(algfd, NULL, NULL);
> > +     if (reqfd < 0)
> > +             die_errno("can't accept() AF_ALG socket");
> > +     if (sendmsg(reqfd, &msg, 0) != datalen)
> > +             die_errno("can'datalen, t sendmsg() AF_ALG request socket");
>
> Something went wrong when copying the above error message.
>
> > +     if (xread(reqfd, dst, datalen) != datalen)
> > +             die("short read from AF_ALG request socket");
> > +     close(reqfd);
> > +
> > +     free(control);
> > +}
> >  #endif
>
> Please add a comment by the #endif, like "#endif /* ENABLE_ALG_TESTS */", since
> this #if-#endif block encloses a lot of code now.
>
> >  /*----------------------------------------------------------------------------*
> >   *                          Finite field arithmetic                           *
> >   *----------------------------------------------------------------------------*/
> >
> > +#define gf128mul_dat(q) { \
> > +     q(0x00), q(0x01), q(0x02), q(0x03), q(0x04), q(0x05), q(0x06), q(0x07),\
> > +     q(0x08), q(0x09), q(0x0a), q(0x0b), q(0x0c), q(0x0d), q(0x0e), q(0x0f),\
> > +     q(0x10), q(0x11), q(0x12), q(0x13), q(0x14), q(0x15), q(0x16), q(0x17),\
> > +     q(0x18), q(0x19), q(0x1a), q(0x1b), q(0x1c), q(0x1d), q(0x1e), q(0x1f),\
> > +     q(0x20), q(0x21), q(0x22), q(0x23), q(0x24), q(0x25), q(0x26), q(0x27),\
> > +     q(0x28), q(0x29), q(0x2a), q(0x2b), q(0x2c), q(0x2d), q(0x2e), q(0x2f),\
> > +     q(0x30), q(0x31), q(0x32), q(0x33), q(0x34), q(0x35), q(0x36), q(0x37),\
> > +     q(0x38), q(0x39), q(0x3a), q(0x3b), q(0x3c), q(0x3d), q(0x3e), q(0x3f),\
> > +     q(0x40), q(0x41), q(0x42), q(0x43), q(0x44), q(0x45), q(0x46), q(0x47),\
> > +     q(0x48), q(0x49), q(0x4a), q(0x4b), q(0x4c), q(0x4d), q(0x4e), q(0x4f),\
> > +     q(0x50), q(0x51), q(0x52), q(0x53), q(0x54), q(0x55), q(0x56), q(0x57),\
> > +     q(0x58), q(0x59), q(0x5a), q(0x5b), q(0x5c), q(0x5d), q(0x5e), q(0x5f),\
> > +     q(0x60), q(0x61), q(0x62), q(0x63), q(0x64), q(0x65), q(0x66), q(0x67),\
> > +     q(0x68), q(0x69), q(0x6a), q(0x6b), q(0x6c), q(0x6d), q(0x6e), q(0x6f),\
> > +     q(0x70), q(0x71), q(0x72), q(0x73), q(0x74), q(0x75), q(0x76), q(0x77),\
> > +     q(0x78), q(0x79), q(0x7a), q(0x7b), q(0x7c), q(0x7d), q(0x7e), q(0x7f),\
> > +     q(0x80), q(0x81), q(0x82), q(0x83), q(0x84), q(0x85), q(0x86), q(0x87),\
> > +     q(0x88), q(0x89), q(0x8a), q(0x8b), q(0x8c), q(0x8d), q(0x8e), q(0x8f),\
> > +     q(0x90), q(0x91), q(0x92), q(0x93), q(0x94), q(0x95), q(0x96), q(0x97),\
> > +     q(0x98), q(0x99), q(0x9a), q(0x9b), q(0x9c), q(0x9d), q(0x9e), q(0x9f),\
> > +     q(0xa0), q(0xa1), q(0xa2), q(0xa3), q(0xa4), q(0xa5), q(0xa6), q(0xa7),\
> > +     q(0xa8), q(0xa9), q(0xaa), q(0xab), q(0xac), q(0xad), q(0xae), q(0xaf),\
> > +     q(0xb0), q(0xb1), q(0xb2), q(0xb3), q(0xb4), q(0xb5), q(0xb6), q(0xb7),\
> > +     q(0xb8), q(0xb9), q(0xba), q(0xbb), q(0xbc), q(0xbd), q(0xbe), q(0xbf),\
> > +     q(0xc0), q(0xc1), q(0xc2), q(0xc3), q(0xc4), q(0xc5), q(0xc6), q(0xc7),\
> > +     q(0xc8), q(0xc9), q(0xca), q(0xcb), q(0xcc), q(0xcd), q(0xce), q(0xcf),\
> > +     q(0xd0), q(0xd1), q(0xd2), q(0xd3), q(0xd4), q(0xd5), q(0xd6), q(0xd7),\
> > +     q(0xd8), q(0xd9), q(0xda), q(0xdb), q(0xdc), q(0xdd), q(0xde), q(0xdf),\
> > +     q(0xe0), q(0xe1), q(0xe2), q(0xe3), q(0xe4), q(0xe5), q(0xe6), q(0xe7),\
> > +     q(0xe8), q(0xe9), q(0xea), q(0xeb), q(0xec), q(0xed), q(0xee), q(0xef),\
> > +     q(0xf0), q(0xf1), q(0xf2), q(0xf3), q(0xf4), q(0xf5), q(0xf6), q(0xf7),\
> > +     q(0xf8), q(0xf9), q(0xfa), q(0xfb), q(0xfc), q(0xfd), q(0xfe), q(0xff) \
> > +}
> > +
> > +#define xda_be(i) ( \
> > +     (i & 0x80 ? 0x4380 : 0) ^ (i & 0x40 ? 0x21c0 : 0) ^ \
> > +     (i & 0x20 ? 0x10e0 : 0) ^ (i & 0x10 ? 0x0870 : 0) ^ \
> > +     (i & 0x08 ? 0x0438 : 0) ^ (i & 0x04 ? 0x021c : 0) ^ \
> > +     (i & 0x02 ? 0x010e : 0) ^ (i & 0x01 ? 0x0087 : 0) \
> > +)
> > +
> > +#define xda_le(i) ( \
> > +     (i & 0x80 ? 0xe100 : 0) ^ (i & 0x40 ? 0x7080 : 0) ^ \
> > +     (i & 0x20 ? 0x3840 : 0) ^ (i & 0x10 ? 0x1c20 : 0) ^ \
> > +     (i & 0x08 ? 0x0e10 : 0) ^ (i & 0x04 ? 0x0708 : 0) ^ \
> > +     (i & 0x02 ? 0x0384 : 0) ^ (i & 0x01 ? 0x01c2 : 0) \
> > +)
> > +
> > +static const u16 gf2_128_mul_table_le[256] = gf128mul_dat(xda_le);
> > +
> >  /* Multiply a GF(2^8) element by the polynomial 'x' */
> >  static inline u8 gf2_8_mul_x(u8 b)
> >  {
> > @@ -292,8 +397,13 @@ typedef struct {
> >       __le64 hi;
> >  } ble128;
> >
> > +typedef struct {
> > +     __le64 hi;
> > +     __le64 lo;
> > +} be128;
> > +
> >  /* Multiply a GF(2^128) element by the polynomial 'x' */
> > -static inline void gf2_128_mul_x(ble128 *t)
> > +static inline void gf2_128_mul_x_ble(ble128 *t)
> >  {
> >       u64 lo = le64_to_cpu(t->lo);
> >       u64 hi = le64_to_cpu(t->hi);
> > @@ -302,6 +412,66 @@ static inline void gf2_128_mul_x(ble128 *t)
> >       t->lo = cpu_to_le64((lo << 1) ^ ((hi & (1ULL << 63)) ? 0x87 : 0));
> >  }
> >
> > +static inline void gf2_128_mul_x_lle(be128 *t)
> > +{
> > +     u64 hi = be64_to_cpu(t->hi);
> > +     u64 lo = be64_to_cpu(t->lo);
> > +
> > +     u64 _tt = (lo & (1ULL)) ? ((u64)0xe1 << 56) : 0;
> > +
> > +     t->lo = cpu_to_be64((lo >> 1) | (hi << 63));
> > +     t->hi = cpu_to_be64((hi >> 1) ^ _tt);
> > +}
> > +
> > +static inline void gf2_128_mul_x8_lle(be128 *t)
> > +{
> > +     u64 hi = be64_to_cpu(t->hi);
> > +     u64 lo = be64_to_cpu(t->lo);
> > +     u64 _tt = gf2_128_mul_table_le[lo & 0xff];
> > +
> > +     t->lo = cpu_to_be64((lo >> 8) | (hi << 56));
> > +     t->hi = cpu_to_be64((hi >> 8) ^ (_tt << 48));
> > +}
> > +
> > +void gf2_128_mul_lle(be128 *r, const be128 *b)
> > +{
> > +     be128 p[8];
> > +     int i;
> > +
> > +     p[0] = *r;
> > +     for (i = 0; i < 7; ++i) {
> > +             memcpy(&p[i + 1], &p[i], sizeof(be128));
> > +             gf2_128_mul_x_lle(&p[i + 1]);
> > +     }
> > +
> > +     memset(r, 0, sizeof(*r));
> > +     for (i = 0;;) {
> > +             u8 ch = ((u8 *)b)[15-i];
> > +
> > +             if (ch & 0x80)
> > +                     xor((u8 *)r, (u8 *)r, (u8 *)&p[0], sizeof(*r));
> > +             if (ch & 0x40)
> > +                     xor((u8 *)r, (u8 *)r, (u8 *)&p[1], sizeof(*r));
> > +             if (ch & 0x20)
> > +                     xor((u8 *)r, (u8 *)r, (u8 *)&p[2], sizeof(*r));
> > +             if (ch & 0x10)
> > +                     xor((u8 *)r, (u8 *)r, (u8 *)&p[3], sizeof(*r));
> > +             if (ch & 0x08)
> > +                     xor((u8 *)r, (u8 *)r, (u8 *)&p[4], sizeof(*r));
> > +             if (ch & 0x04)
> > +                     xor((u8 *)r, (u8 *)r, (u8 *)&p[5], sizeof(*r));
> > +             if (ch & 0x02)
> > +                     xor((u8 *)r, (u8 *)r, (u8 *)&p[6], sizeof(*r));
> > +             if (ch & 0x01)
> > +                     xor((u8 *)r, (u8 *)r, (u8 *)&p[7], sizeof(*r));
> > +
> > +             if (++i >= 16)
> > +                     break;
> > +
> > +             gf2_128_mul_x8_lle(r);
> > +     }
> > +}
> > +
>
> A few comments here.  This program is meant to implement all the algorithms in
> as simple a way as possible.  It doesn't have constraints like performance,
> trying to be constant-time, integration with an existing code-base, etc.
>
> With that being the case, can you try to simplify this as much as possible?  Is
> the multiplication table needed, or is that just an optimization?  You've also
> added some unused code, such as xda_be(); that's definitely not needed.

I can swap the table for an implementation of "peasant multiplication".

I will send a v2 with that and the other comments addressed.

>
> The following is definitely wrong, or at least named wrong:
>
>         typedef struct {
>                 __le64 hi;
>                 __le64 lo;
>         } be128;
>
> If it's a big endian integer, it shouldn't have little endian fields.
>
> POLYVAL also doesn't natively use lle-style field multiplication, but rather
> ble.  Wouldn't it be simpler to just implement the ble multiplication directly?
>
> > +/*----------------------------------------------------------------------------*
> > + *                                 POLVAL                                     *
> > + *----------------------------------------------------------------------------*/
>
> POLVAL => POLYVAL.
>
> For all new algorithms, please also include a link to their specification.
>
> > +static void polyval(const u8 key[POLYVAL_KEY_SIZE],
> > +                 const u8 *msg, size_t msglen, be128 *out)
>
> This isn't actually the whole POLYVAL, but rather just the "update" step.  So it
> should be called "polyval_update", and 'out' should be called something else
> since it is the accumulator (input/output).
>
> Also why does the accumulator have the type be128?  It's not big endian.  Can it
> just be a byte array here?
>
> > +     be128 h;
> > +     be128 tmp;
> > +     int nblocks = msglen / POLYVAL_BLOCK_SIZE;
> > +     int tail = msglen % POLYVAL_BLOCK_SIZE;
> > +
> > +     reverse_bytes(out);
> > +     memcpy(&h, key, sizeof(h));
> > +     reverse_bytes(&h);
> > +     gf2_128_mul_x_lle(&h);
> > +
> > +     while (nblocks > 0) {
> > +             memcpy(&tmp, msg, sizeof(tmp));
> > +             reverse_bytes(&tmp);
> > +             xor((u8 *)out, (u8 *)out, (u8 *)&tmp, sizeof(tmp));
> > +             gf2_128_mul_lle(out, &h);
> > +             msg += POLYVAL_BLOCK_SIZE;
> > +             nblocks--;
> > +     }
> > +     if (tail) {
> > +             memset(&tmp, 0, POLYVAL_BLOCK_SIZE);
> > +             memcpy(&tmp, msg, tail);
> > +             reverse_bytes(&tmp);
> > +             xor((u8 *)out, (u8 *)out, (u8 *)&tmp, sizeof(tmp));
> > +             gf2_128_mul_lle(out, &h);
> > +     }
> > +     reverse_bytes(out);
> > +}
>
> With a from-scratch implementation is it really easiest to use the reverse_bytes
> method?  I thought that this type of implementation is only recommended if there
> is an existing GHASH implementation.  Here there isn't.
>
> > +static void aes_256_xctr_crypt(const u8 key[AES_256_KEY_SIZE],
> > +                           const u8 iv[AES_BLOCK_SIZE], const u8 *src,
> > +                           u8 *dst, size_t nbytes)
> > +{
> > +     struct aes_key k;
> > +     int i;
> > +     int nblocks;
> > +     le128 ctr;
> > +     u8 keystream[AES_BLOCK_SIZE];
> > +
> > +     aes_setkey(&k, key, AES_256_KEY_SIZE);
> > +
> > +     nblocks = nbytes / AES_BLOCK_SIZE;
> > +     for (i = 0; i < nblocks; i++) {
> > +             ctr.hi = 0;
> > +             ctr.lo = cpu_to_le64(i + 1);
> > +             xor((u8 *)&ctr, (u8 *)&ctr, iv, AES_BLOCK_SIZE);
> > +             aes_encrypt(&k, (u8 *)&ctr, keystream);
> > +             xor(dst, keystream, src, AES_BLOCK_SIZE);
> > +             src += AES_BLOCK_SIZE;
> > +             dst += AES_BLOCK_SIZE;
> > +     }
> > +
> > +     if (nbytes % AES_BLOCK_SIZE != 0) {
> > +             ctr.hi = 0;
> > +             ctr.lo = cpu_to_le64(nbytes / AES_BLOCK_SIZE + 1);
> > +             xor((u8 *)&ctr, (u8 *)&ctr, iv, AES_BLOCK_SIZE);
> > +             aes_encrypt(&k, (u8 *)&ctr, keystream);
> > +             xor(dst, keystream, src, nbytes % AES_BLOCK_SIZE);
> > +     }
> > +}
>
> This can be simplified quite a bit, for example:
>
> static void aes_256_xctr_crypt(const u8 key[AES_256_KEY_SIZE],
>                                const u8 iv[AES_BLOCK_SIZE], const u8 *src,
>                                u8 *dst, size_t nbytes)
> {
>         struct aes_key k;
>         union {
>                 u8 bytes[AES_BLOCK_SIZE];
>                 __le64 ctr;
>         } blk;
>         size_t i;
>
>         aes_setkey(&k, key, AES_256_KEY_SIZE);
>
>         for (i = 0; i < nbytes; i += AES_BLOCK_SIZE) {
>                 memcpy(blk.bytes, iv, AES_BLOCK_SIZE);
>                 blk.ctr ^= cpu_to_le64(1 + (i / AES_BLOCK_SIZE));
>                 aes_encrypt(&k, blk.bytes, blk.bytes);
>                 xor(&dst[i], blk.bytes, &src[i],
>                     MIN(AES_BLOCK_SIZE, nbytes - i));
>         }
> }
>
> We are not trying to micro-optimize for performance here, so it is fine to have
> the MIN() in the loop.
>
> Also note that 'i' needs to be size_t, not int.
>
> > +#define HCTR2_IV_SIZE 32
> > +static void aes_256_hctr2_crypt(const u8 key[AES_256_KEY_SIZE],
> > +                             const u8 iv[HCTR2_IV_SIZE], const u8 *src,
> > +                             u8 *dst, size_t nbytes, bool decrypting)
> > +{
> > +     be128 digest;
> > +     u8 MM[AES_BLOCK_SIZE];
> > +     u8 UU[AES_BLOCK_SIZE];
> > +     u8 S[AES_BLOCK_SIZE];
> > +     u8 hbar[AES_BLOCK_SIZE];
> > +     u8 L[AES_BLOCK_SIZE];
> > +     u8 padded_block[POLYVAL_BLOCK_SIZE];
> > +     const u8 *M = src;
> > +     const u8 *N = src + AES_BLOCK_SIZE;
> > +     u8 *U = dst;
> > +     u8 *V = dst + AES_BLOCK_SIZE;
> > +     int bulk_bytes = nbytes - AES_BLOCK_SIZE;
> > +     int remainder = bulk_bytes % AES_BLOCK_SIZE;
> > +     struct aes_key k;
> > +     le128 tweak_block;
>
> There are a lot variables in this function.  To make it easier to read, please
> try to declare them in the order they are used.
>
> bulk_bytes and remainder should be size_t.
>
> > +
> > +     memset(hbar, 0, AES_BLOCK_SIZE);
> > +     memset(L, 0, AES_BLOCK_SIZE);
> > +     L[0] = 0x01;
>
> The above can be replaced with initializers at declaration time:
>
>         u8 hbar[AES_BLOCK_SIZE] = { 0 };
>         u8 L[AES_BLOCK_SIZE] = { 1 };
>
> > +     aes_setkey(&k, key, AES_256_KEY_SIZE);
> > +     aes_encrypt(&k, hbar, hbar);
> > +     aes_encrypt(&k, L, L);
> > +
> > +     tweak_block.hi = 0;
> > +     tweak_block.lo = cpu_to_le64(remainder ? (HCTR2_IV_SIZE * 8 * 2 + 3) :
> > +             (HCTR2_IV_SIZE * 8 * 2 + 2));
>
> Similarly for tweak_block, which really should be called something like
> 'tweaklen_blk':
>
>         le128 tweaklen_blk = {
>                 .lo = cpu_to_le64(HCTR2_IV_SIZE * 8 * 2 + 2 + (remainder != 0)),
>         };
>
> > +     memset(&digest, 0, sizeof(digest));
> > +     polyval(hbar, (u8 *)&tweak_block, POLYVAL_BLOCK_SIZE, &digest);
> > +     polyval(hbar, iv, HCTR2_IV_SIZE, &digest);
> > +
> > +     if (remainder == 0) {
> > +             polyval(hbar, N, bulk_bytes, &digest);
> > +     } else {
> > +             polyval(hbar, N, bulk_bytes - remainder, &digest);
>
> If the 'polyval(hbar, N, bulk_bytes - remainder, &digest);' is moved above the
> 'if', then the 'remainder == 0' branch will be unneeded.  Likewise later on.
>
> > +static void aes_256_hctr2_encrypt(const u8 key[AES_256_KEY_SIZE],
> > +                             const u8 iv[HCTR2_IV_SIZE], const u8 *src,
> > +                             u8 *dst, size_t nbytes)
>
> Continuation lines should be properly aligned.
>
> > +#ifdef ENABLE_ALG_TESTS
> > +#include <linux/if_alg.h>
> > +#include <sys/socket.h>
> > +static void test_aes_256_hctr2(void)
> > +{
> > +     int algfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
> > +     struct sockaddr_alg addr = {
> > +             .salg_type = "skcipher",
> > +             .salg_name = "hctr2(aes)",
> > +     };
> > +     unsigned long num_tests = NUM_ALG_TEST_ITERATIONS;
> > +
> > +     if (algfd < 0)
> > +             die_errno("can't create AF_ALG socket");
> > +     if (bind(algfd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
> > +             die_errno("can't bind AF_ALG socket to HCTR2 algorithm");
> > +
> > +     while (num_tests--) {
> > +             u8 key[AES_256_KEY_SIZE];
> > +             u8 iv[HCTR2_IV_SIZE];
> > +             u8 ptext[4096];
> > +             u8 ctext[sizeof(ptext)];
> > +             u8 ref_ctext[sizeof(ptext)];
> > +             u8 decrypted[sizeof(ptext)];
> > +             const size_t datalen = 16;
>
> This is only testing 16-byte data lengths.  It should be testing random data
> lengths >= 16 bytes and <= the array size above.
>
> > diff --git a/tests/generic/678 b/tests/generic/678
> > new file mode 100755
> > index 00000000..143e93f0
> > --- /dev/null
> > +++ b/tests/generic/678
> > @@ -0,0 +1,24 @@
> > +#! /bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright 2022 Google LLC
> > +#
> > +# FS QA Test No. 678
> > +#
> > +# Verify ciphertext for v1 encryption policies that use AES-256-XTS to encrypt
> > +# file contents and AES-256-HCTR2 to encrypt file names.
>
> I think we shouldn't add any new features to v1 encryption policies, as they are
> deprecated in favor of v2.
>
> So the kernel shouldn't allow this case, which would make this test unnecessary.
>
> - Eric



[Index of Archives]     [Linux Filesystems Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux