crypto: add FIPS 204 ML-DSA verification
Subsystems (3)
cover crypto: add FIPS 204 ML-DSA verification
Classical signature schemes such as RSA and ECDSA are vulnerable to attacks by sufficiently powerful quantum computers. This series adds ML-DSA verification as a first step towards post-quantum cryptography (PQC) support in U-Boot.
This RFC adds generic verification support for pure FIPS 204 ML-DSA without an external message prehash. SHAKE hashing remains part of the ML-DSA algorithm. HashML-DSA is not supported. See FIPS 204 Section 5.3:
https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.204.pdf
It supports ML-DSA-44, ML-DSA-65 and ML-DSA-87. The implementation is verification-only. It contains no target signing code or private-key handling.
This series targets U-Boot proper. SPL support is not included. Verification allocates approximately 8 to 12 KB of heap workspace depending on the parameter set and ABI alignment. This excludes allocator overhead. Any future SPL integration will need to account for heap availability, stack usage and code size.
The verifier is adapted from the Linux crypto library implementation. The series preserves the Linux licensing, copyright notices and source provenance. Linux facilities are replaced with direct U-Boot equivalents where needed.
ML-DSA requires SHAKE128 and SHAKE256. The series adds generic one-shot and incremental SHAKE interfaces backed by Keccak-f[1600]. This code can be used by consumers other than ML-DSA.
The public ML-DSA API accepts raw FIPS 204 public keys, raw signatures and one contiguous message.
The tests are based on Linux KUnit tests and cover all three ML-DSA parameter sets with valid and invalid inputs. SHAKE128 and SHAKE256 are checked against FIPS 202 known answers.
Validated with sandbox and qemu_arm64_defconfig builds plus the SHAKE and ML-DSA unit tests on sandbox.
This series does not add FIT semantics or mkimage signing. A follow-up series can add a generic incremental transcript, target FIT verification and host signing.
Feedback is welcome on the public API and Kconfig placement.
Ayoub Zaki (4):
crypto: add SHAKE128 and SHAKE256 support
crypto: add FIPS 204 ML-DSA verification
test: add ML-DSA verification tests
doc: describe ML-DSA verification
doc/develop/index.rst | 1 + doc/develop/mldsa.rst | 67 ++ include/crypto/mldsa.h | 67 ++ include/crypto/sha3.h | 353 +++++++ lib/Kconfig | 14 + lib/crypto/Makefile | 3 + lib/crypto/mldsa.c | 679 +++++++++++++ lib/crypto/sha3.c | 382 ++++++++ test/Kconfig | 9 + test/lib/Makefile | 1 + test/lib/mldsa-testvecs.h | 1896 +++++++++++++++++++++++++++++++++++++ test/lib/mldsa.c | 383 ++++++++ 12 files changed, 3855 insertions(+) create mode 100644 doc/develop/mldsa.rst create mode 100644 include/crypto/mldsa.h create mode 100644 include/crypto/sha3.h create mode 100644 lib/crypto/mldsa.c create mode 100644 lib/crypto/sha3.c create mode 100644 test/lib/mldsa-testvecs.h create mode 100644 test/lib/mldsa.c
Signature · 1 line
2.43.0
PATCH 1/4 crypto: add SHAKE128 and SHAKE256 support
Add generic incremental and one-shot SHAKE interfaces backed by Keccak-f[1600].
Adapt the implementation from the Linux SHA-3 library introduced by commit 0593447248044ab609b43b947d0e198c887ac281. Retain its provenance and licensing.
--- include/crypto/sha3.h | 353 ++++++++++++++++++++++++++++++++++++++ lib/crypto/sha3.c | 382 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 735 insertions(+) create mode 100644 include/crypto/sha3.h create mode 100644 lib/crypto/sha3.c
include/crypto/sha3.h new file +353 -0
@@ -0,0 +1,353 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* Common values for SHA-3 algorithms +* +* Based on Linux include/crypto/sha3.h +* at commit: +* https://git.kernel.org/linus/f1799d17285ca99243328cd92133a9f84ee3a593 +* +* Ported to U-Boot by Ayoub Zaki <[email protected]> +*/ +#ifndef __CRYPTO_SHA3_H__ +#define __CRYPTO_SHA3_H__ + +#include <compiler.h> +#include <linux/types.h> +#include <linux/string.h> + +#define SHA3_224_DIGEST_SIZE (224 / 8) +#define SHA3_224_BLOCK_SIZE (200 - 2 * SHA3_224_DIGEST_SIZE) +#define SHA3_224_EXPORT_SIZE SHA3_STATE_SIZE + SHA3_224_BLOCK_SIZE + 1 + +#define SHA3_256_DIGEST_SIZE (256 / 8) +#define SHA3_256_BLOCK_SIZE (200 - 2 * SHA3_256_DIGEST_SIZE) +#define SHA3_256_EXPORT_SIZE SHA3_STATE_SIZE + SHA3_256_BLOCK_SIZE + 1 + +#define SHA3_384_DIGEST_SIZE (384 / 8) +#define SHA3_384_BLOCK_SIZE (200 - 2 * SHA3_384_DIGEST_SIZE) +#define SHA3_384_EXPORT_SIZE SHA3_STATE_SIZE + SHA3_384_BLOCK_SIZE + 1 + +#define SHA3_512_DIGEST_SIZE (512 / 8) +#define SHA3_512_BLOCK_SIZE (200 - 2 * SHA3_512_DIGEST_SIZE) +#define SHA3_512_EXPORT_SIZE SHA3_STATE_SIZE + SHA3_512_BLOCK_SIZE + 1 + +/* +* SHAKE128 and SHAKE256 actually have variable output size, but this is used to +* calculate the block size (rate) analogously to the above. +*/ +#define SHAKE128_DEFAULT_SIZE (128 / 8) +#define SHAKE128_BLOCK_SIZE (200 - 2 * SHAKE128_DEFAULT_SIZE) +#define SHAKE256_DEFAULT_SIZE (256 / 8) +#define SHAKE256_BLOCK_SIZE (200 - 2 * SHAKE256_DEFAULT_SIZE) + +#define SHA3_STATE_SIZE 200 + +/* +* State for the Keccak-f[1600] permutation: 25 64-bit words. +* +* We usually keep the state words as little-endian, to make absorbing and +* squeezing easier. (It means that absorbing and squeezing can just treat the +* state as a byte array.) The state words are converted to native-endian only +* temporarily by implementations of the permutation that need native-endian +* words. Of course, that conversion is a no-op on little-endian machines. +*/ +struct sha3_state { +union { +__le64 words[SHA3_STATE_SIZE /8 ]; +u8 bytes[SHA3_STATE_SIZE ]; + +u64 native_words[SHA3_STATE_SIZE /8 ];/* see comment above */ + }; +}; + +/* Internal context, shared by the digests (SHA3-*) and the XOFs (SHAKE*) */ +struct __sha3_ctx { +struct sha3_state state; +u8 digest_size;/* Digests only: the digest size in bytes */ +u8 block_size;/* Block size in bytes */ +u8 absorb_offset;/* Index of next state byte to absorb into */ +u8 squeeze_offset;/* XOFs only: index of next state byte to extract */ +}; + +void __sha3_update (struct __sha3_ctx *ctx,const u8 *in,size_t in_len); + +/** +* struct sha3_ctx - Context for SHA3-224, SHA3-256, SHA3-384, or SHA3-512 +* @ctx: private +*/ +struct sha3_ctx { +struct __sha3_ctx ctx; +}; + +/** +* sha3_zeroize_ctx() - Zeroize a SHA-3 context +* @ctx: The context to zeroize +* +* This is already called by sha3_final(). Call this explicitly when abandoning +* a context without calling sha3_final(). +*/ +static inline void sha3_zeroize_ctx (struct sha3_ctx *ctx) +{ +memset (ctx,0 ,sizeof (*ctx)); +barrier_data (ctx); +} + +/** +* struct shake_ctx - Context for SHAKE128 or SHAKE256 +* @ctx: private +*/ +struct shake_ctx { +struct __sha3_ctx ctx; +}; + +/** +* shake_zeroize_ctx() - Zeroize a SHAKE context +* @ctx: The context to zeroize +* +* Call this after the last squeeze. +*/ +static inline void shake_zeroize_ctx (struct shake_ctx *ctx) +{ +memset (ctx,0 ,sizeof (*ctx)); +barrier_data (ctx); +} + +/** +* sha3_224_init() - Initialize a context for SHA3-224 +* @ctx: The context to initialize +* +* This begins a new SHA3-224 message digest computation. +* +* Context: Any context. +*/ +static inline void sha3_224_init (struct sha3_ctx *ctx) +{ + *ctx = (struct sha3_ctx ){ + .ctx.digest_size =SHA3_224_DIGEST_SIZE , + .ctx.block_size =SHA3_224_BLOCK_SIZE , + }; +} + +/** +* sha3_256_init() - Initialize a context for SHA3-256 +* @ctx: The context to initialize +* +* This begins a new SHA3-256 message digest computation. +* +* Context: Any context. +*/ +static inline void sha3_256_init (struct sha3_ctx *ctx) +{ + *ctx = (struct sha3_ctx ){ + .ctx.digest_size =SHA3_256_DIGEST_SIZE , + .ctx.block_size =SHA3_256_BLOCK_SIZE , + }; +} + +/** +* sha3_384_init() - Initialize a context for SHA3-384 +* @ctx: The context to initialize +* +* This begins a new SHA3-384 message digest computation. +* +* Context: Any context. +*/ +static inline void sha3_384_init (struct sha3_ctx *ctx) +{ + *ctx = (struct sha3_ctx ){ + .ctx.digest_size =SHA3_384_DIGEST_SIZE , + .ctx.block_size =SHA3_384_BLOCK_SIZE , + }; +} + +/** +* sha3_512_init() - Initialize a context for SHA3-512 +* @ctx: The context to initialize +* +* This begins a new SHA3-512 message digest computation. +* +* Context: Any context. +*/ +static inline void sha3_512_init (struct sha3_ctx *ctx) +{ + *ctx = (struct sha3_ctx ){ + .ctx.digest_size =SHA3_512_DIGEST_SIZE , + .ctx.block_size =SHA3_512_BLOCK_SIZE , + }; +} + +/** +* sha3_update() - Update a SHA-3 digest context with input data +* @ctx: The context to update; must have been initialized +* @in: The input data +* @in_len: Length of the input data in bytes +* +* This can be called any number of times to add data to a SHA3-224, SHA3-256, +* SHA3-384, or SHA3-512 digest (depending on which init function was called). +* +* Context: Any context. +*/ +static inline void sha3_update (struct sha3_ctx *ctx, +const u8 *in,size_t in_len) +{ +__sha3_update (&ctx->ctx, in, in_len); +} + +/** +* sha3_final() - Finish computing a SHA-3 message digest +* @ctx: The context to finalize; must have been initialized +* @out: (output) The resulting SHA3-224, SHA3-256, SHA3-384, or SHA3-512 +* message digest, matching the init function that was called. Note that +* the size differs for each one; see SHA3_*_DIGEST_SIZE. +* +* After finishing, this zeroizes @ctx. So the caller does not need to do it. +* +* Context: Any context. +*/ +void sha3_final (struct sha3_ctx *ctx,u8 *out); + +/** +* shake128_init() - Initialize a context for SHAKE128 +* @ctx: The context to initialize +* +* This begins a new SHAKE128 extendable-output function (XOF) computation. +* +* Context: Any context. +*/ +static inline void shake128_init (struct shake_ctx *ctx) +{ + *ctx = (struct shake_ctx ){ + .ctx.block_size =SHAKE128_BLOCK_SIZE , + }; +} + +/** +* shake256_init() - Initialize a context for SHAKE256 +* @ctx: The context to initialize +* +* This begins a new SHAKE256 extendable-output function (XOF) computation. +* +* Context: Any context. +*/ +static inline void shake256_init (struct shake_ctx *ctx) +{ + *ctx = (struct shake_ctx ){ + .ctx.block_size =SHAKE256_BLOCK_SIZE , + }; +} + +/** +* shake_update() - Update a SHAKE context with input data +* @ctx: The context to update; must have been initialized +* @in: The input data +* @in_len: Length of the input data in bytes +* +* This can be called any number of times to add more input data to SHAKE128 or +* SHAKE256. This cannot be called after squeezing has begun. +* +* Context: Any context. +*/ +static inline void shake_update (struct shake_ctx *ctx, +const u8 *in,size_t in_len) +{ +__sha3_update (&ctx->ctx, in, in_len); +} + +/** +* shake_squeeze() - Generate output from SHAKE128 or SHAKE256 +* @ctx: The context to squeeze; must have been initialized +* @out: Where to write the resulting output data +* @out_len: The amount of data to extract to @out in bytes +* +* This may be called multiple times. A number of consecutive squeezes laid +* end-to-end will yield the same output as one big squeeze generating the same +* total amount of output. More input cannot be provided after squeezing has +* begun. After the last squeeze, call shake_zeroize_ctx(). +* +* Context: Any context. +*/ +void shake_squeeze (struct shake_ctx *ctx,u8 *out,size_t out_len); + +/** +* sha3_224() - Compute SHA3-224 digest in one shot +* @in: The input data to be digested +* @in_len: Length of the input data in bytes +* @out: The buffer into which the digest will be stored +* +* Convenience function that computes a SHA3-224 digest. Use this instead of +* the incremental API if you're able to provide all the input at once. +* +* Context: Any context. +*/ +void sha3_224 (const u8 *in,size_t in_len,u8 out[SHA3_224_DIGEST_SIZE ]); + +/** +* sha3_256() - Compute SHA3-256 digest in one shot +* @in: The input data to be digested +* @in_len: Length of the input data in bytes +* @out: The buffer into which the digest will be stored +* +* Convenience function that computes a SHA3-256 digest. Use this instead of +* the incremental API if you're able to provide all the input at once. +* +* Context: Any context. +*/ +void sha3_256 (const u8 *in,size_t in_len,u8 out[SHA3_256_DIGEST_SIZE ]); + +/** +* sha3_384() - Compute SHA3-384 digest in one shot +* @in: The input data to be digested +* @in_len: Length of the input data in bytes +* @out: The buffer into which the digest will be stored +* +* Convenience function that computes a SHA3-384 digest. Use this instead of +* the incremental API if you're able to provide all the input at once. +* +* Context: Any context. +*/ +void sha3_384 (const u8 *in,size_t in_len,u8 out[SHA3_384_DIGEST_SIZE ]); + +/** +* sha3_512() - Compute SHA3-512 digest in one shot +* @in: The input data to be digested +* @in_len: Length of the input data in bytes +* @out: The buffer into which the digest will be stored +* +* Convenience function that computes a SHA3-512 digest. Use this instead of +* the incremental API if you're able to provide all the input at once. +* +* Context: Any context. +*/ +void sha3_512 (const u8 *in,size_t in_len,u8 out[SHA3_512_DIGEST_SIZE ]); + +/** +* shake128() - Compute SHAKE128 in one shot +* @in: The input data to be used +* @in_len: Length of the input data in bytes +* @out: The buffer into which the output will be stored +* @out_len: Length of the output to produce in bytes +* +* Convenience function that computes SHAKE128 in one shot. Use this instead of +* the incremental API if you're able to provide all the input at once as well +* as receive all the output at once. All output lengths are supported. +* +* Context: Any context. +*/ +void shake128 (const u8 *in,size_t in_len,u8 *out,size_t out_len); + +/** +* shake256() - Compute SHAKE256 in one shot +* @in: The input data to be used +* @in_len: Length of the input data in bytes +* @out: The buffer into which the output will be stored +* @out_len: Length of the output to produce in bytes +* +* Convenience function that computes SHAKE256 in one shot. Use this instead of +* the incremental API if you're able to provide all the input at once as well +* as receive all the output at once. All output lengths are supported. +* +* Context: Any context. +*/ +void shake256 (const u8 *in,size_t in_len,u8 *out,size_t out_len); + +#endif /* __CRYPTO_SHA3_H__ */
lib/crypto/sha3.c new file +382 -0
382 lines not on this page · raw message
Signature · 1 line
2.43.0
Re: [PATCH 1/4] crypto: add SHAKE128 and SHAKE256 support
Hi Ayoub,
Quoted 4 lines · Ayoub Zaki
crypto: add SHAKE128 and SHAKE256 support
Add generic incremental and one-shot SHAKE interfaces backed by Keccak-f[1600].
This patch also adds the fixed-output SHA3-224/256/384/512 digests (sha3_224() etc. and the sha3_ctx API), but the commit message does not mention them. Nothing in the series uses them, they are not wired into the hash framework and patch 3 only tests SHAKE. Please can you either drop them or mention them here and add known-answer tests? If they stay, the Kconfig symbol should probably be SHA3 rather than SHAKE, since it builds both.
Quoted 4 lines
Adapt the implementation from the Linux SHA-3 library introduced by commit
0593447248044ab609b43b947d0e198c887ac281. Retain its provenance and licensing.
This patch cites three different Linux commits: 0593447248044 in the commit message, f1799d17285c in include/crypto/sha3.h and 0354d3c1f1b8 in lib/crypto/sha3.c. Since you plan to track upstream fixes, please say clearly which tree/tag each file was synced from, ideally the same one for both files.
Quoted 9 lines
Signed-off-by Ayoub Zaki <[email protected]>
include/crypto/sha3.h| 353 ++++++++++++++++++++++++++++++++++++++++++++++lib/crypto/sha3.c | 382 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 735 insertions(+)
lib/crypto/sha3.c line 8
Quoted 8 lines
lib/crypto/sha3.c +8
-0@@ -0,0 +1,382 @@ +void __sha3_update (struct __sha3_ctx *ctx,const u8 *in,size_t in_len) +{ +const size_t block_size = ctx->block_size; +size_t absorb_offset = ctx->absorb_offset; + +/* Warn if squeezing has already begun. */ +if (absorb_offset >= block_size) +return ;
The comment says 'warn', but the code silently drops the input. Linux uses WARN_ON_ONCE() here. For a hash this is a nasty failure mode: a caller that misuses the API gets a digest that does not cover all its data, with no sign of a problem. U-Boot has WARN_ON_ONCE() in linux/bug.h, so you could keep that, or at least somehow return an error.
lib/crypto/sha3.c line 6
Quoted 8 lines
lib/crypto/sha3.c +6
-0@@ -0,0 +1,382 @@ +static inline u64 sha3_rol64 (u64 value,unsigned int shift) +{ +return (value << shift) | (value >> (64 - shift)); +} + +#define rol64 (value, shift) sha3_rol64((value), (shift))
U-Boot's linux/bitops.h lacks rol64(), so I see why this is here. I suggest adding rol64() and ror64() to include/linux/bitops.h, matching Linux, so this file stays closer to upstream and other code can use them.
lib/crypto/sha3.c line 7
Quoted 9 lines
lib/crypto/sha3.c +7
-0@@ -0,0 +1,382 @@ +#ifndef sha3_224_arch +static inline bool sha3_224_arch (const u8 *in,size_t in_len, +u8 out[SHA3_224_DIGEST_SIZE ]) +{ +return false; +} +#endif
Nothing in U-Boot defines sha3_*_arch, so these four stubs are dead code, as are the __maybe_unused and the sha3_keccakf/sha3_absorb_blocks #define indirection. You could keep them to make Linux syncs easier, but then please say so in the commit message (or the doc in patch 4) so that later readers don't tidy them away. Otherwise I'd drop them.
Regards,
Simon
PATCH 2/4 crypto: add FIPS 204 ML-DSA verification
In reply to Ayoub ZakiPort the Linux verify-only ML-DSA implementation introduced by commit 64edccea594cf7cb1e2975fdf44531e3377b32db. Include the API documentation update from commit ffd42b6d0420c4be97cc28fd1bb5f4c29e286e98.
Support all three FIPS 204 parameter sets with raw keys and raw signatures. Do not add signing, private-key handling, FIT integration or an external library dependency.
Keep the initial public API aligned with Linux. It accepts one contiguous message. Defer FIT integration to a separate series.
Add U-Boot argument validation for invalid parameter-set values. Reject a NULL message when its length is nonzero.
--- include/crypto/mldsa.h | 67 ++++ lib/Kconfig | 14 + lib/crypto/Makefile | 3 + lib/crypto/mldsa.c | 679 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 763 insertions(+) create mode 100644 include/crypto/mldsa.h create mode 100644 lib/crypto/mldsa.c
include/crypto/mldsa.h new file +67 -0
@@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* +* Support for verifying ML-DSA signatures +* +* Copyright 2025 Google LLC +* +* Based on Linux include/crypto/mldsa.h +* at commit: +* https://git.kernel.org/linus/ffd42b6d0420c4be97cc28fd1bb5f4c29e286e98 +* +* Ported to U-Boot by: +* Ayoub Zaki <[email protected]> +*/ +#ifndef _CRYPTO_MLDSA_H +#define _CRYPTO_MLDSA_H + +#include <linux/types.h> + +/* Identifier for an ML-DSA parameter set */ +enum mldsa_alg { +MLDSA44 ,/* ML-DSA-44 */ +MLDSA65 ,/* ML-DSA-65 */ +MLDSA87 ,/* ML-DSA-87 */ +}; + +/* Lengths of ML-DSA public keys and signatures in bytes */ +#define MLDSA44_PUBLIC_KEY_SIZE 1312 +#define MLDSA65_PUBLIC_KEY_SIZE 1952 +#define MLDSA87_PUBLIC_KEY_SIZE 2592 +#define MLDSA44_SIGNATURE_SIZE 2420 +#define MLDSA65_SIGNATURE_SIZE 3309 +#define MLDSA87_SIGNATURE_SIZE 4627 + +/** +* mldsa_verify() - Verify an ML-DSA signature +* @alg: The ML-DSA parameter set to use +* @sig: The signature +* @sig_len: Length of the signature in bytes. Should match the +* MLDSA*_SIGNATURE_SIZE constant associated with @alg, +* otherwise -EBADMSG will be returned. +* @msg: The message +* @msg_len: Length of the message in bytes +* @pk: The public key +* @pk_len: Length of the public key in bytes. Should match the +* MLDSA*_PUBLIC_KEY_SIZE constant associated with @alg, +* otherwise -EBADMSG will be returned. +* +* This verifies a signature using pure ML-DSA with the specified parameter set. +* The context string is assumed to be empty. This corresponds to FIPS 204 +* Algorithm 3 "ML-DSA.Verify" with the ctx parameter set to the empty string +* and the lengths of the signature and key given explicitly by the caller. +* +* Return: +* * 0 if the signature is valid +* * -EBADMSG if the signature and/or public key is malformed +* * -EKEYREJECTED if the signature is invalid but otherwise well-formed +* * -ENOMEM if out of memory so the validity of the signature is unknown +*/ +int mldsa_verify (enum mldsa_alg alg,const u8 *sig,size_t sig_len, +const u8 *msg,size_t msg_len,const u8 *pk,size_t pk_len); + +#if IS_ENABLED (CONFIG_UT_LIB_MLDSA ) +/* Internal function exposed only for unit testing */ +s32 mldsa_use_hint (u8 h,s32 r,s32 gamma2); +#endif + +#endif /* _CRYPTO_MLDSA_H */
lib/Kconfig +14 -0
@@ -568,6 +568,12 @@ endmenu menu "Hashing Support" +config SHAKE + bool "Enable SHAKE128/SHAKE256 support" + help + Enable the FIPS 202 SHAKE128 and SHAKE256 extendable-output + functions. Both one-shot and incremental interfaces are provided. + config BLAKE2 bool "Enable BLAKE2 support" help
@@ -618,6 +624,14 @@ config SM3 SM3 (ShangMi 3) secure hash function (OSCCA GM/T 0004-2012, ISO/IEC 10118-3) The hash is calculated in software. +config MLDSA_VERIFY + bool "Enable ML-DSA signature verification" + select SHAKE + help + Enable verification of pure FIPS 204 ML-DSA-44, ML-DSA-65 and + ML-DSA-87 signatures using raw public keys and signatures. This + option does not include signing, private-key handling or FIT support. + config SHA_HW_ACCEL bool "Enable hardware acceleration for SHA hash functions" help
lib/crypto/Makefile +3 -0
@@ -60,6 +60,9 @@ $(obj)/pkcs7.asn1.o: $(obj)/pkcs7.asn1.c $(obj)/pkcs7.asn1.h obj-$(CONFIG_$(PHASE_)PKCS7_VERIFY) += pkcs7_verify.o +obj-$(CONFIG_$(PHASE_)SHAKE) += sha3.o +obj-$(CONFIG_$(PHASE_)MLDSA_VERIFY) += mldsa.o + # # Signed PE binary-wrapped key handling #
lib/crypto/mldsa.c new file +679 -0
679 lines not on this page · raw message
Signature · 1 line
2.43.0
Hi Ayoub,
Quoted 17 lines · Ayoub Zaki
crypto: add FIPS 204 ML-DSA verification
Port the Linux verify-only ML-DSA implementation introduced by commit
64edccea594cf7cb1e2975fdf44531e3377b32db. Include the API documentation update from commitffd42b6d0420c4be97cc28fd1bb5f4c29e286e98.Support all three FIPS 204 parameter sets with raw keys and raw signatures. Do not add signing, private-key handling, FIT integration or an external library dependency.
Keep the initial public API aligned with Linux. It accepts one contiguous message. Defer FIT integration to a separate series.
Add U-Boot argument validation for invalid parameter-set values. Reject a NULL message when its length is nonzero.
Quoted 7 lines
Signed-off-by Ayoub Zaki <[email protected]>
include/crypto/mldsa.h| 67 +++++lib/Kconfig | 14 + lib/crypto/Makefile | 3 + lib/crypto/mldsa.c | 679 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 763 insertions(+)
I'm reviewing this but of course it depends on the outcome of the mbedtls discussion.
lib/Kconfig config SM3 · line 642
Quoted 5 lines
lib/Kconfig +3
-0@@ -634,6 +640,14 @@ config SM3 +config MLDSA_VERIFY + bool "Enable ML-DSA signature verification" + select SHAKE
You asked about Kconfig placement. ML-DSA is a signature scheme, not a hash, so it fits better in the "Security support" menu next to lib/ecdsa/Kconfig and lib/rsa/Kconfig than under "Hashing Support", e.g. as lib/mldsa/Kconfig or inside lib/crypto/Kconfig. Then when FIT support arrives, it will sit alongside the other verification options it has to interact with. What do you think?
include/crypto/mldsa.h line 6
Quoted 8 lines
include/crypto/mldsa.h +6
-0@@ -0,0 +1,67 @@ +* Return: +* * 0 if the signature is valid +* * -EBADMSG if the signature and/or public key is malformed +* * -EKEYREJECTED if the signature is invalid but otherwise well-formed +* * -ENOMEM if out of memory so the validity of the signature is unknown +*/
The U-Boot-specific checks in mldsa_verify() return -EINVAL, which is missing from this list. Please can you add it?
lib/crypto/mldsa.c line 2
Quoted 4 lines
lib/crypto/mldsa.c +2
-0@@ -0,0 +1,679 @@ +if (alg <MLDSA44 || alg >MLDSA87 ) +return -EINVAL ;
If the enum has an unsigned underlying type, 'alg < MLDSA44' is always false and -Wtype-limits warns about it. Checking '(unsigned int)alg >= ARRAY_SIZE(mldsa_parameter_sets)' avoids that and stays correct if a parameter set is added later.
lib/crypto/mldsa.c line 4
Quoted 6 lines
lib/crypto/mldsa.c +4
-0@@ -0,0 +1,679 @@ +* For freeing it, use kfree_sensitive() rather than kfree(). This is +* mainly to comply with FIPS 204 Section 3.6.3 "Intermediate Values". +* In reality it's a bit gratuitous, as this is a public key operation. +*/
This comment is out of date, since the port uses memset()/barrier_data()/free(). It also contradicts the doc in patch
4. Please can you update it to describe what the code actually does?
Regards,
Simon
PATCH 3/4 test: add ML-DSA verification tests
In reply to Ayoub ZakiAdapt the Linux KUnit coverage introduced by commit ed894faccb8de55cd755e093c4b0971f190d384d to the U-Boot unit-test framework. Import its fixed vectors for ML-DSA-44, ML-DSA-65 and ML-DSA-87.
Use deterministic mutation positions for reproducible U-Boot tests. Test valid signatures for every parameter set. Test signature and public-key length errors plus a changed message length. Test malformed encodings and every valid UseHint input.
Add an invalid-algorithm test beyond the Linux coverage. Test SHAKE128 and SHAKE256 against FIPS 202 known answers.
--- test/Kconfig | 9 + test/lib/Makefile | 1 + test/lib/mldsa-testvecs.h | 1896 +++++++++++++++++++++++++++++++++++++ test/lib/mldsa.c | 383 ++++++++ 4 files changed, 2289 insertions(+) create mode 100644 test/lib/mldsa-testvecs.h create mode 100644 test/lib/mldsa.c
test/Kconfig +9 -0
@@ -75,6 +75,15 @@ config UT_LIB_RSA Enables rsa_verify() test, currently rsa_verify_with_pkey only() only, at the 'ut lib' command. +config UT_LIB_MLDSA + bool "Unit tests for ML-DSA verification" + default y + select MLDSA_VERIFY + help + Enables fixed-vector tests for all three FIPS 204 ML-DSA parameter + sets. Tests cover malformed encodings, input mutations and the + complete UseHint input space at the 'ut lib' command. + endif # UT_LIB config UT_BOOTSTD
test/lib/Makefile +1 -0
@@ -28,6 +28,7 @@ obj-y += strlcat.o obj-$(CONFIG_ERRNO_STR) += test_errno_str.o obj-$(CONFIG_UT_LIB_ASN1) += asn1.o obj-$(CONFIG_UT_LIB_RSA) += rsa.o +obj-$(CONFIG_UT_LIB_MLDSA) += mldsa.o obj-$(CONFIG_AES) += test_aes.o obj-$(CONFIG_SHA256) += test_sha256_hmac.o obj-$(CONFIG_HKDF_MBEDTLS) += test_sha256_hkdf.o
test/lib/mldsa-testvecs.h new file +1896 -0
1,896 lines not on this page · raw message
test/lib/mldsa.c new file +383 -0
383 lines not on this page · raw message
Signature · 1 line
2.43.0
Re: [PATCH 3/4] test: add ML-DSA verification tests
Hi Ayoub,
Quoted 6 lines · Ayoub Zaki
test: add ML-DSA verification tests
Adapt the Linux KUnit coverage introduced by commit
ed894faccb8de55cd755e093c4b0971f190d384dto the U-Boot unit-test framework. Import its fixed vectors for ML-DSA-44, ML-DSA-65 and ML-DSA-87.
Please can you use the usual form, i.e. commit ed894faccb8d ('subject'), so that people can see what the commit is without looking it up? The same applies to patch 2.
Quoted 19 lines
Use deterministic mutation positions for reproducible U-Boot tests. Test valid signatures for every parameter set. Test signature and public-key length errors plus a changed message length. Test malformed encodings and every valid UseHint input.
Add an invalid-algorithm test beyond the Linux coverage. Test SHAKE128 and SHAKE256 against FIPS 202 known answers.
Signed-off-by Ayoub Zaki <[email protected]>test/Kconfig | 9 +
test/lib/Makefile | 1 + test/lib/mldsa-testvecs.h | 1896 +++++++++++++++++++++++++++++++++++++++++++++ test/lib/mldsa.c | 383 +++++++++ 4 files changed, 2289 insertions(+)
test/Kconfig config UT_LIB_RSA · line 78
Quoted 4 lines
test/Kconfig +4
-0@@ -75,6 +75,15 @@ config UT_LIB_RSA +config UT_LIB_MLDSA + bool "Unit tests for ML-DSA verification" + default y + select MLDSA_VERIFY
With 'default y' and 'select', any board with UNIT_TEST now builds the ML-DSA verifier, SHAKE and about 9KB of test vectors. That includes QEMU boards (qemu_arm64, qemu-riscv64, malta, etc.), not just sandbox. Enabling unit tests should not silently turn on a crypto feature. Please can you use 'depends on MLDSA_VERIFY' instead, as UT_LIB_RSA does, and enable MLDSA_VERIFY for sandbox (e.g. imply it from SANDBOX or add it to sandbox_defconfig)? Then the test runs wherever the feature is actually used.
BTW the tests all pass on sandbox. lib_mldsa_use_hint takes about 150ms on my machine there, which is fine, though it will be much slower under QEMU emulation.
test/lib/mldsa.c line 3
Quoted 5 lines
test/lib/mldsa.c +3
-0@@ -0,0 +1,383 @@ +static int lib_shake (struct unit_test_state *uts) +{ +static const u8 shake128_empty[32 ] = {
SHAKE comes in patch 1 and is meant to be generic, so its test belongs with it, in patch 1 or a separate patch straight after it. Please put it in its own file (e.g. test/lib/sha3.c) controlled by CONFIG_SHAKE or its own option. At present it is only built when the ML-DSA test is enabled.
The coverage is also thin. Only the empty message is tested, so the absorb path never processes a full block (168 bytes for SHAKE128, 136 for SHAKE256) and shake_update() never handles partial blocks. Linux has lib/crypto/tests/sha3_kunit.c with vectors you could port, including multi-block and incremental cases. Please can you add those?
Regards,
Simon
PATCH 4/4 doc: describe ML-DSA verification
In reply to Ayoub ZakiDocument the verifier config symbol and the raw FIPS 204 public-key and signature encodings accepted by the public API. Describe the single per-parameter-set workspace allocation.
Record the exact Linux file revisions used for the port. Explain which kernel facilities were dropped or replaced by U-Boot equivalents.
Note that the initial API takes one contiguous message. State that FIT and mkimage integration is deferred to a separate series.
--- doc/develop/index.rst | 1 + doc/develop/mldsa.rst | 67 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 doc/develop/mldsa.rst
doc/develop/index.rst +1 -0
@@ -16,6 +16,7 @@ General docstyle kconfig memory + mldsa process release_cycle security
doc/develop/mldsa.rst new file +67 -0
67 lines not on this page · raw message
Signature · 1 line
2.43.0
Re: [PATCH 4/4] doc: describe ML-DSA verification
Am 18. September 2026 19:21:27 MESZ schrieb Ayoub Zaki <[email protected]>:
Quoted 48 lines
Document the verifier config symbol and the raw FIPS 204 public-key and signature encodings accepted by the public API. Describe the single per-parameter-set workspace allocation.
Record the exact Linux file revisions used for the port. Explain which kernel facilities were dropped or replaced by U-Boot equivalents.
Note that the initial API takes one contiguous message. State that FIT and mkimage integration is deferred to a separate series.
Signed-off-by Ayoub Zaki <[email protected]>---
doc/develop/index.rst| 1 +doc/develop/mldsa.rst| 67 +++++++++++++++++++++++++++++++++++++++++++2 files changed, 68 insertions(+)create mode 100644
doc/develop/mldsa.rstdoc/develop/index.rst +1
-0@@ -16,6 +16,7 @@ General docstyle kconfig memory + mldsa process release_cycle securitydoc/develop/mldsa.rst new file +13
-0@@ -0,0 +1,67 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later + +ML-DSA verification +=================== + +U-Boot provides a FIT-independent verifier for pure ML-DSA with an empty +context string. ``CONFIG_MLDSA_VERIFY`` enables ML-DSA-44, ML-DSA-65 and +ML-DSA-87; it selects the generic SHAKE implementation. The public API in +``include/crypto/mldsa.h`` accepts the raw FIPS 204 public-key and signature +encodings. It does not parse PEM or DER and contains no signing or private-key +code. + +Verification makes a single heap allocation whose size depends on the
doc/develop/mldsa.rst line 23
Quoted 10 lines
doc/develop/mldsa.rst new file +10
-0+parameter set and ABI alignment. Targets with 8-byte ``u64`` alignment use +8800 bytes for ML-DSA-44, 10336 bytes for ML-DSA-65 and 12896 bytes for +ML-DSA-87. This includes x86_64 and 32-bit ARM EABI. Targets with 4-byte +``u64`` alignment use 8792 bytes, 10328 bytes and 12888 bytes respectively. +There is no message-sized allocation or copy. The workspace size does not +scale with the size of the signed data. + +The initial API accepts one contiguous message. Its Linux origin does the same. +There is no FIT or mkimage integration yet. A follow-up can add a generic +incremental API that lets the verifier absorb FIT signed regions directly.
Can we add the api header to doc/api/ and link the generated documentation here?
Best regards
Heinrich
Quoted 44 lines
doc/develop/mldsa.rst new file +44
-0+ +Origin +------ + +The verifier, SHAKE code, APIs and test vectors were adapted from these exact +Linux file revisions:: + + include/crypto/sha3.h + f1799d17285ca99243328cd92133a9f84ee3a593 + lib/crypto/sha3.c + 0354d3c1f1b8628e60eceb304b6d2ef75eea6f41 + include/crypto/mldsa.h + lib/crypto/mldsa.c + ffd42b6d0420c4be97cc28fd1bb5f4c29e286e98 + lib/crypto/tests/mldsa_kunit.c + lib/crypto/tests/mldsa-testvecs.h + ed894faccb8de55cd755e093c4b0971f190d384d + +Each imported file header links to its corresponding kernel.org commit. The +SHA-3 library was introduced by Linux commit +``0593447248044ab609b43b947d0e198c887ac281``. ML-DSA verification was +introduced by Linux commit ``64edccea594cf7cb1e2975fdf44531e3377b32db``. + +The Linux SPDX identifiers, copyright notices and algorithm commentary are +retained. The module boilerplate, symbol exports, FIPS self-tests and KUnit +harness were dropped. ``crypto_xor()``, ``mem_is_zero()`` and +``memzero_explicit()`` were replaced by local equivalents. ``kmalloc()`` and +``kfree_sensitive()`` were replaced by ``malloc()`` with an explicit zeroize +before ``free()``. The ``WARN_ON_ONCE()`` in ``__sha3_update()`` was replaced +by an early return. + +Testing +------- + +``CONFIG_UT_LIB_MLDSA`` adds unit tests that cover all three parameter sets +using the fixed Linux test vectors. It also adds FIPS 202 SHAKE128 and +SHAKE256 known-answer tests:: + + ut lib lib_shake + ut lib lib_mldsa44 + ut lib lib_mldsa65 + ut lib lib_mldsa87 + ut lib lib_mldsa_invalid_alg + ut lib lib_mldsa_use_hint
Re: [PATCH 4/4] doc: describe ML-DSA verification
Hi Heinrich,
Quoted 2 lines · Heinrich Schuchardt
Can we add the api header to doc/api/ and link the generated documentation here?
I’ll add the generated API documentation under doc/api and
link it here in v2 if we proceed with this approach.
That depends on whether Tom prefers the Linux kernel based implementation for now or waiting for mbedTLS support to mature.
Mit freundlichen Grüßen / Kind regards
Signature · 9 lines
Ayoub Zaki Embedded Systems Consultant Vaihinger Straße 2/1 D-71634 Ludwigsburg Email : [email protected] Homepage : https://embetrix.com VAT No. : DE313902634
Re: [PATCH 4/4] doc: describe ML-DSA verification
In reply to Ayoub ZakiHi Ayoub,
Quoted 20 lines · Ayoub Zaki
doc: describe ML-DSA verification
Document the verifier config symbol and the raw FIPS 204 public-key and signature encodings accepted by the public API. Describe the single per-parameter-set workspace allocation.
Record the exact Linux file revisions used for the port. Explain which kernel facilities were dropped or replaced by U-Boot equivalents.
Note that the initial API takes one contiguous message. State that FIT and mkimage integration is deferred to a separate series.
Signed-off-by Ayoub Zaki <[email protected]>
doc/develop/index.rst| 1 +doc/develop/mldsa.rst | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+)
doc/develop/mldsa.rst line 5
Quoted 5 lines
doc/develop/mldsa.rst +5
-0@@ -0,0 +1,67 @@ +Verification makes a single heap allocation whose size depends on the +parameter set and ABI alignment. Targets with 8-byte ``u64`` alignment use +8800 bytes for ML-DSA-44, 10336 bytes for ML-DSA-65 and 12896 bytes for +ML-DSA-87. This includes x86_64 and 32-bit ARM EABI. Targets with 4-byte +``u64`` alignment use 8792 bytes, 10328 bytes and 12888 bytes respectively.
These exact byte counts depend on the layout of struct shake_ctx and struct mldsa_verification_workspace. They will be wrong as soon as either struct changes (e.g. when a Linux fix is pulled in), and nothing will catch it. Please can you give an approximate figure (about 9KB to 13KB, as in the cover letter) and point to the workspace_len calculation in mldsa_verify()? If the exact values matter, a unit test that checks them would keep them accurate.
Quoted 7 lines
doc/develop/mldsa.rst +5
-0@@ -0,0 +1,67 @@ +The verifier, SHAKE code, APIs and test vectors were adapted from these exact +Linux file revisions:: + + include/crypto/sha3.h + f1799d17285ca99243328cd92133a9f84ee3a593
doc/develop/mldsa.rst line 15
Quoted 10 lines
doc/develop/mldsa.rst +10
-0+ lib/crypto/sha3.c + 0354d3c1f1b8628e60eceb304b6d2ef75eea6f41 + include/crypto/mldsa.h + lib/crypto/mldsa.c + ffd42b6d0420c4be97cc28fd1bb5f4c29e286e98 + lib/crypto/tests/mldsa_kunit.c + lib/crypto/tests/mldsa-testvecs.h + ed894faccb8de55cd755e093c4b0971f190d384d + +Each imported file header links to its corresponding kernel.org commit. The
These commits are already recorded in each file header and in the commit messages. Every Linux sync then means updating two places, and given Tom's concern about maintenance, they will likely drift apart. I suggest treating the file headers as the single source of truth and having the doc point to them. Alternatively, keep this table and add a note that it must be updated with each sync. What do you think?
doc/develop/mldsa.rst line 3
Quoted 5 lines
doc/develop/mldsa.rst +3
-0@@ -0,0 +1,67 @@ +The initial API accepts one contiguous message. Its Linux origin does the same. +There is no FIT or mkimage integration yet. A follow-up can add a generic +incremental API that lets the verifier absorb FIT signed regions directly.
Plans for future work go stale in documentation. I suggest keeping them in the cover letter and having the doc describe only what exists now.
Regards,
Simon
Quoted 36 lines · Ayoub Zaki
Classical signature schemes such as RSA and ECDSA are vulnerable to attacks by sufficiently powerful quantum computers. This series adds ML-DSA verification as a first step towards post-quantum cryptography (PQC) support in U-Boot.
This RFC adds generic verification support for pure FIPS 204 ML-DSA without an external message prehash. SHAKE hashing remains part of the ML-DSA algorithm. HashML-DSA is not supported. See FIPS 204 Section 5.3:
https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.204.pdfIt supports ML-DSA-44, ML-DSA-65 and ML-DSA-87. The implementation is verification-only. It contains no target signing code or private-key handling.
This series targets U-Boot proper. SPL support is not included. Verification allocates approximately 8 to 12 KB of heap workspace depending on the parameter set and ABI alignment. This excludes allocator overhead. Any future SPL integration will need to account for heap availability, stack usage and code size.
The verifier is adapted from the Linux crypto library implementation. The series preserves the Linux licensing, copyright notices and source provenance. Linux facilities are replaced with direct U-Boot equivalents where needed.
ML-DSA requires SHAKE128 and SHAKE256. The series adds generic one-shot and incremental SHAKE interfaces backed by Keccak-f[1600]. This code can be used by consumers other than ML-DSA.
The public ML-DSA API accepts raw FIPS 204 public keys, raw signatures and one contiguous message.
The tests are based on Linux KUnit tests and cover all three ML-DSA parameter sets with valid and invalid inputs. SHAKE128 and SHAKE256 are checked against FIPS 202 known answers.
Quoted 8 lines
Validated with sandbox and
qemu_arm64_defconfigbuilds plus the SHAKE and ML-DSA unit tests on sandbox.This series does not add FIT semantics or mkimage signing. A follow-up series can add a generic incremental transcript, target FIT verification and host signing.
Feedback is welcome on the public API and
Kconfigplacement.
This is interesting and something that does have to be on our radar. My first question is, should we not just update to a newer mbedtls release and enable their SHA3-{256,384,512} supports, and anything else we need? Then we tell people that need this that they need to move from legacy crypto support to mbedtls (where we get to leverage a wider community for security audit and response and so on). Thanks!
Signature · 1 line
Tom
Quoted 6 lines · Tom Rini
This is interesting and something that does have to be on our radar. My first question is, should we not just update to a newer mbedtls release and enable their SHA3-{256,384,512} supports, and anything else we need? Then we tell people that need this that they need to move from legacy crypto support to mbedtls (where we get to leverage a wider community for security audit and response and so on). Thanks!
Hi Tom,
Thanks. I agree with the long-term maintenance benefits. ML-DSA requires SHAKE128 and SHAKE256 rather than just fixed-output SHA3. The TF-PSA-Crypto ML-DSA integration is marked experimental in the Mbed TLS 4.2 documentation.
For this series I would prefer to retain the Linux kernel-based implementation with limited U-Boot adaptations. A migration to Mbed TLS could follow as its ML-DSA support matures. Would that be acceptable?
Ayoub
Mit freundlichen Grüßen / Kind regards
Signature · 8 lines
Ayoub Zaki Embedded Systems Consultant Vaihinger Straße 2/1 D-71634 Ludwigsburg Email : [email protected] Homepage : https://embetrix.com VAT No. : DE313902634
Quoted 10 lines · Ayoub Zaki
Quoted 6 lines · Tom Rini
This is interesting and something that does have to be on our radar. My first question is, should we not just update to a newer mbedtls release and enable their SHA3-{256,384,512} supports, and anything else we need? Then we tell people that need this that they need to move from legacy crypto support to mbedtls (where we get to leverage a wider community for security audit and response and so on). Thanks!
Quoted 9 lines
Hi Tom,
Thanks. I agree with the long-term maintenance benefits. ML-DSA requires SHAKE128 and SHAKE256 rather than just fixed-output SHA3. The TF-PSA-Crypto ML-DSA integration is marked experimental in the Mbed TLS 4.2 documentation.
For this series I would prefer to retain the Linux kernel-based implementation with limited U-Boot adaptations. A migration to Mbed TLS could follow as its ML-DSA support matures. Would that be acceptable?
Well, a problem I see is that this is something that needs active maintenance to stay in sync as we don't want to miss important fixes here. In theory, we get that with mbedtls (even if we're behind atm...).
Signature · 1 line
Tom
Hi Tom,
Quoted 21 lines · Tom Rini
Quoted 10 lines · Ayoub Zaki
Quoted 6 lines · Tom Rini
This is interesting and something that does have to be on our radar. My first question is, should we not just update to a newer mbedtls release and enable their SHA3-{256,384,512} supports, and anything else we need? Then we tell people that need this that they need to move from legacy crypto support to mbedtls (where we get to leverage a wider community for security audit and response and so on). Thanks!
Quoted 9 lines
Hi Tom,
Thanks. I agree with the long-term maintenance benefits. ML-DSA requires SHAKE128 and SHAKE256 rather than just fixed-output SHA3. The TF-PSA-Crypto ML-DSA integration is marked experimental in the Mbed TLS 4.2 documentation.
For this series I would prefer to retain the Linux kernel-based implementation with limited U-Boot adaptations. A migration to Mbed TLS could follow as its ML-DSA support matures. Would that be acceptable?
Quoted 4 lines
Well, a problem I see is that this is something that needs active maintenance to stay in sync as we don't want to miss important fixes here. In theory, we get that with mbedtls (even if we're behind atm...).
Agreed. Importing the Linux implementation means taking responsibility for tracking upstream fixes. I’m willing to maintain this code, track changes to the Linux implementations and bring relevant fixes into U-Boot. I can also add a MAINTAINERS entry to make that responsibility explicit. The goal is to prepare U-Boot for early adoption of post-quantum cryptography in secure boot, particularly FIT image signing and signature verification as some hardware already ships with PQC capabilities.
The intention is to switch to Mbed TLS as soon as it provides production ready ML-DSA support and the required SHAKE functionality. That timeline is not clear to me yet so I’d like to prepare U-Boot in the meantime.
Would this address your maintenance concern sufficiently to proceed with this approach?
Mit freundlichen Grüßen / Kind regards
Signature · 8 lines
Ayoub Zaki Embedded Systems Consultant Vaihinger Straße 2/1 D-71634 Ludwigsburg Email : [email protected] Homepage : https://embetrix.com VAT No. : DE313902634
Hi all,
First of all, Ayoub thanks for doing this. It's on my backlog for a number of years :)
Quoted 30 lines · Ayoub Zaki
Hi Tom,
Quoted 21 lines · Tom Rini
Quoted 10 lines · Ayoub Zaki
Quoted 6 lines · Tom Rini
This is interesting and something that does have to be on our radar. My first question is, should we not just update to a newer mbedtls release and enable their SHA3-{256,384,512} supports, and anything else we need? Then we tell people that need this that they need to move from legacy crypto support to mbedtls (where we get to leverage a wider community for security audit and response and so on). Thanks!
Quoted 9 lines
Hi Tom,
Thanks. I agree with the long-term maintenance benefits. ML-DSA requires SHAKE128 and SHAKE256 rather than just fixed-output SHA3. The TF-PSA-Crypto ML-DSA integration is marked experimental in the Mbed TLS 4.2 documentation.
For this series I would prefer to retain the Linux kernel-based implementation with limited U-Boot adaptations. A migration to Mbed TLS could follow as its ML-DSA support matures. Would that be acceptable?Quoted 4 lines
Well, a problem I see is that this is something that needs active maintenance to stay in sync as we don't want to miss important fixes here. In theory, we get that with mbedtls (even if we're behind atm...).
Quoted 9 lines
Agreed. Importing the Linux implementation means taking responsibility for tracking upstream fixes. I’m willing to maintain this code, track changes to the Linux implementations and bring relevant fixes into U-Boot. I can also add a
MAINTAINERSentry to make that responsibility explicit.
The goal is to prepare U-Boot for early adoption of post-quantum cryptography in secure boot, particularly FIT image signing and signature verification as some hardware already ships with PQC capabilities.
There are zero doubts that this is necessary; in fact we are already late.
Quoted 6 lines
The intention is to switch to Mbed TLS as soon as it provides production ready ML-DSA support and the required SHAKE functionality. That timeline is not clear to me yet so I’d like to prepare U-Boot in the meantime. Would this address your maintenance concern sufficiently to proceed with this approach?
I can try to find out more about the mbedTLS roadmap if you are still interested in going down that path. Arguably most country legislation is looking to enforce PQC by 2030 so a month or two won't kill us. There's another benefit apart from the 'less maintenance' when using the external library path. IIRC, there isn't a single algorithm acceptable to all legislative bodies.E.g, CNSA 2.0 does not adopt SLH-DSA while most of Europe does. It would be much easier to use a library and select the desired implementation (even stateful vs stateless) instead of importing and maintaining everything.
Thanks!
/Ilias
Quoted 12 lines
Mit freundlichen Grüßen / Kind regards
--
Ayoub Zaki
Embedded Systems ConsultantVaihinger Straße 2/1
D-71634 Ludwigsburg
Email : [email protected]
Homepage : https://embetrix.com
VAT No. : DE313902634
Hi Ilias,
Quoted 55 lines · Ilias Apalodimas
Hi all,
First of all, Ayoub thanks for doing this. It's on my backlog for a number of years :)
Quoted 30 lines · Ayoub Zaki
Hi Tom,
Quoted 21 lines · Tom Rini
Quoted 10 lines · Ayoub Zaki
Quoted 6 lines · Tom Rini
This is interesting and something that does have to be on our radar. My first question is, should we not just update to a newer mbedtls release and enable their SHA3-{256,384,512} supports, and anything else we need? Then we tell people that need this that they need to move from legacy crypto support to mbedtls (where we get to leverage a wider community for security audit and response and so on). Thanks!
Quoted 9 lines
Hi Tom,
Thanks. I agree with the long-term maintenance benefits. ML-DSA requires SHAKE128 and SHAKE256 rather than just fixed-output SHA3. The TF-PSA-Crypto ML-DSA integration is marked experimental in the Mbed TLS 4.2 documentation.
For this series I would prefer to retain the Linux kernel-based implementation with limited U-Boot adaptations. A migration to Mbed TLS could follow as its ML-DSA support matures. Would that be acceptable?Quoted 4 lines
Well, a problem I see is that this is something that needs active maintenance to stay in sync as we don't want to miss important fixes here. In theory, we get that with mbedtls (even if we're behind atm...).
Quoted 9 lines
Agreed. Importing the Linux implementation means taking responsibility for tracking upstream fixes. I’m willing to maintain this code, track changes to the Linux implementations and bring relevant fixes into U-Boot. I can also add a
MAINTAINERSentry to make that responsibility explicit.
The goal is to prepare U-Boot for early adoption of post-quantum cryptography in secure boot, particularly FIT image signing and signature verification as some hardware already ships with PQC capabilities.There are zero doubts that this is necessary; in fact we are already late.
Quoted 6 lines
The intention is to switch to Mbed TLS as soon as it provides production ready ML-DSA support and the required SHAKE functionality. That timeline is not clear to me yet so I’d like to prepare U-Boot in the meantime. Would this address your maintenance concern sufficiently to proceed with this approach?
Quoted 9 lines
I can try to find out more about the mbedTLS roadmap if you are still interested in going down that path. Arguably most country legislation is looking to enforce PQC by 2030 so a month or two won't kill us. There's another benefit apart from the 'less maintenance' when using the external library path. IIRC, there isn't a single algorithm acceptable to all legislative bodies.E.g, CNSA 2.0 does not adopt SLH-DSA while most of Europe does. It would be much easier to use a library and select the desired implementation (even stateful vs stateless) instead of importing and maintaining everything.
Thanks, any clarification you can get on the mbedTLS roadmap and the expected timeline for production-ready PQC support would be helpful.
Separately from that U-Boot currently uses mbedTLS 3.6.x and moving to newer 4.x involves the split into TF-PSA-Crypto as a separate submodule and incompatible API changes. That migration is work to consider independently of PQC support. Let’s revisit the PQC approach once we have more information on the roadmap.
Mit freundlichen Grüßen / Kind regards
Signature · 9 lines
Ayoub Zaki Embedded Systems Consultant Vaihinger Straße 2/1 D-71634 Ludwigsburg Email : [email protected] Homepage : https://embetrix.com VAT No. : DE313902634
[...]
Quoted 36 lines
Quoted 25 lines
Quoted 6 lines
Quoted 5 lines
Well, a problem I see is that this is something that needs active maintenance to stay in sync as we don't want to miss important fixes here. In theory, we get that with mbedtls (even if we're behind atm...).
Quoted 9 lines
Agreed. Importing the Linux implementation means taking responsibility for tracking upstream fixes. I’m willing to maintain this code, track changes to the Linux implementations and bring relevant fixes into U-Boot. I can also add a
MAINTAINERSentry to make that responsibility explicit.
The goal is to prepare U-Boot for early adoption of post-quantum cryptography in secure boot, particularly FIT image signing and signature verification as some hardware already ships with PQC capabilities.There are zero doubts that this is necessary; in fact we are already late.
Quoted 6 lines
The intention is to switch to Mbed TLS as soon as it provides production ready ML-DSA support and the required SHAKE functionality. That timeline is not clear to me yet so I’d like to prepare U-Boot in the meantime. Would this address your maintenance concern sufficiently to proceed with this approach?
Quoted 9 lines
I can try to find out more about the mbedTLS roadmap if you are still interested in going down that path. Arguably most country legislation is looking to enforce PQC by 2030 so a month or two won't kill us. There's another benefit apart from the 'less maintenance' when using the external library path. IIRC, there isn't a single algorithm acceptable to all legislative bodies.E.g, CNSA 2.0 does not adopt SLH-DSA while most of Europe does. It would be much easier to use a library and select the desired implementation (even stateful vs stateless) instead of importing and maintaining everything.
Quoted 2 lines
Thanks, any clarification you can get on the mbedTLS roadmap and the expected timeline for production-ready PQC support would be helpful.
Will do
Quoted 4 lines
Separately from that U-Boot currently uses mbedTLS 3.6.x and moving to newer 4.x involves the split into TF-PSA-Crypto as a separate submodule and incompatible API changes. That migration is work to consider independently of PQC support.
Yes last time I looked the gap wasn't massive, but it's there and indeed frustrating.
Quoted 1 line
Let’s revisit the PQC approach once we have more information on the roadmap.
Will do get back to you!
Thanks
/Ilias
Quoted 15 lines
Mit freundlichen Grüßen / Kind regards
--
Ayoub Zaki
Embedded Systems ConsultantVaihinger Straße 2/1
D-71634 LudwigsburgEmail : [email protected]
Homepage : https://embetrix.com
VAT No. : DE313902634
Apologies for the late reply.
Was waiting for some announcements to settle down.
What I found out was this [0]. Comments welcome but I'd like to see how this plays out before making any decisions, since we use mbedTLS for https as well
Thanks
/Ilias
Quoted 74 lines · Ilias Apalodimas
[...]
Quoted 36 lines
Quoted 25 lines
Quoted 6 lines
Quoted 5 lines
Well, a problem I see is that this is something that needs active maintenance to stay in sync as we don't want to miss important fixes here. In theory, we get that with mbedtls (even if we're behind atm...).
Quoted 9 lines
Agreed. Importing the Linux implementation means taking responsibility for tracking upstream fixes. I’m willing to maintain this code, track changes to the Linux implementations and bring relevant fixes into U-Boot. I can also add a
MAINTAINERSentry to make that responsibility explicit.
The goal is to prepare U-Boot for early adoption of post-quantum cryptography in secure boot, particularly FIT image signing and signature verification as some hardware already ships with PQC capabilities.There are zero doubts that this is necessary; in fact we are already late.
Quoted 6 lines
The intention is to switch to Mbed TLS as soon as it provides production ready ML-DSA support and the required SHAKE functionality. That timeline is not clear to me yet so I’d like to prepare U-Boot in the meantime. Would this address your maintenance concern sufficiently to proceed with this approach?
Quoted 9 lines
I can try to find out more about the mbedTLS roadmap if you are still interested in going down that path. Arguably most country legislation is looking to enforce PQC by 2030 so a month or two won't kill us. There's another benefit apart from the 'less maintenance' when using the external library path. IIRC, there isn't a single algorithm acceptable to all legislative bodies.E.g, CNSA 2.0 does not adopt SLH-DSA while most of Europe does. It would be much easier to use a library and select the desired implementation (even stateful vs stateless) instead of importing and maintaining everything.
Quoted 2 lines
Thanks, any clarification you can get on the mbedTLS roadmap and the expected timeline for production-ready PQC support would be helpful.
Will do
Quoted 4 lines
Separately from that U-Boot currently uses mbedTLS 3.6.x and moving to newer 4.x involves the split into TF-PSA-Crypto as a separate submodule and incompatible API changes. That migration is work to consider independently of PQC support.
Yes last time I looked the gap wasn't massive, but it's there and indeed frustrating.
Quoted 1 line
Let’s revisit the PQC approach once we have more information on the roadmap.
Will do get back to you!
Thanks
/IliasQuoted 15 lines
Mit freundlichen Grüßen / Kind regards
--
Ayoub Zaki
Embedded Systems ConsultantVaihinger Straße 2/1
D-71634 LudwigsburgEmail : [email protected]
Homepage : https://embetrix.com
VAT No. : DE313902634
Hi Ilias,
Quoted 11 lines · Ilias Apalodimas
Apologies for the late reply.
Was waiting for some announcements to settle down.What I found out was this [0]. Comments welcome but I'd like to see how this plays out before making any decisions, since we use mbedTLS for https as well
Thanks
/Ilias
Thanks for checking. Should I address Simon’s comments and send a v2 of the Linux based ML-DSA series or hold off until the direction for crypto integration in U-Boot is clearer?
Quoted 54 lines
Quoted 52 lines · Ilias Apalodimas
[...]
Quoted 36 lines
Quoted 25 lines
Quoted 6 lines
Quoted 5 lines
Well, a problem I see is that this is something that needs active maintenance to stay in sync as we don't want to miss important fixes here. In theory, we get that with mbedtls (even if we're behind atm...).
Quoted 9 lines
Agreed. Importing the Linux implementation means taking responsibility for tracking upstream fixes. I’m willing to maintain this code, track changes to the Linux implementations and bring relevant fixes into U-Boot. I can also add a
MAINTAINERSentry to make that responsibility explicit.
The goal is to prepare U-Boot for early adoption of post-quantum cryptography in secure boot, particularly FIT image signing and signature verification as some hardware already ships with PQC capabilities.There are zero doubts that this is necessary; in fact we are already late.
Quoted 6 lines
The intention is to switch to Mbed TLS as soon as it provides production ready ML-DSA support and the required SHAKE functionality. That timeline is not clear to me yet so I’d like to prepare U-Boot in the meantime. Would this address your maintenance concern sufficiently to proceed with this approach?
Quoted 9 lines
I can try to find out more about the mbedTLS roadmap if you are still interested in going down that path. Arguably most country legislation is looking to enforce PQC by 2030 so a month or two won't kill us. There's another benefit apart from the 'less maintenance' when using the external library path. IIRC, there isn't a single algorithm acceptable to all legislative bodies.E.g, CNSA 2.0 does not adopt SLH-DSA while most of Europe does. It would be much easier to use a library and select the desired implementation (even stateful vs stateless) instead of importing and maintaining everything.
Quoted 2 lines
Thanks, any clarification you can get on the mbedTLS roadmap and the expected timeline for production-ready PQC support would be helpful.
Will do
Quoted 4 lines
Separately from that U-Boot currently uses mbedTLS 3.6.x and moving to newer 4.x involves the split into TF-PSA-Crypto as a separate submodule and incompatible API changes. That migration is work to consider independently of PQC support.
Yes last time I looked the gap wasn't massive, but it's there and indeed frustrating.
Quoted 6 lines
Quoted 6 lines
Quoted 1 line
Let’s revisit the PQC approach once we have more information on the roadmap.
Will do get back to you!
Thanks
/Ilias
Mit freundlichen Grüßen / Kind regards
Signature · 7 lines
Ayoub Zaki Embedded Systems Consultant Vaihinger Straße 2/1 D-71634 Ludwigsburg Email : [email protected] Homepage : https://embetrix.com
Quoted 11 lines · Ayoub Zaki
Hi Ilias,
Quoted 7 lines · Ilias Apalodimas
Apologies for the late reply.
Was waiting for some announcements to settle down.What I found out was this [0]. Comments welcome but I'd like to see how this plays out before making any decisions, since we use mbedTLS for https as well
Quoted 8 lines
Quoted 4 lines
Thanks
/IliasThanks for checking. Should I address Simon’s comments and send a v2 of the Linux based ML-DSA series or hold off until the direction for crypto integration in U-Boot is clearer?
We can hold off a bit until the overall direction is clearer, thanks.
Signature · 1 line
Tom
Hi Ayoub,
Quoted 3 lines · Ayoub Zaki
ML-DSA requires SHAKE128 and SHAKE256. The series adds generic one-shot and incremental SHAKE interfaces backed by Keccak-f[1600]. This code can be used by consumers other than ML-DSA.
The split needs some adjustment so that each patch builds and tests what it adds. See my comments on patches 1 and 3.
Quoted 1 line
Feedback is welcome on the public API and
Kconfigplacement.
For Kconfig, see my comment on patch 2.
On the API, it is hard to judge without a caller. The cover letter already says FIT will need an incremental transcript over the signed regions, so the single-contiguous-message API will most likely change once FIT support lands. Since FIT is the main motivation, I suggest including at least a minimal FIT crypto_algo hook-up in the series, even as RFC. That would show the API works with the existing region-based verify() path and give us a real consumer to test in CI, not just unit tests. What do you think?
On the mbedTLS discussion with Tom and Ilias: whichever backend we use, the public header should be independent of the implementation, so that a later move to mbedTLS / TF-PSA-Crypto does not affect callers. Please keep that in mind as you shape the API.
You offered a MAINTAINERS entry in your reply to Tom. Please can you add one in v2 covering lib/crypto/sha3.c, lib/crypto/mldsa.c, the headers, the tests and the doc? That records who is responsible for tracking Linux upstream.
Regards,
Simon