From: Harald Freudenberger <freude@linux.ibm.com>
To: richard.henderson@linaro.org, iii@linux.ibm.com,
david@kernel.org, thuth@redhat.com, berrange@redhat.com
Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org,
linux-s390@vger.kernel.org, dengler@linux.ibm.com,
borntraeger@linux.ibm.com, fcallies@linux.ibm.com,
cohuck@redhat.com
Subject: [PATCH v14 06/19] crypto: Add aes-helpers file to support some AES modes
Date: Thu, 6 Aug 2026 17:12:48 +0200 [thread overview]
Message-ID: <20260806151302.26846-7-freude@linux.ibm.com> (raw)
In-Reply-To: <20260806151302.26846-1-freude@linux.ibm.com>
Add a new file crypto/aes-helpers.c with simple functions
to support some AES modes:
- AES cbc: AES_cbc_encrypt() AES_cbc_decrypt()
- AES ctr: AES_ctr_encrypt()
- AES xts: AES_xts_encrypt() AES_xts_decrypt()
and some AES related helpers:
- AES_xor()
- AES_xts_prep_next_tweak()
Add header file include/crypto/aes-helpers.h for these functions
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Finn Callies <fcallies@linux.ibm.com>
Reviewed-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Acked-by: Daniel P. Berrangé <berrange@redhat.com>
---
crypto/aes-helpers.c | 106 ++++++++++++++++++++++++++++++++++
crypto/meson.build | 1 +
include/crypto/aes-helpers.h | 109 +++++++++++++++++++++++++++++++++++
3 files changed, 216 insertions(+)
create mode 100644 crypto/aes-helpers.c
create mode 100644 include/crypto/aes-helpers.h
diff --git a/crypto/aes-helpers.c b/crypto/aes-helpers.c
new file mode 100644
index 0000000000..68d848683c
--- /dev/null
+++ b/crypto/aes-helpers.c
@@ -0,0 +1,106 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * AES helper functions and mode implementations
+ *
+ * Authors:
+ * Harald Freudenberger <freude@linux.ibm.com>
+ */
+
+#include "qemu/osdep.h"
+#include "crypto/aes.h"
+#include "crypto/aes-helpers.h"
+
+void AES_xor(const unsigned char *src1, const unsigned char *src2,
+ unsigned char *dst)
+{
+ int i;
+
+ for (i = 0; i < AES_BLOCK_SIZE; i++) {
+ dst[i] = src1[i] ^ src2[i];
+ }
+}
+
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ unsigned char *iv, const AES_KEY *key)
+{
+ unsigned char buf[AES_BLOCK_SIZE];
+
+ /* in xor iv => buf */
+ AES_xor(in, iv, buf);
+ /* encrypt buf => out */
+ AES_encrypt(buf, out, key);
+ /* prep iv for next round */
+ memcpy(iv, out, AES_BLOCK_SIZE);
+}
+
+void AES_cbc_decrypt(const unsigned char *in, unsigned char *out,
+ unsigned char *iv, const AES_KEY *key)
+{
+ unsigned char buf[AES_BLOCK_SIZE];
+
+ /* decrypt in => buf */
+ AES_decrypt(in, buf, key);
+ /* buf xor iv => out */
+ AES_xor(buf, iv, out);
+ /* prep iv for next round */
+ memcpy(iv, in, AES_BLOCK_SIZE);
+}
+
+void AES_ctr_encrypt(const unsigned char *in, unsigned char *out,
+ const unsigned char *ctr, const AES_KEY *key)
+{
+ unsigned char buf[AES_BLOCK_SIZE];
+
+ /* encrypt ctr => buf */
+ AES_encrypt(ctr, buf, key);
+ /* exor input data with encrypted ctr => out */
+ AES_xor(in, buf, out);
+}
+
+/*
+ * Tweak calculation for AES XTS.
+ * Multiply tweak by α (x) in GF(2^128) per IEEE 1619-2007. The tweak
+ * is a 128-bit little-endian integer (tweak[0]=LSB, tweak[15]=MSB).
+ * This implementation has been verified on little and big endian.
+ */
+void AES_xts_prep_next_tweak(unsigned char *tweak)
+{
+ unsigned char carry;
+ int i;
+
+ carry = tweak[AES_BLOCK_SIZE - 1] >> 7;
+
+ for (i = AES_BLOCK_SIZE - 1; i > 0; i--) {
+ tweak[i] = (unsigned char)((tweak[i] << 1) | (tweak[i - 1] >> 7));
+ }
+
+ tweak[i] = (unsigned char)(tweak[i] << 1);
+ tweak[i] ^= (unsigned char)(0x87 & (unsigned char)(-(unsigned char)carry));
+}
+
+void AES_xts_encrypt(const unsigned char *in, unsigned char *out,
+ const unsigned char *tweak, const AES_KEY *key)
+{
+ unsigned char buf1[AES_BLOCK_SIZE], buf2[AES_BLOCK_SIZE];
+
+ /* in xor tweak => buf1 */
+ AES_xor(in, tweak, buf1);
+ /* encrypt buf1 => buf2 */
+ AES_encrypt(buf1, buf2, key);
+ /* buf2 xor tweak => out */
+ AES_xor(buf2, tweak, out);
+}
+
+void AES_xts_decrypt(const unsigned char *in, unsigned char *out,
+ const unsigned char *tweak, const AES_KEY *key)
+{
+ unsigned char buf1[AES_BLOCK_SIZE], buf2[AES_BLOCK_SIZE];
+
+ /* in xor tweak => buf1 */
+ AES_xor(in, tweak, buf1);
+ /* encrypt buf1 => buf2 */
+ AES_decrypt(buf1, buf2, key);
+ /* buf2 xor tweak => out */
+ AES_xor(buf2, tweak, out);
+}
diff --git a/crypto/meson.build b/crypto/meson.build
index 6ac83857aa..534b995c9b 100644
--- a/crypto/meson.build
+++ b/crypto/meson.build
@@ -55,6 +55,7 @@ system_ss.add(when: gnutls, if_true: files('tls-cipher-suites.c'))
util_ss.add(files(
'aes.c',
+ 'aes-helpers.c',
'clmul.c',
'init.c',
'sm4.c',
diff --git a/include/crypto/aes-helpers.h b/include/crypto/aes-helpers.h
new file mode 100644
index 0000000000..9a94c48d86
--- /dev/null
+++ b/include/crypto/aes-helpers.h
@@ -0,0 +1,109 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * AES helper functions and modes
+ */
+
+#ifndef QEMU_AES_HELPERS_H
+#define QEMU_AES_HELPERS_H
+
+/**
+ * AES_xor:
+ * @src1: first source buffer of AES_BLOCK_SIZE bytes
+ * @src2: second source buffer of AES_BLOCK_SIZE bytes
+ * @dst: destination buffer of AES_BLOCK_SIZE bytes
+ *
+ * Bitwise XOR operation between two AES blocks.
+ */
+void AES_xor(const unsigned char *src1, const unsigned char *src2,
+ unsigned char *dst);
+
+/**
+ * AES_cbc_encrypt:
+ * @in: input plaintext block of AES_BLOCK_SIZE bytes
+ * @out: output ciphertext block of AES_BLOCK_SIZE bytes
+ * @iv: IV, updated after processing for chaining
+ * @key: AES key
+ *
+ * Single block AES encrypt in CBC (Cipher Block Chaining) mode.
+ * The input block is XORed with the IV, then encrypted with AES.
+ * IV is updated at the end and is prepared for the next invocation.
+ */
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ unsigned char *iv, const AES_KEY *key);
+
+/**
+ * AES_cbc_decrypt:
+ * @in: input ciphertext block of AES_BLOCK_SIZE bytes
+ * @out: output plaintext block of AES_BLOCK_SIZE bytes
+ * @iv: initialization vector, updated to input block for chaining
+ * @key: AES key
+ *
+ * Single block AES decrypt in CBC (Cipher Block Chaining) mode.
+ * The input block is decrypted, then XORed with the IV.
+ * IV is updated at the end and is prepared for the next invocation.
+ */
+void AES_cbc_decrypt(const unsigned char *in, unsigned char *out,
+ unsigned char *iv, const AES_KEY *key);
+
+/**
+ * AES_ctr_encrypt:
+ * @in: input data block of AES_BLOCK_SIZE bytes
+ * @out: output data block of AES_BLOCK_SIZE bytes
+ * @ctr: counter value of AES_BLOCK_SIZE bytes
+ * @key: AES key
+ *
+ * Single block AES encrypt/decrypt in CTR (Counter) mode.
+ * The counter block is encrypted, then XORed with the
+ * input data block.
+ * In CTR mode encrypt and decrypt are identical operations.
+ * Note that the caller is responsible for incrementing the
+ * counter block.
+ */
+void AES_ctr_encrypt(const unsigned char *in, unsigned char *out,
+ const unsigned char *ctr, const AES_KEY *key);
+
+/**
+ * AES_xts_prep_next_tweak:
+ * @tweak: pointer to tweak value to be updated (16 bytes buffer
+ * containing a 128 bit little endian integer)
+ *
+ * Tweak calculation for AES XTS.
+ * Prepares the next tweak value for AES-XTS mode by multiplying
+ * the current tweak by α (x) in GF(2^128) according to IEEE 1619-2007.
+ */
+void AES_xts_prep_next_tweak(unsigned char *tweak);
+
+/**
+ * AES_xts_encrypt:
+ * @in: input plaintext block of AES_BLOCK_SIZE bytes
+ * @out: output ciphertext block of AES_BLOCK_SIZE bytes
+ * @tweak: tweak value (16 bytes)
+ * @key: AES key
+ *
+ * Single block AES encrypt in XTS mode.
+ * The input is XORed with the tweak, encrypted, then XORed with
+ * the tweak again to produce the output.
+ * Note that the caller is responsible for managing the tweak value.
+ * Use AES_xts_prep_next_tweak() to advance the tweak for the next block.
+ */
+void AES_xts_encrypt(const unsigned char *in, unsigned char *out,
+ const unsigned char *tweak, const AES_KEY *key);
+
+/**
+ * AES_xts_decrypt:
+ * @in: input ciphertext block of AES_BLOCK_SIZE bytes
+ * @out: output plaintext block of AES_BLOCK_SIZE bytes
+ * @tweak: tweak value (16 bytes)
+ * @key: AES key
+ *
+ * Single block AES decrypt in XTS mode.
+ * The input is XORed with the tweak, decrypted, then XORed with
+ * the tweak again to produce the output.
+ * Note that the caller is responsible for managing the tweak value.
+ * Use AES_xts_prep_next_tweak() to advance the tweak for the next block.
+ */
+void AES_xts_decrypt(const unsigned char *in, unsigned char *out,
+ const unsigned char *tweak, const AES_KEY *key);
+
+#endif
--
2.43.0
next prev parent reply other threads:[~2026-08-06 15:13 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-06 15:12 [PATCH v14 00/19] target/s390x: Extend qemu CPACF support Harald Freudenberger
2026-08-06 15:12 ` [PATCH v14 01/19] target/s390x: Fix missing privileged flag at PCKMO instruction Harald Freudenberger
2026-08-06 18:48 ` Ilya Leoshkevich
2026-08-06 15:12 ` [PATCH v14 02/19] target/s390x: Rework s390 cpacf implementations Harald Freudenberger
2026-08-06 15:12 ` [PATCH v14 03/19] target/s390x: Move cpacf sha512 code into a new file Harald Freudenberger
2026-08-06 15:12 ` [PATCH v14 04/19] target/s390x: Support cpacf sha256 Harald Freudenberger
2026-08-06 15:12 ` [PATCH v14 05/19] target/s390x: Add helper functions for copy memory to and from guest Harald Freudenberger
2026-08-06 15:12 ` Harald Freudenberger [this message]
2026-08-06 15:12 ` [PATCH v14 07/19] target/s390x: Support AES ECB for cpacf km instruction Harald Freudenberger
2026-08-06 15:12 ` [PATCH v14 08/19] target/s390x: Support AES CBC for cpacf kmc instruction Harald Freudenberger
2026-08-06 15:12 ` [PATCH v14 09/19] target/s390x: Support AES CTR for cpacf kmctr instruction Harald Freudenberger
2026-08-06 15:12 ` [PATCH v14 10/19] target/s390x: Minimal AES XTS support for cpacf pcc instruction Harald Freudenberger
2026-08-06 15:12 ` [PATCH v14 11/19] target/s390x: Support AES XTS for cpacf km instruction Harald Freudenberger
2026-08-06 15:12 ` [PATCH v14 12/19] target/s390x: Base support for cpacf protected keys and pckmo Harald Freudenberger
2026-08-06 15:12 ` [PATCH v14 13/19] target/s390x: Support protected key AES ECB for cpacf km instruction Harald Freudenberger
2026-08-06 15:12 ` [PATCH v14 14/19] target/s390x: Support protected key AES CBC for cpacf kmc instruction Harald Freudenberger
2026-08-06 15:12 ` [PATCH v14 15/19] target/s390x: Support protected key AES CTR for cpacf kmctr instruction Harald Freudenberger
2026-08-06 15:12 ` [PATCH v14 16/19] target/s390x: Minimal protected key AES XTS support for cpacf pcc instruction Harald Freudenberger
2026-08-06 15:12 ` [PATCH v14 17/19] target/s390x: Support protected key AES XTS for cpacf km instruction Harald Freudenberger
2026-08-06 15:13 ` [PATCH v14 18/19] docs/s390: Document CPACF instructions support Harald Freudenberger
2026-08-06 15:13 ` [PATCH v14 19/19] tests/tcg/s390x: Add tests for CPACF instructions Harald Freudenberger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260806151302.26846-7-freude@linux.ibm.com \
--to=freude@linux.ibm.com \
--cc=berrange@redhat.com \
--cc=borntraeger@linux.ibm.com \
--cc=cohuck@redhat.com \
--cc=david@kernel.org \
--cc=dengler@linux.ibm.com \
--cc=fcallies@linux.ibm.com \
--cc=iii@linux.ibm.com \
--cc=linux-s390@vger.kernel.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-s390x@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.