Skip to content

zephyr: imgtool: sim: support multiple keys (closes #2700)#2701

Draft
JPHutchins wants to merge 1 commit intomcu-tools:mainfrom
intercreate:feature-zephyr-multiple-signing-keys
Draft

zephyr: imgtool: sim: support multiple keys (closes #2700)#2701
JPHutchins wants to merge 1 commit intomcu-tools:mainfrom
intercreate:feature-zephyr-multiple-signing-keys

Conversation

@JPHutchins
Copy link
Copy Markdown
Contributor

Closes #2700.

Summary

Extend the Zephyr port to optionally embed a second signing-verification key in the bootloader. When CONFIG_BOOT_SIGNATURE_KEY_FILE_2 is set, the bootloader accepts images signed by either the primary or the secondary key. When it is empty (the default), the compiled output is unchanged relative to current upstream — no new symbols, no new array entries, no runtime cost.

See the linked issue for motivation, user demand, and the underlying documented-but-unimplemented design intent.

Testing

Verified:

  • imgtool unit tests (scripts/tests/test_keys.py): pass, including the new --name-suffix positive and negative cases across all supported key types.
  • Simulator tests with sig-ed25519 alone and with sig-ed25519,sig-second-key: the four new multi_key scenarios pass under both configurations, with the #[cfg]-gated variants applying correctly.

Not yet verified:

  • End-to-end on real hardware. I have not run the prod-bootloader / dev-bootloader matrix on a physical target. The simulator exercises the same boot/zephyr/keys.c code path that production builds use, so I expect parity, but that's inference, not a measurement. Happy to perform hardware validation before merge if that's the expectation, or as a follow-up if simulator + imgtool-test coverage is considered sufficient for a gated, off-by-default feature. Please advise.

CI expected to exercise:

  • Sim workflow — new feature combinations.
  • Build Zephyr samples with Twister — existing coverage unaffected; the new option defaults off.
  • imgtool workflow — new unit tests.

Design questions for reviewers

Three points where I made a choice but should be considered open:

1. Symbol-renaming mechanism. I added --name-suffix to imgtool getpub / getpubhash. The alternative was a post-processing rename script inside the Zephyr CMake build. I preferred the imgtool route because it's reusable across ports (Mynewt, Espressif, sim), unit-testable, and keeps the generated sources clean. If you'd rather keep imgtool's CLI surface smaller, I can move the rename logic into the build system — let me know.

2. autogen-pubkey2.c vs autogen-pubkey2.h. The existing mechanism for the primary key emits build/zephyr/autogen-pubkey.h and #includes it from boot/zephyr/keys.c. This PR emits autogen-pubkey2.c and links it as a separate source file instead. I chose this because it keeps keys.c structurally unchanged (just an added extern block) and avoids a conditional #include of a file that may not exist. If you prefer symmetry with the primary-key mechanism (i.e. a .h #included conditionally), I'll switch — small change, called out here so it's not a surprise.

3. Scope of sig-second-key in the simulator. Currently wired for sig-ed25519 only. Extending to RSA and ECDSA in sim/mcuboot-sys/csupport/keys.c is mechanical (another root_pub_der_2 for each type). Happy to do it in this PR if you'd rather see full matrix coverage before merge, or as a follow-up if you'd rather land the Zephyr-port change first.

4. Kconfig naming. I went with BOOT_SIGNATURE_KEY_FILE_2. The alternative is a list-style BOOT_SIGNATURE_KEY_FILES taking whitespace-separated paths. In practice every multi-key fleet I've seen is "prod + dev", so two is the right starting point, and _N leaves room to grow. Push back if you'd rather pick the list form from the start.

@JPHutchins
Copy link
Copy Markdown
Contributor Author

Local test runs

Click to expand
$ cd scripts && /home/jp/repos/mcuboot/scratch/imgtool-venv/bin/pytest -v
===================================== test session starts =====================================
platform linux -- Python 3.12.3, pytest-9.0.3, pluggy-1.6.0 -- /home/jp/repos/mcuboot/scratch/imgtool-venv/bin/python3
cachedir: .pytest_cache
rootdir: /home/jp/repos/mcuboot/scripts
collected 195 items

tests/keys/test_ecdsa.py::EcKeyGeneration::test_emit PASSED                             [  0%]
tests/keys/test_ecdsa.py::EcKeyGeneration::test_emit_pub PASSED                         [  1%]
tests/keys/test_ecdsa.py::EcKeyGeneration::test_keygen PASSED                           [  1%]
tests/keys/test_ecdsa.py::EcKeyGeneration::test_sig PASSED                              [  2%]
tests/keys/test_ed25519.py::Ed25519KeyGeneration::test_emit PASSED                      [  2%]
tests/keys/test_ed25519.py::Ed25519KeyGeneration::test_emit_pub PASSED                  [  3%]
tests/keys/test_ed25519.py::Ed25519KeyGeneration::test_keygen PASSED                    [  3%]
tests/keys/test_ed25519.py::Ed25519KeyGeneration::test_sig PASSED                       [  4%]
tests/keys/test_rsa.py::KeyGeneration::test_emit PASSED                                 [  4%]
tests/keys/test_rsa.py::KeyGeneration::test_emit_pub PASSED                             [  5%]
tests/keys/test_rsa.py::KeyGeneration::test_keygen PASSED                               [  5%]
tests/keys/test_rsa.py::KeyGeneration::test_sig PASSED                                  [  6%]
tests/test_commands.py::test_new_command PASSED                                         [  6%]
tests/test_commands.py::test_help PASSED                                                [  7%]
tests/test_commands.py::test_version PASSED                                             [  7%]
tests/test_commands.py::test_unknown PASSED                                             [  8%]
tests/test_commands.py::test_cmd_help[create] PASSED                                    [  8%]
tests/test_commands.py::test_cmd_help[dumpinfo] PASSED                                  [  9%]
tests/test_commands.py::test_cmd_help[getpriv] PASSED                                   [  9%]
tests/test_commands.py::test_cmd_help[getpub] PASSED                                    [ 10%]
tests/test_commands.py::test_cmd_help[getpubhash] PASSED                                [ 10%]
tests/test_commands.py::test_cmd_help[keygen] PASSED                                    [ 11%]
tests/test_commands.py::test_cmd_help[sign] PASSED                                      [ 11%]
tests/test_commands.py::test_cmd_help[verify] PASSED                                    [ 12%]
tests/test_commands.py::test_cmd_help[version] PASSED                                   [ 12%]
tests/test_commands.py::test_cmd_dif_help[create-create] PASSED                         [ 13%]
tests/test_commands.py::test_cmd_dif_help[create-dumpinfo] PASSED                       [ 13%]
tests/test_commands.py::test_cmd_dif_help[create-getpriv] PASSED                        [ 14%]
tests/test_commands.py::test_cmd_dif_help[create-getpub] PASSED                         [ 14%]
tests/test_commands.py::test_cmd_dif_help[create-getpubhash] PASSED                     [ 15%]
tests/test_commands.py::test_cmd_dif_help[create-keygen] PASSED                         [ 15%]
tests/test_commands.py::test_cmd_dif_help[create-sign] PASSED                           [ 16%]
tests/test_commands.py::test_cmd_dif_help[create-verify] PASSED                         [ 16%]
tests/test_commands.py::test_cmd_dif_help[create-version] PASSED                        [ 17%]
tests/test_commands.py::test_cmd_dif_help[dumpinfo-create] PASSED                       [ 17%]
tests/test_commands.py::test_cmd_dif_help[dumpinfo-dumpinfo] PASSED                     [ 18%]
tests/test_commands.py::test_cmd_dif_help[dumpinfo-getpriv] PASSED                      [ 18%]
tests/test_commands.py::test_cmd_dif_help[dumpinfo-getpub] PASSED                       [ 19%]
tests/test_commands.py::test_cmd_dif_help[dumpinfo-getpubhash] PASSED                   [ 20%]
tests/test_commands.py::test_cmd_dif_help[dumpinfo-keygen] PASSED                       [ 20%]
tests/test_commands.py::test_cmd_dif_help[dumpinfo-sign] PASSED                         [ 21%]
tests/test_commands.py::test_cmd_dif_help[dumpinfo-verify] PASSED                       [ 21%]
tests/test_commands.py::test_cmd_dif_help[dumpinfo-version] PASSED                      [ 22%]
tests/test_commands.py::test_cmd_dif_help[getpriv-create] PASSED                        [ 22%]
tests/test_commands.py::test_cmd_dif_help[getpriv-dumpinfo] PASSED                      [ 23%]
tests/test_commands.py::test_cmd_dif_help[getpriv-getpriv] PASSED                       [ 23%]
tests/test_commands.py::test_cmd_dif_help[getpriv-getpub] PASSED                        [ 24%]
tests/test_commands.py::test_cmd_dif_help[getpriv-getpubhash] PASSED                    [ 24%]
tests/test_commands.py::test_cmd_dif_help[getpriv-keygen] PASSED                        [ 25%]
tests/test_commands.py::test_cmd_dif_help[getpriv-sign] PASSED                          [ 25%]
tests/test_commands.py::test_cmd_dif_help[getpriv-verify] PASSED                        [ 26%]
tests/test_commands.py::test_cmd_dif_help[getpriv-version] PASSED                       [ 26%]
tests/test_commands.py::test_cmd_dif_help[getpub-create] PASSED                         [ 27%]
tests/test_commands.py::test_cmd_dif_help[getpub-dumpinfo] PASSED                       [ 27%]
tests/test_commands.py::test_cmd_dif_help[getpub-getpriv] PASSED                        [ 28%]
tests/test_commands.py::test_cmd_dif_help[getpub-getpub] PASSED                         [ 28%]
tests/test_commands.py::test_cmd_dif_help[getpub-getpubhash] PASSED                     [ 29%]
tests/test_commands.py::test_cmd_dif_help[getpub-keygen] PASSED                         [ 29%]
tests/test_commands.py::test_cmd_dif_help[getpub-sign] PASSED                           [ 30%]
tests/test_commands.py::test_cmd_dif_help[getpub-verify] PASSED                         [ 30%]
tests/test_commands.py::test_cmd_dif_help[getpub-version] PASSED                        [ 31%]
tests/test_commands.py::test_cmd_dif_help[getpubhash-create] PASSED                     [ 31%]
tests/test_commands.py::test_cmd_dif_help[getpubhash-dumpinfo] PASSED                   [ 32%]
tests/test_commands.py::test_cmd_dif_help[getpubhash-getpriv] PASSED                    [ 32%]
tests/test_commands.py::test_cmd_dif_help[getpubhash-getpub] PASSED                     [ 33%]
tests/test_commands.py::test_cmd_dif_help[getpubhash-getpubhash] PASSED                 [ 33%]
tests/test_commands.py::test_cmd_dif_help[getpubhash-keygen] PASSED                     [ 34%]
tests/test_commands.py::test_cmd_dif_help[getpubhash-sign] PASSED                       [ 34%]
tests/test_commands.py::test_cmd_dif_help[getpubhash-verify] PASSED                     [ 35%]
tests/test_commands.py::test_cmd_dif_help[getpubhash-version] PASSED                    [ 35%]
tests/test_commands.py::test_cmd_dif_help[keygen-create] PASSED                         [ 36%]
tests/test_commands.py::test_cmd_dif_help[keygen-dumpinfo] PASSED                       [ 36%]
tests/test_commands.py::test_cmd_dif_help[keygen-getpriv] PASSED                        [ 37%]
tests/test_commands.py::test_cmd_dif_help[keygen-getpub] PASSED                         [ 37%]
tests/test_commands.py::test_cmd_dif_help[keygen-getpubhash] PASSED                     [ 38%]
tests/test_commands.py::test_cmd_dif_help[keygen-keygen] PASSED                         [ 38%]
tests/test_commands.py::test_cmd_dif_help[keygen-sign] PASSED                           [ 39%]
tests/test_commands.py::test_cmd_dif_help[keygen-verify] PASSED                         [ 40%]
tests/test_commands.py::test_cmd_dif_help[keygen-version] PASSED                        [ 40%]
tests/test_commands.py::test_cmd_dif_help[sign-create] PASSED                           [ 41%]
tests/test_commands.py::test_cmd_dif_help[sign-dumpinfo] PASSED                         [ 41%]
tests/test_commands.py::test_cmd_dif_help[sign-getpriv] PASSED                          [ 42%]
tests/test_commands.py::test_cmd_dif_help[sign-getpub] PASSED                           [ 42%]
tests/test_commands.py::test_cmd_dif_help[sign-getpubhash] PASSED                       [ 43%]
tests/test_commands.py::test_cmd_dif_help[sign-keygen] PASSED                           [ 43%]
tests/test_commands.py::test_cmd_dif_help[sign-sign] PASSED                             [ 44%]
tests/test_commands.py::test_cmd_dif_help[sign-verify] PASSED                           [ 44%]
tests/test_commands.py::test_cmd_dif_help[sign-version] PASSED                          [ 45%]
tests/test_commands.py::test_cmd_dif_help[verify-create] PASSED                         [ 45%]
tests/test_commands.py::test_cmd_dif_help[verify-dumpinfo] PASSED                       [ 46%]
tests/test_commands.py::test_cmd_dif_help[verify-getpriv] PASSED                        [ 46%]
tests/test_commands.py::test_cmd_dif_help[verify-getpub] PASSED                         [ 47%]
tests/test_commands.py::test_cmd_dif_help[verify-getpubhash] PASSED                     [ 47%]
tests/test_commands.py::test_cmd_dif_help[verify-keygen] PASSED                         [ 48%]
tests/test_commands.py::test_cmd_dif_help[verify-sign] PASSED                           [ 48%]
tests/test_commands.py::test_cmd_dif_help[verify-verify] PASSED                         [ 49%]
tests/test_commands.py::test_cmd_dif_help[verify-version] PASSED                        [ 49%]
tests/test_commands.py::test_cmd_dif_help[version-create] PASSED                        [ 50%]
tests/test_commands.py::test_cmd_dif_help[version-dumpinfo] PASSED                      [ 50%]
tests/test_commands.py::test_cmd_dif_help[version-getpriv] PASSED                       [ 51%]
tests/test_commands.py::test_cmd_dif_help[version-getpub] PASSED                        [ 51%]
tests/test_commands.py::test_cmd_dif_help[version-getpubhash] PASSED                    [ 52%]
tests/test_commands.py::test_cmd_dif_help[version-keygen] PASSED                        [ 52%]
tests/test_commands.py::test_cmd_dif_help[version-sign] PASSED                          [ 53%]
tests/test_commands.py::test_cmd_dif_help[version-verify] PASSED                        [ 53%]
tests/test_commands.py::test_cmd_dif_help[version-version] PASSED                       [ 54%]
tests/test_compression.py::test_lzma2_compression[lzma2-True] PASSED                    [ 54%]
tests/test_compression.py::test_lzma2_compression[disabled-False] PASSED                [ 55%]
tests/test_keys.py::test_keygen[rsa-2048] PASSED                                        [ 55%]
tests/test_keys.py::test_keygen[rsa-3072] PASSED                                        [ 56%]
tests/test_keys.py::test_keygen[ecdsa-p256] PASSED                                      [ 56%]
tests/test_keys.py::test_keygen[ecdsa-p384] PASSED                                      [ 57%]
tests/test_keys.py::test_keygen[ed25519] PASSED                                         [ 57%]
tests/test_keys.py::test_keygen[x25519] PASSED                                          [ 58%]
tests/test_keys.py::test_keygen_type[rsa-2048] PASSED                                   [ 58%]
tests/test_keys.py::test_keygen_type[rsa-3072] PASSED                                   [ 59%]
tests/test_keys.py::test_keygen_type[ecdsa-p256] PASSED                                 [ 60%]
tests/test_keys.py::test_keygen_type[ecdsa-p384] PASSED                                 [ 60%]
tests/test_keys.py::test_keygen_type[ed25519] PASSED                                    [ 61%]
tests/test_keys.py::test_keygen_type[x25519] PASSED                                     [ 61%]
tests/test_keys.py::test_getpriv[openssl-rsa-2048] PASSED                               [ 62%]
tests/test_keys.py::test_getpriv[openssl-rsa-3072] PASSED                               [ 62%]
tests/test_keys.py::test_getpriv[openssl-ecdsa-p256] PASSED                             [ 63%]
tests/test_keys.py::test_getpriv[openssl-ecdsa-p384] PASSED                             [ 63%]
tests/test_keys.py::test_getpriv[openssl-ed25519] XFAIL                                 [ 64%]
tests/test_keys.py::test_getpriv[openssl-x25519] XFAIL                                  [ 64%]
tests/test_keys.py::test_getpriv[pkcs8-rsa-2048] XFAIL                                  [ 65%]
tests/test_keys.py::test_getpriv[pkcs8-rsa-3072] XFAIL                                  [ 65%]
tests/test_keys.py::test_getpriv[pkcs8-ecdsa-p256] PASSED                               [ 66%]
tests/test_keys.py::test_getpriv[pkcs8-ecdsa-p384] PASSED                               [ 66%]
tests/test_keys.py::test_getpriv[pkcs8-ed25519] XFAIL                                   [ 67%]
tests/test_keys.py::test_getpriv[pkcs8-x25519] PASSED                                   [ 67%]
tests/test_keys.py::test_getpub[lang-c-rsa-2048] PASSED                                 [ 68%]
tests/test_keys.py::test_getpub[lang-c-rsa-3072] PASSED                                 [ 68%]
tests/test_keys.py::test_getpub[lang-c-ecdsa-p256] PASSED                               [ 69%]
tests/test_keys.py::test_getpub[lang-c-ecdsa-p384] PASSED                               [ 69%]
tests/test_keys.py::test_getpub[lang-c-ed25519] PASSED                                  [ 70%]
tests/test_keys.py::test_getpub[lang-c-x25519] PASSED                                   [ 70%]
tests/test_keys.py::test_getpub[lang-rust-rsa-2048] PASSED                              [ 71%]
tests/test_keys.py::test_getpub[lang-rust-rsa-3072] PASSED                              [ 71%]
tests/test_keys.py::test_getpub[lang-rust-ecdsa-p256] PASSED                            [ 72%]
tests/test_keys.py::test_getpub[lang-rust-ecdsa-p384] PASSED                            [ 72%]
tests/test_keys.py::test_getpub[lang-rust-ed25519] PASSED                               [ 73%]
tests/test_keys.py::test_getpub[lang-rust-x25519] PASSED                                [ 73%]
tests/test_keys.py::test_getpub[pem-rsa-2048] PASSED                                    [ 74%]
tests/test_keys.py::test_getpub[pem-rsa-3072] PASSED                                    [ 74%]
tests/test_keys.py::test_getpub[pem-ecdsa-p256] PASSED                                  [ 75%]
tests/test_keys.py::test_getpub[pem-ecdsa-p384] PASSED                                  [ 75%]
tests/test_keys.py::test_getpub[pem-ed25519] XFAIL                                      [ 76%]
tests/test_keys.py::test_getpub[pem-x25519] PASSED                                      [ 76%]
tests/test_keys.py::test_getpub[raw-rsa-2048] PASSED                                    [ 77%]
tests/test_keys.py::test_getpub[raw-rsa-3072] PASSED                                    [ 77%]
tests/test_keys.py::test_getpub[raw-ecdsa-p256] PASSED                                  [ 78%]
tests/test_keys.py::test_getpub[raw-ecdsa-p384] PASSED                                  [ 78%]
tests/test_keys.py::test_getpub[raw-ed25519] PASSED                                     [ 79%]
tests/test_keys.py::test_getpub[raw-x25519] PASSED                                      [ 80%]
tests/test_keys.py::test_getpubhash[lang-c-rsa-2048] PASSED                             [ 80%]
tests/test_keys.py::test_getpubhash[lang-c-rsa-3072] PASSED                             [ 81%]
tests/test_keys.py::test_getpubhash[lang-c-ecdsa-p256] PASSED                           [ 81%]
tests/test_keys.py::test_getpubhash[lang-c-ecdsa-p384] PASSED                           [ 82%]
tests/test_keys.py::test_getpubhash[lang-c-ed25519] PASSED                              [ 82%]
tests/test_keys.py::test_getpubhash[lang-c-x25519] PASSED                               [ 83%]
tests/test_keys.py::test_getpubhash[raw-rsa-2048] PASSED                                [ 83%]
tests/test_keys.py::test_getpubhash[raw-rsa-3072] PASSED                                [ 84%]
tests/test_keys.py::test_getpubhash[raw-ecdsa-p256] PASSED                              [ 84%]
tests/test_keys.py::test_getpubhash[raw-ecdsa-p384] PASSED                              [ 85%]
tests/test_keys.py::test_getpubhash[raw-ed25519] PASSED                                 [ 85%]
tests/test_keys.py::test_getpubhash[raw-x25519] PASSED                                  [ 86%]
tests/test_keys.py::test_getpub_name_suffix_c[rsa-2048] PASSED                          [ 86%]
tests/test_keys.py::test_getpub_name_suffix_c[rsa-3072] PASSED                          [ 87%]
tests/test_keys.py::test_getpub_name_suffix_c[ecdsa-p256] PASSED                        [ 87%]
tests/test_keys.py::test_getpub_name_suffix_c[ecdsa-p384] PASSED                        [ 88%]
tests/test_keys.py::test_getpub_name_suffix_c[ed25519] PASSED                           [ 88%]
tests/test_keys.py::test_getpub_name_suffix_c[x25519] PASSED                            [ 89%]
tests/test_keys.py::test_getpub_name_suffix_rust[rsa-2048] PASSED                       [ 89%]
tests/test_keys.py::test_getpub_name_suffix_rust[rsa-3072] PASSED                       [ 90%]
tests/test_keys.py::test_getpub_name_suffix_rust[ecdsa-p256] PASSED                     [ 90%]
tests/test_keys.py::test_getpub_name_suffix_rust[ecdsa-p384] PASSED                     [ 91%]
tests/test_keys.py::test_getpub_name_suffix_rust[ed25519] PASSED                        [ 91%]
tests/test_keys.py::test_getpub_name_suffix_rust[x25519] PASSED                         [ 92%]
tests/test_keys.py::test_getpub_name_suffix_rejected[pem] PASSED                        [ 92%]
tests/test_keys.py::test_getpub_name_suffix_rejected[raw] PASSED                        [ 93%]
tests/test_keys.py::test_getpubhash_name_suffix_c[rsa-2048] PASSED                      [ 93%]
tests/test_keys.py::test_getpubhash_name_suffix_c[rsa-3072] PASSED                      [ 94%]
tests/test_keys.py::test_getpubhash_name_suffix_c[ecdsa-p256] PASSED                    [ 94%]
tests/test_keys.py::test_getpubhash_name_suffix_c[ecdsa-p384] PASSED                    [ 95%]
tests/test_keys.py::test_getpubhash_name_suffix_c[ed25519] PASSED                       [ 95%]
tests/test_keys.py::test_getpubhash_name_suffix_c[x25519] PASSED                        [ 96%]
tests/test_keys.py::test_getpubhash_name_suffix_rejects_raw PASSED                      [ 96%]
tests/test_keys.py::test_sign_verify[rsa-2048] PASSED                                   [ 97%]
tests/test_keys.py::test_sign_verify[rsa-3072] PASSED                                   [ 97%]
tests/test_keys.py::test_sign_verify[ecdsa-p256] PASSED                                 [ 98%]
tests/test_keys.py::test_sign_verify[ecdsa-p384] PASSED                                 [ 98%]
tests/test_keys.py::test_sign_verify[ed25519] PASSED                                    [ 99%]
tests/test_keys.py::test_sign_verify[x25519] XFAIL                                      [100%]

=============================== 188 passed, 7 xfailed in 7.95s ================================

$ cd sim && cargo test --features sig-ed25519 --test core
warning: use of deprecated function `rand::thread_rng`: Renamed to `rng`
    --> sim/src/image.rs:1707:29
     |
1707 |         let mut rng = rand::thread_rng();
     |                             ^^^^^^^^^^
     |
     = note: `#[warn(deprecated)]` on by default

warning: use of deprecated method `rand::Rng::gen_range`: Renamed to `random_range`
    --> sim/src/image.rs:1711:37
     |
1711 |             let reset_counter = rng.gen_range(1 ..= remaining_ops / 2);
     |                                     ^^^^^^^^^

warning: `bootsim` (lib) generated 2 warnings
    Finished `test` profile [optimized + debuginfo] target(s) in 0.06s
     Running tests/core.rs (/home/jp/repos/mcuboot/target/debug/deps/core-658591a82fff9de3)

running 28 tests
test dependency_combos ... ok
test bootstrap ... ok
test hw_prot_failed_security_cnt_check ... ok
test hw_prot_missing_security_cnt ... ok
test direct_xip_first ... ok
test oversized_bootstrap ... ok
test multi_key::signed_primary_key_boots ... ok
test norevert_newimage ... ok
test oversized_secondary_slot ... ok
test ram_load_corrupt_higher_version_image ... ok
test ram_load_missing_header_flag ... ok
test multi_key::signed_unknown_key_rejected ... ok
test ram_load_failed_validation ... ok
test ram_load_from_flash ... ok
test bad_secondary_slot ... ok
test multi_key::single_key_build_rejects_secondary_key_image ... ok
test ram_load_first ... ok
test downgrade_prevention ... ok
test ram_load_split ... ok
test ram_load_out_of_bounds ... ok
test secondary_trailer_leftover ... ok
test perm_with_random_fails ... ok
test norevert ... ok
test status_write_fails_complete ... ok
test status_write_fails_with_reset ... ok
test basic_revert ... ok
test perm_with_fails has been running for over 60 seconds
test revert_with_fails has been running for over 60 seconds
test perm_with_fails ... ok
test revert_with_fails ... ok

test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 284.80s


$ cd sim && cargo test --features 'sig-ed25519 sig-second-key' --test core
   Compiling bootsim v0.1.0 (/home/jp/repos/mcuboot/sim)
warning: use of deprecated function `rand::thread_rng`: Renamed to `rng`
    --> sim/src/image.rs:1707:29
     |
1707 |         let mut rng = rand::thread_rng();
     |                             ^^^^^^^^^^
     |
     = note: `#[warn(deprecated)]` on by default

warning: use of deprecated method `rand::Rng::gen_range`: Renamed to `random_range`
    --> sim/src/image.rs:1711:37
     |
1711 |             let reset_counter = rng.gen_range(1 ..= remaining_ops / 2);
     |                                     ^^^^^^^^^

warning: `bootsim` (lib) generated 2 warnings
    Finished `test` profile [optimized + debuginfo] target(s) in 4.54s
     Running tests/core.rs (/home/jp/repos/mcuboot/target/debug/deps/core-fc4e87a8e8bb9e24)

running 28 tests
test dependency_combos ... ok
test oversized_bootstrap ... ok
test hw_prot_failed_security_cnt_check ... ok
test hw_prot_missing_security_cnt ... ok
test bootstrap ... ok
test norevert_newimage ... ok
test direct_xip_first ... ok
test multi_key::signed_secondary_key_boots ... ok
test oversized_secondary_slot ... ok
test multi_key::signed_unknown_key_rejected ... ok
test ram_load_corrupt_higher_version_image ... ok
test multi_key::signed_primary_key_boots ... ok
test ram_load_failed_validation ... ok
test bad_secondary_slot ... ok
test ram_load_from_flash ... ok
test downgrade_prevention ... ok
test ram_load_out_of_bounds ... ok
test ram_load_missing_header_flag ... ok
test ram_load_first ... ok
test norevert ... ok
test secondary_trailer_leftover ... ok
test ram_load_split ... ok
test perm_with_random_fails ... ok
test status_write_fails_complete ... ok
test status_write_fails_with_reset ... ok
test basic_revert ... ok
test perm_with_fails has been running for over 60 seconds
test revert_with_fails has been running for over 60 seconds
test perm_with_fails ... ok
test revert_with_fails ... ok

test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 293.63s

zephyr: support 2 signing keys

Add optional kconfig BOOT_SIGNATURE_KEY_FILE_2. Update
keys.c to support multiple keys of the same type.

imgtool: add --name-suffix to getpub

Update documentation and test coverage.

sim: tests for multiple ed25519 keys

Update sim test cases to cover multiple keys.

Signed-off-by: JP Hutchins <jp@intercreate.io>
@nordicjm
Copy link
Copy Markdown
Collaborator

the idea here would need @de-nordic to look at it and approve, but do not add another Kconfig for another key, how do you add a 3rd key? a 9th key? 300 keys? Just use multiple files in the existing Kconfig and iterate them as a list in cmake

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

zephyr: support embedding a second signing key (CONFIG_BOOT_SIGNATURE_KEY_FILE_2)

2 participants