Plan 9の暗号処理部分を読んだメモ
This content is a draft and will not be included in production builds.
TLS 1.2 AEAD対応のためにコードを読んだときのメモ。さすがに雑すぎるので整理したい。
* 鍵交換: libsecのtlsClient, tlsServer ここでmaster secretとsecretを取り出す encalgs, hashalgs, secretをdevtlsにwriteする DHE, ECDHE* 認証: factotum 通信で利用する証明書に対応するキーペアをfactotumから取り出す 証明書に含まれる公開鍵によって、RSAだったりECDSAだったりする* 共通鍵暗号: devtls AES/CBC, AES/GCM... devtls: aes_256_cbc, aes_256_gcm_aead, ...* メッセージ認証(ハッシュ関数): devtls SHA1, SHA256 devtls: sha1, sha256
[client]/sys/src/libsec/port/tlshand.c:tlsClient ctl = open(#/tls/clone) hand = open(#/tls/$n/hand) data = open(#/tls/$n/data) fprint(ctl, "fd $remotefd 0x$protoVersion") tlsClient2()
/sys/src/libsec/port/tlshand.c:tlsClient2 :ctl = #/tls/$n/ctl :hand = #/tls/$n/hand :cert = ? :psk = ? :ext = ?
var c TlsConnection c.ctl = ctl c.hand = hand if(psk) c.sec.psk = psk if(cert){ c.sec.rsapub = X509toRSApub(cert) c.sec.rpc = factotum_rsa_open(c.sec.rsapub) } // > client hello
// < server hello // この辺りでアルゴリズムを設定している dhx = isDHE(cihper) || isECDHE(cipher) msgRecv(c, &m) if(m.tag == HCertificate){ c.cert = makebytes(...) msgRecv(c, &m) } if(m.tag == HServerKeyExchange){ if(dhx){ ... if(isECDHE(cipher)) epm = tlsSecECDHEc(c.sec, curve, dh_Ys) else epm = tlsSecDHEc(c.sec, dh_p, dh_g, dh_Ys) } }
// < certificate request (optional)
if(!dhx){ if(c.cert) epm = tlsSecRSAc(c.sec, c.cert) else if(psk) setMasterSecret(c.sec, ...) } setSecrets(c, 1)
/sys/src/libsec/port/tlshand.c:factotum_rsa_open afd = open(/mnt/factotum/rpc) rpc = auth_allocrpc(afd) auth_rpc(rpc, "start", "proto=rsa service=tls role=client") while(n = auth_rpc(rpc, "read")) if(n == rsapub.n) return rpc return nil
/sys/src/libsec/port/tlshand.c:tlsSecDHEc :sec TlsSec :p, g, Ys
P = bytestomp(p) G = bytestomp(g) Y = bytestomp(Ys) dh_new(dh, P, nil, G) n = (mpsignif(P) + 7) / 8 Yc = mptobytes(dh->y, n) K = dh_finish(dh, Y) setMasterSecret(sec, mptobytes(K, n))
/sys/src/libsec/port/tlshand.c:setMasterSecret :sec TlsSec :pm *Bytes
// だいたいtls12PRF sec.prf(sec.sec, pm, "master secret", sec.crandom, sec.srandom)
/sys/src/libsec/port/tlshand.c:tls12PRF :buf :key :label :seed0 :seed1
seed = append(seed0, seed1) p_sha256(buf, key, label, seed)
/sys/src/libsec/port/tlshand.c:setSecrets :c TlsConnection :isclient bool
c.sec.prf(kd, c.sec.sec, "key expansion", c.sec.srandom, c.sec.crandom) enc64(secrets, 2*c.nsecret, kd, c.nsecret) fprint(c.ctl, "secret $c.digest $c.enc $isclient $secrets") // secret hashalg encalg isclient secretdata- https://code.9front.org/hg/plan9front/file/bc7c2ed6d7aa/sys/src/libsec/port
- https://code.9front.org/hg/plan9front/file/bc7c2ed6d7aa/sys/src/libsec/port/tlshand.c
- https://code.9front.org/hg/plan9front/file/808eb735fc45/sys/src/9/port/devtls.c#l1510
- https://github.com/lufia/plan9/blob/main/sys/src/9/port/devtls.c
- https://github.com/lufia/plan9/blob/main/sys/src/libsec/port/tlshand.c