nx_tls12_prf.nx source
↩ module page · 67 lines · 2450 B
1// nx_tls12_prf.nx -- TLS 1.2 PRF (RFC 5246 §5), the key-derivation core of
2// the sovereign TLS 1.2 client lane (B2-TLS12-001). TLS 1.2 (unlike 1.3,
3// which uses HKDF) derives the master secret + key block via:
4//
5// PRF(secret, label, seed) = P_SHA256(secret, label || seed)
6// P_hash(secret, seed) = HMAC(secret, A(1)||seed) || HMAC(secret, A(2)||seed) || ...
7// A(0) = seed ; A(i) = HMAC(secret, A(i-1))
8//
9// For the modern cipher suites we target (ECDHE-RSA-AES128-GCM-SHA256, as on
10// httpbin.org / AWS-ELB-class TLS-1.2-only servers) the PRF hash is SHA-256.
11// Composes the shipped hmac_sha256 -- no new primitive.
12//
13// license_tier: INDEPENDENT_REDERIVE
14// genealogy_id: international-research-sources/ietf/rfc_5246
15// lineage_id: nishi_tls12_prf_q1
16
17import "nx_syscalls.nx"
18import "nx_hmac.nx"
19
20// PRF(secret, label, seed) -> out[0..out_len). label/seed are concatenated
21// (label first) to form the P_SHA256 seed, per RFC 5246 §5.
22func nx_tls12_prf_sha256(secret: *u8, secret_len: i64,
23 label: *u8, label_len: i64,
24 seed: *u8, seed_len: i64,
25 out: *u8, out_len: i64) -> i64 {
26 // labelseed = label || seed
27 let ls_len: i64 = label_len + seed_len
28 let ls: *u8 = sys_mmap(ls_len + 8)
29 var i: i64 = 0
30 while i < label_len { ls[i] = label[i]; i = i + 1 }
31 i = 0
32 while i < seed_len { ls[label_len + i] = seed[i]; i = i + 1 }
33
34 // A(1) = HMAC(secret, labelseed)
35 let a: *u8 = sys_mmap(32)
36 hmac_sha256(secret, secret_len, ls, ls_len, a)
37
38 let blkin: *u8 = sys_mmap(32 + ls_len + 8) // A(i) || labelseed
39 let blk: *u8 = sys_mmap(32) // HMAC output block
40 let anext: *u8 = sys_mmap(32) // A(i+1)
41
42 var pos: i64 = 0
43 while pos < out_len {
44 // out-block = HMAC(secret, A(i) || labelseed)
45 i = 0
46 while i < 32 { blkin[i] = a[i]; i = i + 1 }
47 i = 0
48 while i < ls_len { blkin[32 + i] = ls[i]; i = i + 1 }
49 hmac_sha256(secret, secret_len, blkin, 32 + ls_len, blk)
50
51 var n: i64 = out_len - pos
52 if n > 32 { n = 32 }
53 i = 0
54 while i < n { out[pos + i] = blk[i]; i = i + 1 }
55 pos = pos + 32
56
57 // A(i+1) = HMAC(secret, A(i))
58 hmac_sha256(secret, secret_len, a, 32, anext)
59 i = 0
60 while i < 32 { a[i] = anext[i]; i = i + 1 }
61 }
62 return 0
63}
64
65func main() -> i64 {
66 return 0
67}