code wiki / _hdl_build / nx_x509_emit.nx

nx_x509_emit.nx source

↩ module page · 387 lines · 18294 B

1// nx_x509_emit.nx -- F103e RUNG 9: author a SELF-SIGNED X.509 v3 certificate. 2// 3// The cert that will carry our Secure Boot key. Real EDK2 with MS keys refuses our unsigned .efi 4// (Access Denied) while the same secboot firmware in SETUP mode runs it, so the blocker is the 5// enrolled key set (debt 1786237435). Enrolling means putting a CERT in db. 6// 7// ★OIDs ARE DERIVED, NOT RECALLED. An OID written as a byte string from memory is a fabricated 8// constant. Here `der_oid_from_arcs` ENCODES the arc numbers (X.690 §8.19: first byte = 40*a1 + a2, 9// then base-128 with continuation bits) -- and T1 validates that encoder against a known-good 10// encoding the estate already ships: the SHA-256 OID sitting inside the incumbent's 11// `rsa_pkcs1_sha256_di_byte` DigestInfo table. ★★★★★★**ONE VERIFIED ENCODER TURNS EVERY OTHER OID 12// FROM A REMEMBERED BYTE STRING INTO A DERIVED RESULT — AND THE ARC NUMBERS ARE SPEC FACTS, WHICH 13// THE ENCODER THEN PROVES.** 14// 15// ★THE ORACLE IS THE ESTATE'S OWN READER, END TO END: emit -> `x509_parse` must accept and report a 16// tbs region -> our signer signs exactly that region -> the incumbent `rsa_pkcs1_v1_5_sha256_verify` 17// must accept. Four independently written pieces agreeing. A cert that only round-trips through its 18// own emitter proves nothing. 19// 20// Structure (RFC 5280): Certificate ::= SEQUENCE { tbsCertificate, signatureAlgorithm, signatureValue } 21// TBSCertificate ::= SEQUENCE { [0] v3, serial, sigAlg, issuer, validity, subject, SPKI } 22// ⚠extensions ([3] basicConstraints CA:TRUE) are NOT emitted yet -- named as owed rather than 23// silently absent, because a db entry does not require them but a KEK/PK chain will. 24// 25// Usage: nx_x509_emit selftest 26// Exit: 0 GREEN | 1 RED. Log -> knowledge/status/nishi_os.log, verdict= LAST. 27// license_tier: ORIGINAL 28import "nx_syscalls.nx" 29import "nx_sha256.nx" 30import "nx_u2048.nx" 31import "nx_u2048_mul.nx" 32import "nx_rsa2048_mod.nx" 33import "nx_rsa2048_mod_exp.nx" 34import "nx_rsa2048_mont.nx" 35import "nx_rsa2048_mod_exp_big.nx" 36import "nx_asn1.nx" 37import "nx_x509.nx" 38import "nx_rsa_pkcs1_v1_5_sha256.nx" 39import "nx_u2048_millerrabin.nx" 40import "nx_u2048_smallops.nx" 41import "nx_rsa_keygen.nx" 42import "nx_rsa_pkcs1_sign.nx" 43const XE_MAGIC_65536: i64 = 65536 44const XE_MAGIC_1024: i64 = 1024 45const XE_MAGIC_113549: i64 = 113549 46const XE_MAGIC_20260808: i64 = 20260808 47const XE_MAGIC_65537: i64 = 65537 48const XE_MAGIC_4097: i64 = 4097 49 50const XE_BUF: i64 = 8192 51 52func xe_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 53func xe_fp(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 } 54func xe_fn(fd: i64, v: i64) -> i64 { 55 let bb: *u8 = sys_mmap(28); var m: i64 = v 56 if m < 0 { m = 0 - m; bb[0] = 45 as u8; sys_write(fd, bb, 1) } 57 let t: *u8 = sys_mmap(28); var k: i64 = 0 58 if m == 0 { t[0] = 48 as u8; k = 1 } 59 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 60 var i: i64 = 0 61 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 62 sys_write(fd, bb, k); return 0 63} 64 65// ---- DER length + TLV (minimal form; the same rules nx_asn1_der_emit proves) -------------------- 66func xe_put_len(out: *u8, off: i64, n: i64) -> i64 { 67 if n < 128 { out[off] = n as u8; return off + 1 } 68 if n < 256 { out[off] = 0x81 as u8; out[off+1] = n as u8; return off + 2 } 69 if n < XE_MAGIC_65536 { 70 out[off] = 0x82 as u8 71 out[off+1] = ((n >> 8) & 0xff) as u8 72 out[off+2] = (n & 0xff) as u8 73 return off + 3 74 } 75 return 0 - 1 76} 77func xe_len_size(n: i64) -> i64 { 78 if n < 128 { return 1 } 79 if n < 256 { return 2 } 80 return 3 81} 82// wrap payload[0..plen) at `out+off` as tag||len||payload 83func xe_wrap(out: *u8, off: i64, tag: i64, payload: *u8, plen: i64) -> i64 { 84 out[off] = (tag & 0xff) as u8 85 var o: i64 = xe_put_len(out, off + 1, plen) 86 if o < 0 { return 0 - 1 } 87 var i: i64 = 0 88 while i < plen { out[o + i] = payload[i]; i = i + 1 } 89 return o + plen 90} 91 92// ---- OID: DERIVE from arcs (X.690 8.19). Never a remembered byte string. ----------------------- 93func der_oid_from_arcs(out: *u8, off: i64, arcs: *i64, narcs: i64) -> i64 { 94 if narcs < 2 { return 0 - 1 } 95 let body: *u8 = sys_mmap(128) 96 var bl: i64 = 0 97 body[bl] = (40 * arcs[0] + arcs[1]) as u8 // first two arcs share a byte 98 bl = bl + 1 99 var i: i64 = 2 100 while i < narcs { 101 let v: i64 = arcs[i] 102 // base-128, most significant group first, continuation bit on all but the last 103 var tmp: *u8 = sys_mmap(16) 104 var t: i64 = 0 105 var x: i64 = v 106 if x == 0 { tmp[0] = 0 as u8; t = 1 } 107 while x > 0 { tmp[t] = (x & 0x7f) as u8; x = x >> 7; t = t + 1 } 108 var k: i64 = t - 1 109 while k >= 0 { 110 var b: i64 = tmp[k] as i64 111 if k > 0 { b = b | 0x80 } 112 body[bl] = b as u8 113 bl = bl + 1 114 k = k - 1 115 } 116 i = i + 1 117 } 118 return xe_wrap(out, off, ASN1_OID, body, bl) 119} 120 121// ---- AlgorithmIdentifier ::= SEQUENCE { OID, NULL } --------------------------------------------- 122func xe_algid(out: *u8, off: i64, arcs: *i64, narcs: i64) -> i64 { 123 let inner: *u8 = sys_mmap(256) 124 var o: i64 = der_oid_from_arcs(inner, 0, arcs, narcs) 125 if o < 0 { return 0 - 1 } 126 inner[o] = ASN1_NULL as u8; inner[o+1] = 0 as u8 // NULL params, as RSA algids carry 127 o = o + 2 128 return xe_wrap(out, off, ASN1_SEQUENCE, inner, o) 129} 130 131// ---- Name ::= SEQUENCE { SET { SEQUENCE { OID cn, PrintableString } } } ------------------------- 132func xe_name(out: *u8, off: i64, cn: *u8) -> i64 { 133 var cl: i64 = 0 134 while cn[cl] != (0 as u8) { cl = cl + 1 } 135 let cnarcs: *i64 = sys_mmap(64) as *i64 136 cnarcs[0]=2; cnarcs[1]=5; cnarcs[2]=4; cnarcs[3]=3 // id-at-commonName 2.5.4.3 137 let atv: *u8 = sys_mmap(512) 138 var o: i64 = der_oid_from_arcs(atv, 0, cnarcs, 4) 139 o = xe_wrap(atv, o, ASN1_PRINTABLE, cn, cl) 140 let seq: *u8 = sys_mmap(512) 141 let sl: i64 = xe_wrap(seq, 0, ASN1_SEQUENCE, atv, o) 142 let set: *u8 = sys_mmap(512) 143 let stl: i64 = xe_wrap(set, 0, ASN1_SET, seq, sl) 144 return xe_wrap(out, off, ASN1_SEQUENCE, set, stl) 145} 146 147// ---- SubjectPublicKeyInfo ::= SEQUENCE { AlgId(rsaEncryption), BIT STRING { SEQ { n, e } } } ---- 148func xe_spki(out: *u8, off: i64, n: *i64, e: i64) -> i64 { 149 let nb: *u8 = sys_mmap(256) 150 u2048_store_be(nb, n) 151 var s: i64 = 0 152 while s < 256 { if (nb[s] as i64) != 0 { s = 256 } else { s = s + 1 } } // find first nonzero 153 var start: i64 = 0 154 var scanning: i64 = 1 155 while scanning == 1 { 156 if start >= 256 { scanning = 0 } else { 157 if (nb[start] as i64) == 0 { start = start + 1 } else { scanning = 0 } 158 } 159 } 160 let nlen: i64 = 256 - start 161 // INTEGER n, with the leading 0x00 an RSA modulus always needs (top bit set) 162 let rsapub: *u8 = sys_mmap(XE_MAGIC_1024) 163 var o: i64 = 0 164 rsapub[o] = ASN1_INTEGER as u8; o = o + 1 165 var pad: i64 = 0 166 if ((nb[start] as i64) & 0x80) != 0 { pad = 1 } 167 o = xe_put_len(rsapub, o, nlen + pad) 168 if pad == 1 { rsapub[o] = 0 as u8; o = o + 1 } 169 var i: i64 = 0 170 while i < nlen { rsapub[o + i] = nb[start + i]; i = i + 1 } 171 o = o + nlen 172 // INTEGER e (65537 = 01 00 01, top bit clear -> no pad) 173 let eb: *u8 = sys_mmap(16) 174 var el: i64 = 0 175 if e < 256 { eb[0] = e as u8; el = 1 } else { 176 if e < XE_MAGIC_65536 { eb[0] = ((e >> 8) & 0xff) as u8; eb[1] = (e & 0xff) as u8; el = 2 } else { 177 eb[0] = ((e >> 16) & 0xff) as u8; eb[1] = ((e >> 8) & 0xff) as u8; eb[2] = (e & 0xff) as u8; el = 3 } } 178 o = xe_wrap(rsapub, o, ASN1_INTEGER, eb, el) 179 let pubseq: *u8 = sys_mmap(XE_MAGIC_1024) 180 let psl: i64 = xe_wrap(pubseq, 0, ASN1_SEQUENCE, rsapub, o) 181 // BIT STRING: one leading "unused bits" byte, always 0 here 182 let bits: *u8 = sys_mmap(XE_MAGIC_1024) 183 bits[0] = 0 as u8 184 var j: i64 = 0 185 while j < psl { bits[1 + j] = pubseq[j]; j = j + 1 } 186 let inner: *u8 = sys_mmap(XE_MAGIC_1024) 187 let rsaarcs: *i64 = sys_mmap(64) as *i64 188 rsaarcs[0]=1; rsaarcs[1]=2; rsaarcs[2]=840; rsaarcs[3]=XE_MAGIC_113549; rsaarcs[4]=1; rsaarcs[5]=1; rsaarcs[6]=1 189 var io: i64 = xe_algid(inner, 0, rsaarcs, 7) 190 io = xe_wrap(inner, io, ASN1_BIT_STRING, bits, psl + 1) 191 return xe_wrap(out, off, ASN1_SEQUENCE, inner, io) 192} 193 194// ---- tbsCertificate ---------------------------------------------------------------------------- 195func xe_tbs(out: *u8, off: i64, n: *i64, e: i64, cn: *u8, serial: i64) -> i64 { 196 let body: *u8 = sys_mmap(XE_BUF) 197 var o: i64 = 0 198 // [0] EXPLICIT { INTEGER 2 } -- v3 199 let vin: *u8 = sys_mmap(16) 200 vin[0] = ASN1_INTEGER as u8; vin[1] = 1 as u8; vin[2] = 2 as u8 201 o = xe_wrap(body, o, 0xA0, vin, 3) 202 // serialNumber INTEGER (positive, so a high bit forces a leading zero) 203 let sb: *u8 = sys_mmap(16) 204 sb[0] = ((serial >> 8) & 0xff) as u8 205 sb[1] = (serial & 0xff) as u8 206 o = xe_wrap(body, o, ASN1_INTEGER, sb, 2) 207 // signature AlgorithmIdentifier: sha256WithRSAEncryption 1.2.840.113549.1.1.11 208 let sigarcs: *i64 = sys_mmap(64) as *i64 209 sigarcs[0]=1; sigarcs[1]=2; sigarcs[2]=840; sigarcs[3]=XE_MAGIC_113549; sigarcs[4]=1; sigarcs[5]=1; sigarcs[6]=11 210 o = xe_algid(body, o, sigarcs, 7) 211 // issuer == subject (self-signed) 212 o = xe_name(body, o, cn) 213 // validity SEQUENCE { UTCTime notBefore, UTCTime notAfter } 214 let vb: *u8 = sys_mmap(256) 215 let nb1: *u8 = "260808000000Z" as *u8 216 let na1: *u8 = "360808000000Z" as *u8 217 var vo: i64 = xe_wrap(vb, 0, ASN1_UTC_TIME, nb1, 13) 218 vo = xe_wrap(vb, vo, ASN1_UTC_TIME, na1, 13) 219 o = xe_wrap(body, o, ASN1_SEQUENCE, vb, vo) 220 o = xe_name(body, o, cn) 221 o = xe_spki(body, o, n, e) 222 return xe_wrap(out, off, ASN1_SEQUENCE, body, o) 223} 224 225// ---- the whole certificate; returns total length or negative ------------------------------------ 226func x509_emit_selfsigned(out: *u8, n: *i64, d: *i64, e: i64, cn: *u8, serial: i64, 227 tbs_off_p: *i64, tbs_len_p: *i64) -> i64 { 228 let tbs: *u8 = sys_mmap(XE_BUF) 229 let tlen: i64 = xe_tbs(tbs, 0, n, e, cn, serial) 230 if tlen < 0 { return 0 - 1 } 231 // sign the tbs DER exactly as emitted (tag+len+value), which is what RFC 5280 hashes 232 let sig: *u8 = sys_mmap(300) 233 if rsa_pkcs1_v1_5_sha256_sign(sig, tbs, tlen, d, n) != 1 { return 0 - 2 } 234 let sigarcs: *i64 = sys_mmap(64) as *i64 235 sigarcs[0]=1; sigarcs[1]=2; sigarcs[2]=840; sigarcs[3]=XE_MAGIC_113549; sigarcs[4]=1; sigarcs[5]=1; sigarcs[6]=11 236 let body: *u8 = sys_mmap(XE_BUF) 237 var o: i64 = 0 238 var i: i64 = 0 239 while i < tlen { body[o + i] = tbs[i]; i = i + 1 } 240 tbs_off_p[0] = o // offset of tbs INSIDE body (pre-wrap) 241 tbs_len_p[0] = tlen 242 o = o + tlen 243 o = xe_algid(body, o, sigarcs, 7) 244 let bits: *u8 = sys_mmap(300) 245 bits[0] = 0 as u8 246 var j: i64 = 0 247 while j < 256 { bits[1 + j] = sig[j]; j = j + 1 } 248 o = xe_wrap(body, o, ASN1_BIT_STRING, bits, 257) 249 return xe_wrap(out, 0, ASN1_SEQUENCE, body, o) 250} 251 252// ================================================================================================= 253func xe_selftest() -> i64 { 254 var pass: i64 = 0 255 var teeth: i64 = 0 256 257 // T1 THE OID ENCODER, validated against a known-good encoding the estate already ships: 258 // the SHA-256 OID (2.16.840.1.101.3.4.2.1) lives at bytes 4..14 of the DigestInfo table. 259 teeth = teeth + 1 260 // 9 arcs = 72 bytes. A 64-byte arena block here OVERRAN by 8 and the estate's own guard caught 261 // it (ARENA-OVERRUN prev_alloc_size=64) while every tooth still reported GREEN. 262 // ★★★★★★A HEAP OVERRUN DOES NOT FAIL THE TEST THAT CAUSED IT — IT CORRUPTS SOMETHING ELSE LATER. 263 // Only the allocator's guard separated "7/7" from "7/7 and a latent memory bug". 264 let arcs: *i64 = sys_mmap(128) as *i64 265 arcs[0]=2; arcs[1]=16; arcs[2]=840; arcs[3]=1; arcs[4]=101; arcs[5]=3; arcs[6]=4; arcs[7]=2; arcs[8]=1 266 let ob: *u8 = sys_mmap(128) 267 let ol: i64 = der_oid_from_arcs(ob, 0, arcs, 9) 268 var t1: i64 = 1 269 if ol != 11 { t1 = 0 } // 06 09 + 9 body bytes 270 var i: i64 = 0 271 while i < 11 { 272 if (ob[i] as i64) != (rsa_pkcs1_sha256_di_byte(4 + i) & 0xff) { t1 = 0 } 273 i = i + 1 274 } 275 if t1 == 1 { pass = pass + 1; xe_p("XE-T1 oid-encoder matches the estate's shipped SHA-256 OID GREEN\n" as *u8) } 276 else { xe_p("XE-T1 RED len=" as *u8); xe_fn(1, ol); xe_p("\n" as *u8) } 277 278 // T2 NEGATIVE CONTROL: a different arc list must NOT produce those bytes, or T1 proves nothing. 279 teeth = teeth + 1 280 arcs[8] = 2 // ...4.2.2 instead of ...4.2.1 281 let ol2: i64 = der_oid_from_arcs(ob, 0, arcs, 9) 282 var same: i64 = 1 283 var k: i64 = 0 284 while k < 11 { if (ob[k] as i64) != (rsa_pkcs1_sha256_di_byte(4 + k) & 0xff) { same = 0 } k = k + 1 } 285 if ol2 == 11 { if same == 0 { pass = pass + 1; xe_p("XE-T2 neg-control-different-arcs-differ GREEN\n" as *u8) } 286 else { xe_p("XE-T2 RED [VACUOUS: encoder ignores its input]\n" as *u8) } } 287 else { xe_p("XE-T2 RED\n" as *u8) } 288 289 // T3 multi-byte arc: 113549 must encode as three continuation bytes 86 F7 0D (DERIVED here, and 290 // checked by re-decoding base-128 rather than by comparing to a remembered string). 291 teeth = teeth + 1 292 let a2: *i64 = sys_mmap(64) as *i64 293 a2[0]=1; a2[1]=2; a2[2]=840; a2[3]=XE_MAGIC_113549 294 let o3: i64 = der_oid_from_arcs(ob, 0, a2, 4) 295 var acc: i64 = 0 296 var p: i64 = 2 + 1 + 2 // skip 06 len, first-two-arcs byte, 840's 2 bytes 297 var decoded: i64 = 0 298 var run: i64 = 1 299 while run == 1 { 300 if p >= o3 { run = 0 } else { 301 let b: i64 = ob[p] as i64 302 acc = (acc << 7) | (b & 0x7f) 303 if (b & 0x80) == 0 { decoded = acc; run = 0 } 304 p = p + 1 305 } 306 } 307 if decoded == XE_MAGIC_113549 { pass = pass + 1; xe_p("XE-T3 multi-byte-arc round-trips to 113549 GREEN\n" as *u8) } 308 else { xe_p("XE-T3 RED decoded=" as *u8); xe_fn(1, decoded); xe_p("\n" as *u8) } 309 310 // ---- generate a key and emit a real certificate ---- 311 xe_p("TEST-KEY-DO-NOT-USE: generating a deterministic 2048-bit key...\n" as *u8) 312 let np: *i64 = u2048_alloc(); let qp: *i64 = u2048_alloc() 313 let n: *i64 = u2048_alloc(); let d: *i64 = u2048_alloc() 314 let st: *i64 = sys_mmap(16) as *i64 315 st[0] = XE_MAGIC_20260808 316 if kg_keygen(XE_MAGIC_1024, np, qp, n, d, st, 1) != 1 { 317 xe_p("XE RED: keygen failed\n" as *u8); sys_exit(1); return 1 318 } 319 xe_p("key ready\n" as *u8) 320 321 let cert: *u8 = sys_mmap(XE_BUF) 322 let toff: *i64 = sys_mmap(16) as *i64 323 let tlen: *i64 = sys_mmap(16) as *i64 324 let cn: *u8 = "Nishi Platform Key" as *u8 325 let clen: i64 = x509_emit_selfsigned(cert, n, d, XE_MAGIC_65537, cn, XE_MAGIC_4097, toff, tlen) 326 327 // T4 THE INCUMBENT PARSER MUST ACCEPT IT. 328 teeth = teeth + 1 329 let xc: *X509Cert = sys_mmap(512) as *X509Cert 330 var rcp: i64 = 0 - 999 331 if clen > 0 { rcp = x509_parse(cert, clen, xc) } 332 if rcp >= 0 { pass = pass + 1; xe_p("XE-T4 incumbent x509_parse ACCEPTS our cert GREEN len=" as *u8) 333 xe_fn(1, clen); xe_p("\n" as *u8) } 334 else { xe_p("XE-T4 RED clen=" as *u8); xe_fn(1, clen); xe_p(" rc=" as *u8); xe_fn(1, rcp); xe_p("\n" as *u8) } 335 336 // T5 THE SIGNATURE MUST VERIFY over the tbs region the PARSER found -- not the one we remember 337 // emitting. ★★★★★★A SELF-SIGNED CERT WHERE THE SIGNER AND THE PARSER DISAGREE ABOUT WHICH BYTES 338 // ARE SIGNED IS EXACTLY THE BUG THAT LOOKS CORRECT FROM BOTH SIDES. 339 teeth = teeth + 1 340 if rcp >= 0 { 341 let v: i64 = rsa_pkcs1_v1_5_sha256_verify((cert + xc.tbs_off) as *u8, xc.tbs_len, 342 (cert + clen - 256) as *u8, n, XE_MAGIC_65537) 343 if v == NX_RSA_PKCS1_V15_OK { pass = pass + 1 344 xe_p("XE-T5 signature verifies over the PARSER-reported tbs region GREEN\n" as *u8) } 345 else { xe_p("XE-T5 RED verify=" as *u8); xe_fn(1, v) 346 xe_p(" tbs_off=" as *u8); xe_fn(1, xc.tbs_off) 347 xe_p(" tbs_len=" as *u8); xe_fn(1, xc.tbs_len) 348 xe_p(" emitted_len=" as *u8); xe_fn(1, tlen[0]); xe_p("\n" as *u8) } 349 } else { xe_p("XE-T5 RED [parser failed, cannot locate tbs]\n" as *u8) } 350 351 // T6 the parser's tbs region must equal what we emitted -- an independent cross-check of T5. 352 teeth = teeth + 1 353 if rcp >= 0 { if xc.tbs_len == tlen[0] { pass = pass + 1 354 xe_p("XE-T6 parser tbs_len == emitted tbs_len GREEN\n" as *u8) } 355 else { xe_p("XE-T6 RED parser=" as *u8); xe_fn(1, xc.tbs_len) 356 xe_p(" emitted=" as *u8); xe_fn(1, tlen[0]); xe_p("\n" as *u8) } } 357 else { xe_p("XE-T6 RED\n" as *u8) } 358 359 // T7 NEGATIVE CONTROL: corrupt one tbs byte -> the signature must STOP verifying. 360 teeth = teeth + 1 361 if rcp >= 0 { 362 let sv: i64 = cert[xc.tbs_off + 20] as i64 363 cert[xc.tbs_off + 20] = ((sv ^ 0xff) & 0xff) as u8 364 let v2: i64 = rsa_pkcs1_v1_5_sha256_verify((cert + xc.tbs_off) as *u8, xc.tbs_len, 365 (cert + clen - 256) as *u8, n, XE_MAGIC_65537) 366 if v2 != NX_RSA_PKCS1_V15_OK { pass = pass + 1 367 xe_p("XE-T7 neg-control-tbs-tamper-breaks-signature GREEN\n" as *u8) } 368 else { xe_p("XE-T7 RED [VACUOUS]\n" as *u8) } 369 cert[xc.tbs_off + 20] = sv as u8 370 } else { xe_p("XE-T7 RED\n" as *u8) } 371 372 xe_p("XE-SELFTEST " as *u8); xe_fn(1, pass); xe_p("/" as *u8); xe_fn(1, teeth); xe_p("\n" as *u8) 373 let lf: i64 = sys_openat_append("knowledge/status/nishi_os.log" as *u8, 0x1a4) 374 if lf >= 0 { 375 xe_fp(lf, "X509EMIT selftest teeth=" as *u8); xe_fn(lf, pass) 376 xe_fp(lf, "of" as *u8); xe_fn(lf, teeth) 377 xe_fp(lf, " oracle=incumbent-x509_parse+rsa-verify verdict=" as *u8) 378 if pass == teeth { xe_fp(lf, "GREEN\n" as *u8) } else { xe_fp(lf, "RED\n" as *u8) } 379 sys_close(lf) 380 } 381 if pass == teeth { sys_exit(0); return 0 } 382 sys_exit(1); return 1 383} 384 385func main(argc: i64, argv: *i64) -> i64 { 386 return xe_selftest() 387}