nx_x509_verify_ecdsa_p384.nx source
↩ module page · 89 lines · 3508 B
1// nx_x509_verify_ecdsa_p384.nx -- X.509 outer-signature verification
2// for ECDSA-P384-with-SHA-384 signed certs.
3//
4// Parallel to nx_x509_verify_ecdsa.nx (commit 6bd3fdf3 family) but
5// targets the P-384 / SHA-384 combination used by many Web PKI
6// intermediates (e.g. DigiCert Global Root G3, Sectigo P384).
7//
8// Composes:
9// - sha384_digest (48-byte SHA-384 hash of tbs)
10// - nx_ecdsa_sig_parse_der_384 (DER SEQUENCE -> r, s U384)
11// - nx_ecdsa_p384_verify (verify under issuer's pubkey)
12//
13// Public API:
14// nx_x509_verify_ecdsa_p384(tbs, tbs_len, sig_der, sig_len,
15// pub_x, pub_y) -> verdict
16//
17// Sealed verdict enum mirrors nx_x509_verify_ecdsa's; same shape so
18// the caller's switch-case stays uniform.
19//
20// Per Cardinals 9 (single-responsibility), 22 (composition),
21// 23 (preamble names what caller MUST verify separately).
22//
23// license_tier: INDEPENDENT_REDERIVE
24// genealogy_id: international-research-sources/ietf/rfc_5280 + rfc_5480 + nist_fips_186_5
25// lineage_id: nishi_x509_verify_ecdsa_p384_q10
26
27// nx_safety_envelope:
28// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
29// sil_target: SIL1
30// evidence: [bulk_applied_2026-05-20, x509-outer-sig-ecdsa-p384-orchestrator]
31// verdict: NOT_YET_EVALUATED
32
33import "nx_syscalls.nx"
34import "nx_u384.nx"
35import "nx_sha512.nx"
36import "nx_ecdsa_sig_der.nx"
37import "nx_ecdsa_sig_der_384.nx"
38import "nx_ecdsa_p384.nx"
39
40const NX_X509_ECDSA_P384_OK: i64 = 1
41const NX_X509_ECDSA_P384_BAD_SIG_DER: i64 = 2
42const NX_X509_ECDSA_P384_BAD_SIG: i64 = 3
43const NX_X509_ECDSA_P384_BAD_PUBKEY: i64 = 4
44const NX_X509_ECDSA_P384_INFINITY: i64 = 5
45const NX_X509_ECDSA_P384_VERDICT_N: i64 = 6
46
47func nx_x509_verify_ecdsa_p384_verdict_is_valid(v: i64) -> i64 {
48 if v < NX_X509_ECDSA_P384_OK { return 0 }
49 if v >= NX_X509_ECDSA_P384_VERDICT_N { return 0 }
50 return 1
51}
52
53// Verify an X.509 outer signature for an ECDSA-P384-with-SHA-384
54// signed cert.
55//
56// Returns NX_X509_ECDSA_P384_OK on valid signature, or a non-OK
57// verdict.
58func nx_x509_verify_ecdsa_p384(tbs: *u8, tbs_len: i64,
59 sig_der: *u8, sig_len: i64,
60 pub_x: *i64, pub_y: *i64) -> i64 {
61 // ---- Hash tbs with SHA-384 ----
62 let hash_bytes: *u8 = sys_mmap(48)
63 sha384_digest(tbs, tbs_len, hash_bytes)
64
65 let e: *i64 = u384_alloc()
66 u384_load_be(e, hash_bytes)
67
68 // ---- Parse DER signature into r, s (12-limb U384 each) ----
69 let r: *i64 = u384_alloc()
70 let s: *i64 = u384_alloc()
71 let parse: i64 = nx_ecdsa_sig_parse_der_384(sig_der, sig_len, r, s)
72 if parse != NX_ECDSA_DER_OK {
73 sys_munmap(hash_bytes, 48); u384_free(e); u384_free(r); u384_free(s) // S-CLASS certloop leak fix
74 return NX_X509_ECDSA_P384_BAD_SIG_DER
75 }
76
77 // ---- Call ECDSA-P384 verify ----
78 let v: i64 = nx_ecdsa_p384_verify(pub_x, pub_y, e, r, s)
79 sys_munmap(hash_bytes, 48); u384_free(e); u384_free(r); u384_free(s) // S-CLASS certloop leak fix: free per-verify scratch
80 if v == NX_ECDSA_P384_OK { return NX_X509_ECDSA_P384_OK }
81 if v == NX_ECDSA_P384_PUBKEY_NOT_ON_CURVE { return NX_X509_ECDSA_P384_BAD_PUBKEY }
82 if v == NX_ECDSA_P384_PUBKEY_INFINITY { return NX_X509_ECDSA_P384_BAD_PUBKEY }
83 if v == NX_ECDSA_P384_INFINITY_RESULT { return NX_X509_ECDSA_P384_INFINITY }
84 return NX_X509_ECDSA_P384_BAD_SIG
85}
86
87func main() -> i64 {
88 return 0
89}