mirror of https://github.com/wolfSSL/wolfBoot.git
281 lines
8.9 KiB
Markdown
281 lines
8.9 KiB
Markdown
# Post-Quantum Signatures
|
|
|
|
wolfBoot is continuously adding support for post-quantum (PQ) signature
|
|
algorithms as they mature. At present, support has been added for three NIST
|
|
approved PQ signature algorithms:
|
|
|
|
- ML-DSA: https://csrc.nist.gov/pubs/fips/204/final
|
|
- LMS/HSS: https://csrc.nist.gov/projects/stateful-hash-based-signatures
|
|
- XMSS/XMSS^MT: https://csrc.nist.gov/projects/stateful-hash-based-signatures
|
|
|
|
ML-DSA is a PQ lattice-based algorithm standardized by NIST (FIPS 204).
|
|
|
|
LMS/HSS and XMSS/XMSS^MT are both PQ stateful hash-based signature (HBS)
|
|
schemes, recommended in NIST SP 800-208.
|
|
|
|
In terms of relative tradeoffs:
|
|
- All three methods have fast verifying operations.
|
|
- All three methods have variable length signature sizes.
|
|
- ML-DSA key generation is much faster than LMS/HSS and XMSS/XMSS^MT.
|
|
- ML-DSA public keys are larger than LMS/HSS and XMSS/XMSS^MT, and
|
|
variable sized.
|
|
- LMS/HSS and XMSS/XMSS^MT have stateful private keys, which requires
|
|
more care with key generation and signing operations.
|
|
|
|
See these config files for simulated target examples:
|
|
|
|
- `config/examples/sim-ml-dsa.config`
|
|
- `config/examples/sim-ml-dsa3.config`
|
|
- `config/examples/sim-ml-dsa5.config`
|
|
- `config/examples/sim-lms.config`
|
|
- `config/examples/sim-xmss.config`
|
|
|
|
## Lattice Based Signature Methods
|
|
|
|
### ML-DSA
|
|
|
|
ML-DSA (Module-Lattice Digital Signature Algorithm) was standardized in
|
|
FIPS 204 (https://csrc.nist.gov/pubs/fips/204/final), based on its
|
|
round 3 predecessor CRYSTALS-DILITHIUM.
|
|
|
|
ML-DSA has three standardized parameter sets:
|
|
|
|
- `ML-DSA-44`
|
|
- `ML-DSA-65`
|
|
- `ML-DSA-87`
|
|
|
|
The numerical suffix (44, 65, 87) denotes the dimension of the matrix used
|
|
in the underlying lattice construction.
|
|
|
|
The private key, public key, signature size, and overall security strength
|
|
all depend on the parameter set:
|
|
|
|
```
|
|
#
|
|
# Private Key Public Key Signature Size Security Strength
|
|
# ML-DSA-44 2560 1312 2420 Category 2
|
|
# ML-DSA-65 4032 1952 3309 Category 3
|
|
# ML-DSA-87 4896 2592 4627 Category 5
|
|
#
|
|
```
|
|
|
|
### ML-DSA Config
|
|
|
|
See ML-DSA sim examples here:
|
|
|
|
```
|
|
config/examples/sim-ml-dsa.config
|
|
config/examples/sim-ml-dsa3.config
|
|
config/examples/sim-ml-dsa5.config
|
|
```
|
|
|
|
The security category level is configured with `ML_DSA_LEVEL=<num>`, where
|
|
num = 2, 3, 5. Here is an example for level 2:
|
|
|
|
```
|
|
# ML-DSA config examples:
|
|
#
|
|
# Category 2:
|
|
ML_DSA_LEVEL=2
|
|
IMAGE_SIGNATURE_SIZE=2420
|
|
IMAGE_HEADER_SIZE?=4840
|
|
```
|
|
|
|
Note: The wolfcrypt implementation of ML-DSA builds to the FIPS 204 final
|
|
standard by default. If you wish to conform to the older FIPS 204 draft
|
|
standard, then build with `WOLFSSL_MLDSA_FIPS204_DRAFT`
|
|
instead.
|
|
|
|
## Stateful Hash-Based Signature Methods
|
|
|
|
LMS/HSS and XMSS/XMSS^MT are both post-quantum stateful hash-based signature
|
|
(HBS) schemes. They are known for having small public keys, relatively fast
|
|
signing and verifying operations, but larger signatures. Their signature sizes
|
|
however are tunable via their different parameters, which affords a space-time
|
|
tradeoff.
|
|
|
|
Stateful HBS schemes are based on the security of their underlying hash
|
|
functions and Merkle trees, which are not expected to be broken by the advent
|
|
of cryptographically relevant quantum computers. For this reason they have
|
|
been recommended by both NIST SP 800-208, and the NSA's CNSA 2.0 suite.
|
|
|
|
See these links for more info on stateful HBS support and wolfSSL/wolfCrypt:
|
|
- https://www.wolfssl.com/documentation/manuals/wolfssl/appendix07.html#post-quantum-stateful-hash-based-signatures
|
|
- https://github.com/wolfSSL/wolfssl-examples/tree/master/pq/stateful_hash_sig
|
|
|
|
### Supported PQ HBS Options
|
|
|
|
These two hash-based PQ signature options are supported:
|
|
- LMS: uses wolfcrypt implementation from `wc_lms.c`, and `wc_lms_impl.c`.
|
|
- XMSS: uses wolfcrypt implementation from `wc_xmss.c`, and `wc_xmss_impl.c`.
|
|
|
|
### LMS/HSS Config
|
|
|
|
A new LMS sim example has been added here:
|
|
```
|
|
config/examples/sim-lms.config
|
|
```
|
|
|
|
The `LMS_LEVELS`, `LMS_HEIGHT`, and `LMS_WINTERNITZ`, `IMAGE_SIGNATURE_SIZE`,
|
|
and (optionally) `IMAGE_HEADER_SIZE` must be set:
|
|
|
|
```
|
|
SIGN?=LMS
|
|
...
|
|
LMS_LEVELS=2
|
|
LMS_HEIGHT=5
|
|
LMS_WINTERNITZ=8
|
|
...
|
|
IMAGE_SIGNATURE_SIZE=2644
|
|
IMAGE_HEADER_SIZE?=5288
|
|
```
|
|
|
|
In LMS the signature size is a function of the parameters. Use the added helper
|
|
script `tools/lms/lms_siglen.sh` to calculate your signature length given your
|
|
LMS parameters:
|
|
```
|
|
$ ./tools/lms/lms_siglen.sh 2 5 8
|
|
levels: 2
|
|
height: 5
|
|
winternitz: 8
|
|
signature length: 2644
|
|
```
|
|
|
|
### XMSS/XMSS^MT Config
|
|
|
|
A new XMSS sim example has been added here:
|
|
```
|
|
config/examples/sim-xmss.config
|
|
```
|
|
|
|
The `XMSS_PARAMS`, `IMAGE_SIGNATURE_SIZE`, and (optionally) `IMAGE_HEADER_SIZE`
|
|
must be set:
|
|
|
|
```
|
|
SIGN?=XMSS
|
|
...
|
|
XMSS_PARAMS='XMSS-SHA2_10_256'
|
|
...
|
|
IMAGE_SIGNATURE_SIZE=2500
|
|
IMAGE_HEADER_SIZE?=5000
|
|
```
|
|
|
|
The `XMSS_PARAMS` may be any SHA256 parameter set string from Tables 10 and 11
|
|
from NIST SP 800-208. Use the helper script `tools/xmss/xmss_siglen.sh` to
|
|
calculate your signature length given your XMSS/XMSS^MT parameter string, e.g.:
|
|
```
|
|
$ ./tools/xmss/xmss_siglen.sh XMSS-SHA2_10_256
|
|
parameter set: XMSS-SHA2_10_256
|
|
signature length: 2500
|
|
```
|
|
|
|
```
|
|
$ ./tools/xmss/xmss_siglen.sh XMSSMT-SHA2_20/2_256
|
|
parameter set: XMSSMT-SHA2_20/2_256
|
|
signature length: 4963
|
|
```
|
|
|
|
## Hybrid mode (classic + PQ)
|
|
|
|
wolfBoot supports a hybrid mode where both classic and PQ signatures are verified,
|
|
sequentially. This allows for a gradual transition from classic to PQ signatures,
|
|
and protects the secure boot mechanism from potential vulnerabilities in either of
|
|
the two ciphers in use.
|
|
|
|
The hybrid mode is enabled by setting a `SECONDARY_SIGN` option in the config file,
|
|
which specifies the secondary signature algorithm to be used. The secondary signature
|
|
option requires the option `WOLFBOOT_UNIVERSAL_KEYSTORE=1`, to ensure that the
|
|
keystore can handle both classic and PQ keys.
|
|
|
|
The secondary signature option can be set to any of the supported PQ signature options.
|
|
|
|
The example configuration provided in `config/examples/sim-ml-dsa-ecc-hybrid.config`
|
|
demonstrates the use of hybrid mode with both ML-DSA-65 and ECC-384.
|
|
|
|
### Hybrid signature
|
|
|
|
The `sign` tool supports hybrid signatures. It is sufficient to specify two
|
|
ciphers argument from command line. When you do that, the tool expects two private
|
|
key files path passed as arguments, instead of one.
|
|
|
|
The two public keys must be added to the same keystore. For this reason, the two
|
|
keypairs must be generated either at the same time, or in two subsequent steps.
|
|
|
|
### Generating keypairs for hybrid signatures
|
|
|
|
#### Generate both keys at the same time:
|
|
|
|
```
|
|
./tools/keytools/keygen --ml_dsa -g wolfboot_signing_private_key.der --ecc384 -g wolfboot_signing_second_private_key.der
|
|
```
|
|
|
|
both keys are automatically added to the same keystore.
|
|
|
|
|
|
#### Generate the two keys in separate steps
|
|
|
|
If you want to generate the keys in two steps, you will have to import the first
|
|
key in the new keystore. The first public key is stored in `keystore.der` during
|
|
the keypair generation:
|
|
```
|
|
./tools/keytools/keygen --ml_dsa -g wolfboot_signing_private_key.der
|
|
```
|
|
|
|
The first 16 bytes contain the keystore header, and must be skipped:
|
|
|
|
```
|
|
dd if=keystore.der of=ml_dsa-pubkey.der bs=1 skip=16
|
|
```
|
|
|
|
The new keypair can be generated (`-g`) while importing (`-i`)the old public key:
|
|
|
|
```
|
|
./tools/keytools/keygen --ml_dsa -i ml_dsa-pubkey.der -g --ecc384 wolfboot_signing_second_private_key.der
|
|
```
|
|
|
|
The keystore generated is now ready to be used by wolfBoot for hybrid signature verification.
|
|
|
|
### Hybrid signature of the firmware
|
|
|
|
In both examples above, the two private keys are now available in separate .der files.
|
|
The `sign` tool can now be used to sign the firmware with both keys:
|
|
|
|
```
|
|
./tools/sign/sign --ml_dsa --ecc384 --sha256 test-app/image.elf wolfboot_signing_private_key.der wolfboot_signing_second_private_key.der 1
|
|
```
|
|
|
|
The command should confirm that both keys are loaded, and that the image is signed and includes the hybrid signature:
|
|
```
|
|
wolfBoot KeyTools (Compiled C version)
|
|
wolfBoot version 2020000
|
|
Parsing arguments in hybrid mode
|
|
Secondary private key: wolfboot_signing_second_private_key.der
|
|
Secondary cipher: ECC384
|
|
Version: 1
|
|
Update type: Firmware
|
|
Input image: test-app/image.elf
|
|
Selected cipher: ML-DSA
|
|
Selected hash : SHA256
|
|
Private key: wolfboot_signing_private_key.der
|
|
Secondary cipher: ECC384
|
|
Secondary private key: wolfboot_signing_second_private_key.der
|
|
Output image: test-app/image_v1_signed.bin
|
|
Target partition id : 1
|
|
info: using ML-DSA parameters: 3
|
|
info: ML-DSA signature size: 3309
|
|
Key buffer size: 5984
|
|
info: ml-dsa priv len: 4032
|
|
info: ml-dsa pub len: 1952
|
|
Found ml-dsa key
|
|
image header size overridden by config value (8192 bytes)
|
|
Loading secondary key
|
|
Key buffer size: 144
|
|
Secondary ECC key, size: 96
|
|
image header size overridden by config value (8192 bytes)
|
|
Creating hybrid signature
|
|
[...]
|
|
```
|
|
|
|
The resulting image `image_v1_signed.bin` contains both signatures, and can be verified using a wolfBoot with hybrid signature support.
|
|
|