Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/crypto/aes/arch/x86 Implement AES-CCM with x86 AES-NI.
details: https://anonhg.NetBSD.org/src/rev/7cb780b7fb3b
branches: trunk
changeset: 936312:7cb780b7fb3b
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sat Jul 25 22:29:06 2020 +0000
description:
Implement AES-CCM with x86 AES-NI.
diffstat:
sys/crypto/aes/arch/x86/aes_ni.c | 49 ++++++++++-
sys/crypto/aes/arch/x86/aes_ni.h | 9 +-
sys/crypto/aes/arch/x86/aes_ni_64.S | 167 +++++++++++++++++++++++++++++++++++-
3 files changed, 221 insertions(+), 4 deletions(-)
diffs (286 lines):
diff -r 1ae0d2b17233 -r 7cb780b7fb3b sys/crypto/aes/arch/x86/aes_ni.c
--- a/sys/crypto/aes/arch/x86/aes_ni.c Sat Jul 25 22:28:27 2020 +0000
+++ b/sys/crypto/aes/arch/x86/aes_ni.c Sat Jul 25 22:29:06 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: aes_ni.c,v 1.3 2020/07/25 22:12:57 riastradh Exp $ */
+/* $NetBSD: aes_ni.c,v 1.4 2020/07/25 22:29:06 riastradh Exp $ */
/*-
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: aes_ni.c,v 1.3 2020/07/25 22:12:57 riastradh Exp $");
+__KERNEL_RCSID(1, "$NetBSD: aes_ni.c,v 1.4 2020/07/25 22:29:06 riastradh Exp $");
#ifdef _KERNEL
#include <sys/types.h>
@@ -204,6 +204,48 @@
fpu_kern_leave();
}
+static void
+aesni_cbcmac_update1_impl(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);
+
+ fpu_kern_enter();
+ aesni_cbcmac_update1(enc, in, nbytes, auth, nrounds);
+ fpu_kern_leave();
+}
+
+static void
+aesni_ccm_enc1_impl(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)
+{
+
+ KASSERT(nbytes);
+ KASSERT(nbytes % 16 == 0);
+
+ fpu_kern_enter();
+ aesni_ccm_enc1(enc, in, out, nbytes, authctr, nrounds);
+ fpu_kern_leave();
+}
+
+static void
+aesni_ccm_dec1_impl(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)
+{
+
+ KASSERT(nbytes);
+ KASSERT(nbytes % 16 == 0);
+
+ fpu_kern_enter();
+ aesni_ccm_dec1(enc, in, out, nbytes, authctr, nrounds);
+ fpu_kern_leave();
+}
+
static int
aesni_xts_update_selftest(void)
{
@@ -273,4 +315,7 @@
.ai_cbc_dec = aesni_cbc_dec_impl,
.ai_xts_enc = aesni_xts_enc_impl,
.ai_xts_dec = aesni_xts_dec_impl,
+ .ai_cbcmac_update1 = aesni_cbcmac_update1_impl,
+ .ai_ccm_enc1 = aesni_ccm_enc1_impl,
+ .ai_ccm_dec1 = aesni_ccm_dec1_impl,
};
diff -r 1ae0d2b17233 -r 7cb780b7fb3b sys/crypto/aes/arch/x86/aes_ni.h
--- a/sys/crypto/aes/arch/x86/aes_ni.h Sat Jul 25 22:28:27 2020 +0000
+++ b/sys/crypto/aes/arch/x86/aes_ni.h Sat Jul 25 22:29:06 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: aes_ni.h,v 1.2 2020/07/25 22:12:57 riastradh Exp $ */
+/* $NetBSD: aes_ni.h,v 1.3 2020/07/25 22:29:06 riastradh Exp $ */
/*-
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -66,6 +66,13 @@
uint8_t[static 128], size_t, uint8_t[static 16], uint32_t);
void aesni_xts_update(const uint8_t[static 16], uint8_t[static 16]);
+void aesni_cbcmac_update1(const struct aesenc *, const uint8_t[static 16],
+ size_t, uint8_t[static 16], uint32_t);
+void aesni_ccm_enc1(const struct aesenc *, const uint8_t[static 16],
+ uint8_t[static 16], size_t, uint8_t[static 32], uint32_t);
+void aesni_ccm_dec1(const struct aesenc *, const uint8_t[static 16],
+ uint8_t[static 16], size_t, uint8_t[static 32], uint32_t);
+
extern struct aes_impl aes_ni_impl;
#endif /* _CRYPTO_AES_ARCH_X86_AES_NI_H */
diff -r 1ae0d2b17233 -r 7cb780b7fb3b sys/crypto/aes/arch/x86/aes_ni_64.S
--- a/sys/crypto/aes/arch/x86/aes_ni_64.S Sat Jul 25 22:28:27 2020 +0000
+++ b/sys/crypto/aes/arch/x86/aes_ni_64.S Sat Jul 25 22:29:06 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: aes_ni_64.S,v 1.3 2020/07/25 22:11:05 riastradh Exp $ */
+/* $NetBSD: aes_ni_64.S,v 1.4 2020/07/25 22:29:06 riastradh Exp $ */
/*-
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -951,6 +951,142 @@
END(aesni_xts_update)
/*
+ * aesni_cbcmac_update1(const struct aesenc *enckey@rdi, const uint8_t *in@rsi,
+ * size_t nbytes@rdx, uint8_t auth[16] @rcx, uint32_t nrounds@r8d)
+ *
+ * Update CBC-MAC.
+ *
+ * nbytes must be a positive integral multiple of 16.
+ *
+ * Standard ABI calling convention.
+ */
+ENTRY(aesni_cbcmac_update1)
+ movdqu (%rcx),%xmm0 /* xmm0 := auth */
+ mov %rdx,%r10 /* r10 := nbytes */
+ mov %rcx,%rdx /* rdx := &auth */
+1: pxor (%rsi),%xmm0 /* xmm0 ^= plaintext block */
+ lea 0x10(%rsi),%rsi
+ mov %r8d,%ecx /* ecx := nrounds */
+ call aesni_enc1 /* xmm0 := auth'; trash rax,rcx,xmm8 */
+ sub $0x10,%r10
+ jnz 1b
+ movdqu %xmm0,(%rdx) /* store auth' */
+ ret
+END(aesni_cbcmac_update1)
+
+/*
+ * aesni_ccm_enc1(const struct aesenc *enckey@rdi, const uint8_t *in@rsi,
+ * uint8_t *out@rdx, size_t nbytes@rcx,
+ * uint8_t authctr[32] @r8, uint32_t nrounds@r9d)
+ *
+ * Update CCM encryption.
+ *
+ * nbytes must be a positive integral multiple of 16.
+ *
+ * Standard ABI calling convention.
+ */
+ENTRY(aesni_ccm_enc1)
+ mov %rcx,%r10 /* r10 := nbytes */
+ movdqu 0x10(%r8),%xmm2 /* xmm2 := ctr (be) */
+ movdqa bswap32(%rip),%xmm4 /* xmm4 := bswap32 table */
+ movdqa ctr32_inc(%rip),%xmm5 /* xmm5 := (0,0,0,1) (le) */
+ movdqu (%r8),%xmm0 /* xmm0 := auth */
+ pshufb %xmm4,%xmm2 /* xmm2 := ctr (le) */
+1: movdqu (%rsi),%xmm3 /* xmm3 := plaintext block */
+ paddd %xmm5,%xmm2 /* increment ctr (32-bit) */
+ lea 0x10(%rsi),%rsi
+ movdqa %xmm2,%xmm1 /* xmm1 := ctr (le) */
+ mov %r9d,%ecx /* ecx := nrounds */
+ pshufb %xmm4,%xmm1 /* xmm1 := ctr (be) */
+ pxor %xmm3,%xmm0 /* xmm0 := auth ^ ptxt */
+ call aesni_enc2 /* trash rax/rcx/xmm8 */
+ pxor %xmm1,%xmm3 /* xmm3 := ciphertext block */
+ sub $0x10,%r10 /* count down bytes */
+ movdqu %xmm3,(%rdx) /* store ciphertext block */
+ lea 0x10(%rdx),%rdx
+ jnz 1b /* repeat if more blocks */
+ pshufb %xmm4,%xmm2 /* xmm2 := ctr (be) */
+ movdqu %xmm0,(%r8) /* store updated auth */
+ movdqu %xmm2,0x10(%r8) /* store updated ctr */
+ ret
+END(aesni_ccm_enc1)
+
+/*
+ * aesni_ccm_dec1(const struct aesenc *enckey@rdi, const uint8_t *in@rsi,
+ * uint8_t *out@rdx, size_t nbytes@rcx,
+ * uint8_t authctr[32] @r8, uint32_t nrounds@r9d)
+ *
+ * Update CCM decryption.
+ *
+ * nbytes must be a positive integral multiple of 16.
+ *
+ * Standard ABI calling convention.
+ */
+ENTRY(aesni_ccm_dec1)
+ movdqu 0x10(%r8),%xmm2 /* xmm2 := ctr (be) */
+ movdqa bswap32(%rip),%xmm4 /* xmm4 := bswap32 table */
+ movdqa ctr32_inc(%rip),%xmm5 /* xmm5 := (0,0,0,1) (le) */
+ movdqu (%r8),%xmm1 /* xmm1 := auth */
+ pshufb %xmm4,%xmm2 /* xmm2 := ctr (le) */
+ mov %rcx,%r10 /* r10 := nbytes */
+
+ /* Decrypt the first block. */
+ paddd %xmm5,%xmm2 /* increment ctr (32-bit) */
+ mov %r9d,%ecx /* ecx := nrounds */
+ movdqa %xmm2,%xmm0 /* xmm0 := ctr (le) */
+ movdqu (%rsi),%xmm3 /* xmm3 := ctxt */
+ pshufb %xmm4,%xmm0 /* xmm0 := ctr (be) */
+ lea 0x10(%rsi),%rsi
+ call aesni_enc1 /* xmm0 := pad; trash rax/rcx/xmm8 */
+ jmp 2f
+
+1: /*
+ * Authenticate the last block and decrypt the next block
+ * simultaneously.
+ *
+ * xmm1 = auth ^ ptxt[-1]
+ * xmm2 = ctr[-1] (le)
+ */
+ paddd %xmm5,%xmm2 /* increment ctr (32-bit) */
+ mov %r9d,%ecx /* ecx := nrounds */
+ movdqa %xmm2,%xmm0 /* xmm0 := ctr (le) */
+ movdqu (%rsi),%xmm3 /* xmm3 := ctxt */
+ pshufb %xmm4,%xmm0 /* xmm0 := ctr (be) */
+ lea 0x10(%rsi),%rsi
+ call aesni_enc2 /* xmm0 := pad, xmm1 := auth';
+ * trash rax/rcx/xmm8 */
+2: pxor %xmm0,%xmm3 /* xmm3 := ptxt */
+ sub $0x10,%r10
+ movdqu %xmm3,(%rdx) /* store plaintext */
+ lea 0x10(%rdx),%rdx
+ pxor %xmm3,%xmm1 /* xmm1 := auth ^ ptxt */
+ jnz 1b
+
+ /* Authenticate the last block. */
+ movdqa %xmm1,%xmm0 /* xmm0 := auth ^ ptxt */
+ mov %r9d,%ecx /* ecx := nrounds */
+ call aesni_enc1 /* xmm0 := auth' */
+ pshufb %xmm4,%xmm2 /* xmm2 := ctr (be) */
+ movdqu %xmm0,(%r8) /* store updated auth */
+ movdqu %xmm2,0x10(%r8) /* store updated ctr */
+ ret
+END(aesni_ccm_dec1)
+
+ .section .rodata
+ .p2align 4
+ .type bswap32,@object
+bswap32:
+ .byte 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12
+END(bswap32)
+
+ .section .rodata
+ .p2align 4
+ .type ctr32_inc,@object
+ctr32_inc:
+ .byte 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,0,0,0
+END(ctr32_inc)
+
+/*
* aesni_enc1(const struct aesenc *enckey@rdi, uint128_t block@xmm0,
* uint32_t nrounds@ecx)
*
@@ -976,6 +1112,35 @@
END(aesni_enc1)
/*
+ * aesni_enc2(const struct aesenc *enckey@rdi, uint128_t block0@xmm0,
+ * uint128_t block1@xmm1, uint32_t nrounds@ecx)
+ *
+ * Encrypt two AES blocks in %xmm0 and %xmm1.
+ *
+ * Internal ABI. Uses %rax and %xmm8 as temporaries. Destroys %ecx.
+ */
+ .text
+ _ALIGN_TEXT
+ .type aesni_enc2,@function
+aesni_enc2:
+ movdqa (%rdi),%xmm8 /* xmm8 := first round key */
+ shl $4,%ecx /* ecx := total byte size of round keys */
+ lea 0x10(%rdi,%rcx),%rax /* rax := end of round key array */
+ neg %rcx /* rcx := byte offset of round key from end */
+ pxor %xmm8,%xmm0 /* xor in first round key */
+ pxor %xmm8,%xmm1
+ jmp 2f
+1: aesenc %xmm8,%xmm0
+ aesenc %xmm8,%xmm1
+2: movdqa (%rax,%rcx),%xmm8 /* load round key */
+ add $0x10,%rcx
+ jnz 1b /* repeat if there's more */
+ aesenclast %xmm8,%xmm0
+ aesenclast %xmm8,%xmm1
+ ret
+END(aesni_enc2)
+
+/*
* aesni_enc8(const struct aesenc *enckey@rdi, uint128_t block0@xmm0, ...,
* block7@xmm7, uint32_t nrounds@ecx)
*
Home |
Main Index |
Thread Index |
Old Index