Skip to content

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