@@ -178,6 +178,109 @@ parameter set: XMSSMT-SHA2_20/2_256
178178signature length: 4963
179179```
180180
181+ ## Hybrid mode (classic + PQ)
182+
183+ wolfBoot supports a hybrid mode where both classic and PQ signatures are verified,
184+ sequentially. This allows for a gradual transition from classic to PQ signatures,
185+ and protects the secure boot mechanism from potential vulnerabilities in either of
186+ the two ciphers in use.
187+
188+ The hybrid mode is enabled by setting a ` SECONDARY_SIGN ` option in the config file,
189+ which specifies the secondary signature algorithm to be used. The secondary signature
190+ option requires the option ` WOLFBOOT_UNIVERSAL_KEYSTORE=1 ` , to ensure that the
191+ keystore can handle both classic and PQ keys.
192+
193+ The secondary signature option can be set to any of the supported PQ signature options.
194+
195+ The example configuration provided in ` config/examples/sim-ml-dsa-ecc-hybrid.config `
196+ demonstrates the use of hybrid mode with both ML-DSA-65 and ECC-384.
197+
198+ ### Hybrid signature
199+
200+ The ` sign ` tool supports hybrid signatures. It is sufficient to specify two
201+ ciphers argument from command line. When you do that, the tool expects two private
202+ key files path passed as arguments, instead of one.
203+
204+ The two public keys must be added to the same keystore. For this reason, the two
205+ keypairs must be generated either at the same time, or in two subsequent steps.
206+
207+ ### Generating keypairs for hybrid signatures
208+
209+ #### Generate both keys at the same time:
210+
211+ ```
212+ ./tools/keytools/keygen --ml_dsa -g wolfboot_signing_private_key.der --ecc384 -g wolfboot_signing_second_private_key.der
213+ ```
214+
215+ both keys are automatically added to the same keystore.
216+
217+
218+ #### Generate the two keys in separate steps
219+
220+ If you want to generate the keys in two steps, you will have to import the first
221+ key in the new keystore. The first public key is stored in ` keystore.der ` during
222+ the keypair generation:
223+ ```
224+ ./tools/keytools/keygen --ml_dsa -g wolfboot_signing_private_key.der
225+ ```
226+
227+ The first 16 bytes contain the keystore header, and must be skipped:
228+
229+ ```
230+ dd if=keystore.der of=ml_dsa-pubkey.der bs=1 skip=16
231+ ```
232+
233+ The new keypair can be generated (` -g ` ) while importing (` -i ` )the old public key:
234+
235+ ```
236+ ./tools/keytools/keygen --ml_dsa -i ml_dsa-pubkey.der -g --ecc384 wolfboot_signing_second_private_key.der
237+ ```
238+
239+ The keystore generated is now ready to be used by wolfBoot for hybrid signature verification.
240+
241+ ### Hybrid signature of the firmware
242+
243+ In both examples above, the two private keys are now available in separate .der files.
244+ The ` sign ` tool can now be used to sign the firmware with both keys:
245+
246+ ```
247+ ./tools/sign/sign --ml_dsa --ecc384 --sha256 test-app/image.elf wolfboot_signing_private_key.der wolfboot_signing_second_private_key.der 1
248+ ```
249+
250+ The command should confirm that both keys are loaded, and that the image is signed and includes the hybrid signature:
251+ ```
252+ wolfBoot KeyTools (Compiled C version)
253+ wolfBoot version 2020000
254+ Parsing arguments in hybrid mode
255+ Secondary private key: wolfboot_signing_second_private_key.der
256+ Secondary cipher: ECC384
257+ Version: 1
258+ Update type: Firmware
259+ Input image: test-app/image.elf
260+ Selected cipher: ML-DSA
261+ Selected hash : SHA256
262+ Private key: wolfboot_signing_private_key.der
263+ Secondary cipher: ECC384
264+ Secondary private key: wolfboot_signing_second_private_key.der
265+ Output image: test-app/image_v1_signed.bin
266+ Target partition id : 1
267+ info: using ML-DSA parameters: 3
268+ info: ML-DSA signature size: 3309
269+ Key buffer size: 5984
270+ info: ml-dsa priv len: 4032
271+ info: ml-dsa pub len: 1952
272+ Found ml-dsa key
273+ image header size overridden by config value (8192 bytes)
274+ Loading secondary key
275+ Key buffer size: 144
276+ Secondary ECC key, size: 96
277+ image header size overridden by config value (8192 bytes)
278+ Creating hybrid signature
279+ [...]
280+ ```
281+
282+ The resulting image ` image_v1_signed.bin ` contains both signatures, and can be verified using a wolfBoot with hybrid signature support.
283+
181284## Building the external PQ Integrations
182285
183286### ext_LMS Support
0 commit comments