fix(v4): MINT-ZUSE wipes Zuse's seed on every return, not only on success (#176, the mint)

sk_v4_mint_zuse wiped seed and rseed only when the real Zuse was minted; its
refusals and every failure after YES left them in stack memory.

Option 1 (Captain Bob, 2026-11-12: "1 is great"): the seeds are in a 64-byte
buffer the caller owns. sk_v4_mint_zuse_with(seeds) runs the mint (now a
private mint()) and then wipes the buffer, whichever way it returned -- one
place, every exit; sk_v4_mint_zuse() gives it a buffer of its own.

kernel/tests/test_sk_v4_mint.c, 17 checks: the real gpt.c on the RAM disk, the
identity code, key mint, signature checks, marker and keyboard faked; each of
the mint's eight exits run with the buffer filled with 0xEE first -- no stick,
under 64 MiB, not YES, the key mint failing, the read-back not hers, no
marker, the marker write failing, and minted. Against the mint as it was: 7
failures (every exit but success). Now: 0. Both runs in logs/20261112-181719/. Built for
amd64, aarch64, riscv64. The identity code's two (sk_v4_genesis,
sk_v4_real_zuse_arrived) follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RzZgrf7V7Zk2iczBXDRbm
This commit is contained in:
Claude
2026-11-12 18:17:19 +00:00
parent 3c053f02a6
commit 2bac2ac8fc
5 changed files with 123 additions and 6 deletions
+23 -4
View File
@@ -81,7 +81,10 @@ static int erased(void) /* its old partition table is gone (#168
return -1;
}
int sk_v4_mint_zuse(void)
/* The mint, with Zuse's seed and its read-back in `seeds`, which the caller owns: seed is its first
* 32 bytes, rseed the next 32. Called only by sk_v4_mint_zuse_with, which wipes `seeds` after it
* whichever way it returned (#176). */
static int mint(uint8_t seeds[64])
{
static blkio_dev_t part;
static gpt_part_dev_t part_state;
@@ -89,7 +92,8 @@ int sk_v4_mint_zuse(void)
static uint8_t zero[BLKIO_FORTH_BLOCK_SIZE];
blkio_dev_t *raw;
uint64_t bytes, sectors;
uint8_t guid[16], seed[32], pub[32], rseed[32], rpub[32];
uint8_t guid[16], pub[32], rpub[32];
uint8_t *seed = seeds, *rseed = seeds + 32;
homeblocks_sig_t sig;
homeblocks_sig_result_t sig_rc;
sk_v4_marker_t m;
@@ -148,10 +152,25 @@ int sk_v4_mint_zuse(void)
m.has_real = 1;
if (sk_v4_marker_write(&m) != 0) return erased();
sk_v4_identity_set_marker(&m);
memset(seed, 0, sizeof seed);
memset(rseed, 0, sizeof rseed);
memset(seeds, 0, 64);
console_println("Zuse: real Zuse minted onto the second stick");
sk_v4_identity_recheck_offered();
return 0;
}
/* One place wipes the seeds, after every return of the mint -- its refusals, each failure after
* YES, and success alike. They were wiped on success only, and left in memory on every other way
* out (#176). */
int sk_v4_mint_zuse_with(uint8_t seeds[64])
{
int rc = mint(seeds);
memset(seeds, 0, 64);
return rc;
}
int sk_v4_mint_zuse(void)
{
static uint8_t seeds[64];
return sk_v4_mint_zuse_with(seeds);
}