/* SPDX-License-Identifier: LicenseRef-Starship-1.0 * Copyright (c) 2023-2026 Robert A. James */ /* test_sk_v4_mint.c -- kernel/src/v4/sk_v4_mint.c on the host (#176): Zuse's seed and its read-back * are wiped on every return of the mint, not only on success. The caller owns the 64-byte buffer * (sk_v4_mint_zuse_with); each case fills it with 0xEE, runs the mint to one of its exits, and * checks it is all zero after. The real gpt.c on the harness's RAM disk; the identity code, the key * mint, the signature checks, the marker and the keyboard faked. */ #include "harness.h" #include "fakes.h" #include "starkernel/gpt.h" #include "starkernel/capsule_zuse_boot.h" #include "starkernel/homeblocks_sig.h" #include "starkernel/v4/sk_v4_mint.h" #include "starkernel/v4/sk_v4_marker.h" #include /* ---- the scenario ---- */ static blkio_dev_t stick; static fake_disk disk; static int offer, mint_rc, key_hers, marker_present, marker_rc; static const char *typed; static unsigned typed_at; static sk_v4_marker_t marker, written; /* ---- the fakes the mint calls ---- */ int sk_v4_identity_offer_wait(blkio_dev_t **raw, uint64_t *bytes) { *raw = &stick; *bytes = (uint64_t)disk.blocks * 1024u; return offer; } int sk_v4_identity_stick_in(void) { return 1; } int sk_v4_identity_offered_present(void) { return 1; } void sk_v4_identity_release_offered(void) { } void sk_v4_identity_recheck_offered(void) { } void sk_v4_identity_beat(void) { } const sk_v4_marker_t *sk_v4_identity_marker(void) { marker.present = marker_present; return ▮ } void sk_v4_identity_set_marker(const sk_v4_marker_t *m) { marker = *m; } int sk_v4_marker_write(const sk_v4_marker_t *m) { written = *m; return marker_rc; } int sk_input_getc(void) { return (typed && typed[typed_at]) ? (unsigned char)typed[typed_at++] : -1; } void arch_halt(void) { } int capsule_zuse_boot_genesis_mint(struct blkio_dev *dev, uint8_t seed[32], uint8_t pubkey[32]) { (void)dev; memset(seed, 0x5A, 32); memset(pubkey, 0x11, 32); /* the seed is in the buffer even when it then fails */ return mint_rc; } homeblocks_sig_result_t homeblocks_sig_check(struct blkio_dev *dev, uint32_t start_fblock, homeblocks_sig_t *out) { (void)dev; (void)start_fblock; memset(out, 0, sizeof *out); return (homeblocks_sig_result_t)0; } zuse_drive_t capsule_zuse_boot_check_key(struct blkio_dev *dev, homeblocks_sig_result_t sig_rc, const homeblocks_sig_t *sig, const uint8_t want[32], uint8_t seed[32], uint8_t pubkey[32]) { (void)dev; (void)sig_rc; (void)sig; (void)want; memset(seed, 0x5A, 32); memset(pubkey, 0x11, 32); /* read back, as minted */ return key_hers ? ZUSE_DRIVE_HERS : (zuse_drive_t)(ZUSE_DRIVE_HERS + 1); } static int all_zero(const uint8_t *p, unsigned n) { unsigned i; for (i = 0; i < n; i++) if (p[i]) return 0; return 1; } /* run the mint once: the scenario, then the buffer must be zero */ static void run(const char *what, int offer_, uint32_t blocks, const char *typed_, int mint_rc_, int hers, int present, int mrc, int want_rc) { uint8_t seeds[64]; int rc; fake_disk_open(&stick, &disk, blocks); offer = offer_; typed = typed_; typed_at = 0; mint_rc = mint_rc_; key_hers = hers; marker_present = present; marker_rc = mrc; memset(&marker, 0, sizeof marker); memset(seeds, 0xEE, sizeof seeds); fake_console_reset(); rc = sk_v4_mint_zuse_with(seeds); CHECK(rc == want_rc, "%s: returns %d (got %d)", what, want_rc, rc); CHECK(all_zero(seeds, 64), "#176: %s -- the seed buffer is zero after", what); fake_disk_free(&disk); } int main(void) { const uint32_t BIG = 70000u, SMALL = 1000u; /* 1 KiB blocks: 68 MiB, and under the 64 MiB the mint wants */ fake_rng_reset(); run("no stick offered", 0, BIG, "YES\r", 0, 1, 1, 0, -1); run("a stick under 64 MiB", 1, SMALL, "YES\r", 0, 1, 1, 0, -1); run("not YES", 1, BIG, "no\r", 0, 1, 1, 0, -1); run("the key mint fails", 1, BIG, "YES\r", -1, 1, 1, 0, -1); run("the read-back is not hers", 1, BIG, "YES\r", 0, 0, 1, 0, -1); run("no marker on the system stick", 1, BIG, "YES\r", 0, 1, 0, 0, -1); run("the marker write fails", 1, BIG, "YES\r", 0, 1, 1, -1, -1); run("minted", 1, BIG, "YES\r", 0, 1, 1, 0, 0); CHECK(written.has_real == 1 && written.real[0] == 0x11, "minted: the marker names the real Zuse's key"); return DONE(); }