code wiki / (root) / nx_tls12_keys.nx

nx_tls12_keys.nx source

↩ module page · 49 lines · 2214 B

1// nx_tls12_keys.nx -- TLS 1.2 key schedule (rung 3 of the sovereign TLS 1.2 client). 2// Wires the already-RFC-tested nx_tls12_prf_sha256 with the exact labels + seed orders RFC 5246 specifies: 3// master_secret = PRF(premaster, "master secret", client_random || server_random)[0..48] 4// key_block = PRF(master_secret, "key expansion", server_random || client_random)[0..n] (NOTE: SR||CR) 5// For ECDHE-*-AES128-GCM (AEAD, no MAC keys) the 40-byte key_block splits as: 6// client_write_key(16) | server_write_key(16) | client_write_IV(4) | server_write_IV(4) 7// license_tier: ORIGINAL 8import "nx_syscalls.nx" 9import "nx_tls12_prf.nx" 10 11func tls12_derive_master_secret(pm: *u8, pm_len: i64, cr: *u8, sr: *u8, out48: *u8) -> i64 { 12 let seed: *u8 = sys_mmap(80) 13 var i: i64 = 0 14 while i < 32 { seed[i] = cr[i]; i = i + 1 } 15 i = 0 16 while i < 32 { seed[32 + i] = sr[i]; i = i + 1 } 17 nx_tls12_prf_sha256(pm, pm_len, "master secret" as *u8, 13, seed, 64, out48, 48) 18 return 48 19} 20 21func tls12_derive_key_block(ms: *u8, sr: *u8, cr: *u8, out: *u8, n: i64) -> i64 { 22 let seed: *u8 = sys_mmap(80) 23 var i: i64 = 0 24 while i < 32 { seed[i] = sr[i]; i = i + 1 } // server_random FIRST for key expansion 25 i = 0 26 while i < 32 { seed[32 + i] = cr[i]; i = i + 1 } 27 nx_tls12_prf_sha256(ms, 48, "key expansion" as *u8, 13, seed, 64, out, n) 28 return n 29} 30 31// Split a 40-byte AES-128-GCM key_block into the four AEAD parts. 32func tls12_split_keys_aes128gcm(kb: *u8, c_key: *u8, s_key: *u8, c_iv: *u8, s_iv: *u8) -> i64 { 33 var i: i64 = 0 34 while i < 16 { c_key[i] = kb[i]; i = i + 1 } 35 i = 0 36 while i < 16 { s_key[i] = kb[16 + i]; i = i + 1 } 37 i = 0 38 while i < 4 { c_iv[i] = kb[32 + i]; i = i + 1 } 39 i = 0 40 while i < 4 { s_iv[i] = kb[36 + i]; i = i + 1 } 41 return 40 42} 43 44// Finished verify_data = PRF(master_secret, finished_label, Hash(handshake_messages))[0..12]. 45// finished_label = "client finished" (client) or "server finished" (server). 46func tls12_finished_verify_data(ms: *u8, label: *u8, label_len: i64, handshake_hash32: *u8, out12: *u8) -> i64 { 47 nx_tls12_prf_sha256(ms, 48, label, label_len, handshake_hash32, 32, out12, 12) 48 return 12 49}