chore: handle backup security findings#590
Conversation
Consolidated Tests Results 2026-05-15 - 13:00:38Test ResultsDetails
test-reporter: Run #2154
🎉 All tests passed!TestsView All Tests
🍂 No flaky tests in this run. Github Test Reporter by CTRF 💚 🔄 This comment has been updated |
| tag: Cow::Borrowed("super fun version"), | ||
| }; | ||
|
|
||
| // KMS test |
There was a problem hiding this comment.
This is removed since it will no longer be accurate since we updated the format. Furthermore, we can ignore the backwards tests since it is currently not deployed
| .collect(); | ||
|
|
||
| let mut req_tasks = JoinSet::new(); | ||
| // we should change the key in the [core_endpoints] hashmap to be the verification key |
There was a problem hiding this comment.
This segment just seemed to complicate things, since any real checks are carried out in the KMS core, not in the client
There was a problem hiding this comment.
not sure I understand the comment, can you elaborate?
There was a problem hiding this comment.
I mean that the check is actually not needed. That is why it is removed :) The client is checking stuff that the KMS core is also checking
| IMPORTANT: DO NOT CHANGE THE NAME OF THE VERIFICATION KEY! THAT IS, THE KEY FILE MUST KEEP THE NAME WHEN FETCHING IT FROM THE OPERATOR! | ||
| Then execute the following command in root of the KMS project, replacing the seed_phrases with the appropriate ones learned from step 1: | ||
| ```{bash} | ||
| cargo run --bin kms-custodian decrypt --seed-phrase "prosper wool oak moon light situate end palm sick monster clever solid" --randomness 123 --custodian-role 1 --recovery-request-path core-client/tests/data/keys/CUSTODIAN/recovery/1 --operator-verf-key core-client/tests/data/keys/PUB-p1/VerfKey/60b7070add74be3827160aa635fb255eeeeb88586c4debf7ab1134ddceb4beee --mpc-context-id 0x0700000000000000000000000000000000000000000000000000000000000001 --output-path core-client/tests/data/keys/CUSTODIAN/response/recovery-response-1-1 |
There was a problem hiding this comment.
we removed this argument because we now backup every context, or what's the reason?
There was a problem hiding this comment.
The reason is that the mpc-context ID is part of the info it gets from the operators. So there is no need to also supply it at the CLI level since the custodian will already know it.
| | **Custodian `B_j`** (`j = 1..n`) | Human-held, offline party. Owns a long-term signing key `sk^{S_j}` and a post-quantum encryption key `sk^{E_j}`, both deterministically derived from a BIP39 seed phrase. Stores nothing online beyond its public-key half published in the `CustodianSetupMessage`. Re-signcrypts its share of the backup key on request. | | ||
| | **Operator `P_i`** (KMS node) | Online KMS server. Holds a long-term signing key `sk^{P_i}`, a TFHE FHE secret key, and other private material that needs backing up. Receives `NewCustodianContext` and, later, `CustodianRecoveryInit` / `CustodianBackupRecovery` gRPC calls from the core-client. | | ||
| | **core-client** | The CLI that drives every gRPC call into the KMS for custodian-based backup. It bundles the operator-bound RPCs (`NewCustodianContext`, `CustodianRecoveryInit`, `CustodianBackupRecovery`, `RestoreFromBackup`) and shuttles the resulting `RecoveryRequest` / `InternalCustodianRecoveryOutput` files between the operator and the custodians out-of-band. Documented in [docs/guides/core_client.md](core_client.md). | | ||
| | **Recovering operator `P_i'`** | A fresh operator process replacing `P_i` after the latter's private storage was lost. Reads only the public storage and the backup vault; coordinates with custodians (via the core-client) to rebuild private state. | |
|
|
||
| ### Phase 1 — Custodian setup (offline, one-time per custodian) | ||
|
|
||
| Corresponds to [`kms-custodian generate`](#custodian-setup). A future custodian boots the air-gapped machine and runs the command. Keys are deterministically derived from system entropy mixed with a user-supplied `--randomness` string; the matching BIP39 seed phrase is printed to stdout **once** and must be copied onto paper. |
There was a problem hiding this comment.
Keys are deterministically derived from system entropy mixed with a user-supplied
--randomnessstring;
Nit: is it really deterministically derived? I guess we want this step to be as indeterministic as possible, even if it's just a pseudo-random generator.
There was a problem hiding this comment.
Technically it is deterministic given the entropy. But rephrased in 34b6082
|
|
||
| ### Phase 2 — Custodian context creation (online, one-time per context) | ||
|
|
||
| The core-client gathers `n` `CustodianSetupMessage`s (from each custodian's `--path` file), picks a corruption threshold `t < n/2`, and issues a `NewCustodianContext` gRPC call to every operator in the KMS cluster. Each operator, independently: generates a per-context backup keypair `(sk^{B}, pk^{B})`, Shamir-shares `sk^{B}` into `n` shares, builds and signcrypts one `BackupMaterial` per custodian role, computes a commitment over each `BackupMaterial`, packages everything into a signed `RecoveryValidationMaterial` (written to public storage at `request_id = custodian_context_id`), and encrypts the resulting `InternalCustodianContext` into a `BackupCiphertext` for the backup vault. After secret-sharing, the operator drops `sk^{B}` and installs `pk^{B}` in its `SecretSharing` keychain. |
There was a problem hiding this comment.
written to public storage
whose pub storage?
|
|
||
| Corresponds to [`kms-custodian decrypt`](#recovery-decryption-of-backup). The core-client (or operator's human operator) distributes the `RecoveryRequest` and the recovering operator's verification key out-of-band to each custodian's air-gapped machine. The custodian boots, types in the seed phrase, and runs the command: re-derives `(sk^{E_j}, sk^{S_j})` from the seed phrase, unsigncrypts its share of `BackupMaterial` from `cts[j]`, sanity-checks the metadata inside and then re-signcrypts the same `BackupMaterial` to the operator's ephemeral key `pk^{e_i}`, and writes the resulting `InternalCustodianRecoveryOutput` to `--output-path`. | ||
|
|
||
| The custodian's only cryptographic obligation is "decrypt your share and re-signcrypt it for the operator's ephemeral key". The custodian can't (and isn't asked to) judge whether this request is legitimate — see the warning at the top of the [Recovery](#recovery-decryption-of-backup) section. |
There was a problem hiding this comment.
should we mention here (again?) that the request comes from a trusted, out-of-band channel?
|
|
||
| ### Phase 6 — Recovery finalization (operator reconstructs) | ||
|
|
||
| The core-client collects `t + 1` (or more) custodian output files and sends them, in a single `CustodianRecoveryRequest`, to every operator in the cluster. The recovering operator re-reads `RecoveryValidationMaterial` from public storage and validates each `CustodianRecoveryOutput`, and once at least `t + 1` shares pass — Shamir-reconstructs `sk^{B}` and installs it in the `SecretSharing` keychain. A subsequent `RestoreFromBackup` call then iterates every `BackupCiphertext` in the backup vault, decrypts each with `sk^{B}`, and writes the plaintext into the now-empty private storage. |
There was a problem hiding this comment.
The core-client collects
t + 1(or more) custodian output files and sends them, in a singleCustodianRecoveryRequest, to every operator in the cluster.
why every operator? wouldn't we restore only a single operator?
| if iv.len() != 12 { | ||
| return Err(anyhow_error_and_log( | ||
| "Invalid IV length: must be exactly 96 bits for AES GCM", | ||
| )); | ||
| } |
There was a problem hiding this comment.
nit: apparently IVs with other lengths than 96 bit are allowed for GCM in general., but of course we can choose to fix the length in our case.
There was a problem hiding this comment.
As far as I can see from the library it would fail if it does not get a vector of exactly 12 bytes
|
General remark: please try to break down PRs into smaller chunks in the future. The backwd compat changes could have lived in a separate PR and also the IV checks could have been separate. This makes it easier to review. Of course, many changes are in the generated backwd compat files, but still it's easier to navigate PR changes if they are limited to a certain scope. |
There was a problem hiding this comment.
Pull request overview
This PR hardens the custodian-based backup/recovery protocol by moving critical identifiers (notably the MPC context ID) into authenticated signcrypted payloads, removing redundant/unauthenticated fields from proto messages, adding IV/auth-tag validation for AES-GCM-SIV encryption, and extending backward-compatibility coverage with a new v0.14.0 dataset + generator.
Changes:
- Embed
mpc_context_idintoBackupMaterial(authenticated inside signcryptions) and refactor operator/custodian validation around this. - Remove unauthenticated/redundant recovery fields from gRPC protos and update core-client / tests accordingly.
- Add v0.14.0 backward-compat generator + data, bump workspace/backward-compat versions, and add IV/auth-tag length checks + tests.
Reviewed changes
Copilot reviewed 101 out of 111 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| Makefile | Adds v0.14.0 backward-compat generation/cleanup targets. |
| docs/guides/core_client.md | Updates custodian decrypt commands and fixes a typo. |
| docs/guides/backup.md | Expands protocol documentation and updates CLI examples to match new fields. |
| docs/developer/backward_compatibility.md | Documents the new v0.14.0 generator target. |
| core/service/tests/integration_test.rs | Updates integration tests for new recovery request/output shapes. |
| core/service/tests/backward_compatibility_kms.rs | Updates backward-compat tests for new backup/recovery structs. |
| core/service/src/vault/keychain/mod.rs | Adds IV/auth-tag length validation + roundtrip/negative tests. |
| core/service/src/engine/context_manager.rs | Threads mpc_context_id into signcryption generation paths. |
| core/service/src/engine/backup_operator.rs | Refactors recovery request validation and parsing; uses operator-side validation. |
| core/service/src/client/tests/threshold/custodian_backup_tests.rs | Adjusts threshold custodian recovery tests to new API/fields. |
| core/service/src/client/tests/centralized/custodian_backup_tests.rs | Adjusts centralized custodian recovery tests to new API/fields. |
| core/service/src/bin/kms-custodian.rs | Removes CLI parsing/usage of unauthenticated MPC context id and backup id. |
| core/service/src/backup/tests.rs | Updates backup protocol tests; adds negative test for MPC context mismatch. |
| core/service/src/backup/operator.rs | Adds mpc_context_id to BackupMaterial, refactors validation and recovery flow. |
| core/service/src/backup/error.rs | Expands RecoverySkipReason variants to reflect finer-grained validation failures. |
| core/service/src/backup/custodian.rs | Removes redundant fields from custodian outputs; strengthens payload validity checks. |
| core/grpc/proto/kms.v1.proto | Removes unauthenticated recovery fields (backup_id, operator key, MPC context id) from messages. |
| core-client/tests/integration/integration_test.rs | Updates core-client integration tests for new recovery init/recovery flows. |
| core-client/src/s3_operations.rs | Gates testing-only S3 key-fetch helpers behind the testing feature. |
| core-client/src/lib.rs | Updates command handling for new recovery init output semantics. |
| core-client/src/backup.rs | Sends all custodian outputs to all operators; adapts to proto field removals. |
| Cargo.toml | Bumps workspace version to 0.14.0-0 and excludes the new generator crate. |
| Cargo.lock | Updates lockfile versions to 0.14.0-0. |
| backward-compatibility/generate-v0.14.0/src/main.rs | New entrypoint for generating v0.14.0 backward-compat data. |
| backward-compatibility/generate-v0.14.0/src/lib.rs | New generator crate module structure. |
| backward-compatibility/generate-v0.14.0/src/generate.rs | New shared generation utilities for v0.14.0 generator. |
| backward-compatibility/generate-v0.14.0/src/data_0_14.rs | New v0.14.0 dataset generation logic (large). |
| backward-compatibility/generate-v0.14.0/Cargo.toml | New generator crate manifest pinned to v0.14.0 deps. |
| backward-compatibility/generate-v0.13.20/src/data_0_13.rs | Removes custodian-backup-related generation from v0.13.20 generator. |
| backward-compatibility/generate-v0.13.20/Cargo.lock | Updates backward-compatibility crate version reference. |
| backward-compatibility/generate-v0.13.10/Cargo.lock | Updates backward-compatibility crate version reference. |
| backward-compatibility/generate-v0.13.0/Cargo.lock | Updates backward-compatibility crate version reference. |
| backward-compatibility/generate-v0.11.1/Cargo.lock | Updates backward-compatibility crate version reference. |
| backward-compatibility/generate-v0.11.0/Cargo.lock | Updates backward-compatibility crate version reference. |
| backward-compatibility/data/threshold-fhe.ron | Adds v0.14.0 threshold-fhe metadata entries. |
| backward-compatibility/data/kms.ron | Adds v0.14.0 kms metadata entries and adjusts v0.13.20 entries. |
| backward-compatibility/data/kms-grpc.ron | Adds v0.14.0 kms-grpc metadata entries. |
| backward-compatibility/data/0_14_0/threshold-fhe/share_64.bcode | Adds new v0.14.0 threshold-fhe serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/threshold-fhe/share_128.bcode | Adds new v0.14.0 threshold-fhe serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/threshold-fhe/release_pcr_values.bcode | Adds new v0.14.0 threshold-fhe serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/threshold-fhe/prss_setup_rpoly_64.bcode | Adds new v0.14.0 threshold-fhe serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/threshold-fhe/prss_setup_rpoly_128.bcode | Adds new v0.14.0 threshold-fhe serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/threshold-fhe/prss_set_64.bcode | Adds new v0.14.0 threshold-fhe serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/threshold-fhe/prss_set_128.bcode | Adds new v0.14.0 threshold-fhe serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/threshold-fhe/prf_key.bcode | Adds new v0.14.0 threshold-fhe serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/threshold-fhe/auxiliary_prss_set_64/legacy_prss_set_64.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/threshold-fhe/auxiliary_prss_set_128/legacy_prss_set_128.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/unified_signcryption.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/unified_ciphertext.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/threshold_fhe_keys.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/software_version.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/signcryption_key.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/recovery_material.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/public_sig_key.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/prss_setup_combined.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/private_sig_key.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/operator_backup_output.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/node_info.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/kms_fhe_key_handles.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/key_gen_metadata.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/key_gen_metadata_with_extra_data.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/internal_recovery_request.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/internal_custodian_setup_message.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/internal_custodian_recovery_output.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/internal_cus_context.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/hybrid_kem_ct.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/designcryption_key.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/crs_gen_metadata.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/crs_gen_metadata_with_extra_data.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/context_info.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/backup_ciphertext.bcode | Adds new v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_unified_ciphertext/hybrid_kem_ct_handle.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/sns_key.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/private_key_set.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/integer_server_key.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/info.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_threshold_fhe_keys/decompression_key.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_recovery_material/internal_cus_context_handle.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_64.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_prss_setup_combined/prss_setup_128.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/sig_key_handle.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/server_key_handle.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/public_key_handle.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/decompression_key.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_kms_fhe_key_handles/client_key_handle.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_internal_cus_context/unified_enc_key_handle.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_crs_gen_metadata/legacy_crs_gen_metadata.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/auxiliary_backup_ciphertext/unified_ciphertext_handle.bcode | Adds v0.14.0 auxiliary artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms/app_key_blob.bcode | Adds v0.14.0 kms serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms-grpc/signed_pub_data_handle_internal.bcode | Adds v0.14.0 kms-grpc serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms-grpc/pub_data_type.bcode | Adds v0.14.0 kms-grpc serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_14_0/kms-grpc/priv_data_type.bcode | Adds v0.14.0 kms-grpc serialized test artifact (LFS pointer). |
| backward-compatibility/data/0_13_20/kms/recovery_material.bcode | Removes v0.13.20 custodian-backup artifact (LFS pointer). |
| backward-compatibility/data/0_13_20/kms/operator_backup_output.bcode | Removes v0.13.20 custodian-backup artifact (LFS pointer). |
| backward-compatibility/data/0_13_20/kms/kms_fhe_key_handles.bcode | Updates v0.13.20 artifact pointer. |
| backward-compatibility/data/0_13_20/kms/key_gen_metadata_with_extra_data.bcode | Updates v0.13.20 artifact pointer. |
| backward-compatibility/data/0_13_20/kms/internal_recovery_request.bcode | Removes v0.13.20 custodian-backup artifact (LFS pointer). |
| backward-compatibility/data/0_13_20/kms/internal_custodian_setup_message.bcode | Updates v0.13.20 artifact pointer. |
| backward-compatibility/data/0_13_20/kms/internal_custodian_recovery_output.bcode | Removes v0.13.20 custodian-backup artifact (LFS pointer). |
| backward-compatibility/data/0_13_10/kms/kms_fhe_key_handles.bcode | Updates v0.13.10 artifact pointer. |
| backward-compatibility/data/0_13_10/kms/key_gen_metadata.bcode | Updates v0.13.10 artifact pointer. |
| backward-compatibility/data/0_13_10/kms/auxiliary_key_gen_metadata/legacy_key_gen_metadata.bcode | Updates v0.13.10 auxiliary artifact pointer. |
| backward-compatibility/data/0_11_0/kms/threshold_fhe_keys.bcode | Updates v0.11.0 artifact pointer. |
| backward-compatibility/data/0_11_0/kms/auxiliary_threshold_fhe_keys/info.bcode | Updates v0.11.0 auxiliary artifact pointer. |
| backward-compatibility/Cargo.toml | Bumps backward-compatibility crate version to 0.14.0. |
| backward-compatibility/ADDING_NEW_VERSIONS.md | Documents the new v0.14.0 generator in the version matrix. |
| ai-docs/COMMANDS.md | Documents the new make target for v0.14.0 generation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Daniel Demmler <daniel.demmler@zama.ai>
Co-authored-by: Daniel Demmler <daniel.demmler@zama.ai>
|
|
@dd23 I created another PR just taking care of adding the new backwards compatibility tests here. Feel free to review whichever one first, since I changed the merge target of this one to the new backwards tests PR; hence on this PR you will only see the actual changes to the backup, and on the other you will only see the changes actually related to backwards compatibility. |
Description of changes
Note that almost all line additions are from the new backwards compatibility test.
Issue ticket number and link
This closes [https://github.com/zama-ai/kms-internal/issues/3025]
PR Checklist
I attest that all checked items are satisfied. Any deviation is clearly justified above.
chore: ...).TODO(#issue).unwrap/expect/paniconly in tests or for invariant bugs (documented if present).devopslabel + infra notified + infra-team reviewer assigned.!and affected teams notified.Zeroize+ZeroizeOnDropimplemented.unsafe; if unavoidable: minimal, justified, documented, and test/fuzz covered.Dependency Update Questionnaire (only if deps changed or added)
Answer in the
Cargo.tomlnext to the dependency (or here if updating):More details and explanations for the checklist and dependency updates can be found in CONTRIBUTING.md