@@ -72,25 +72,21 @@ type keySchedule13 struct {
7272
7373// Interface implemented by key exchange strategies
7474type kex interface {
75- // c - context of current TLS handshake, groupId - ID of an algorithm
76- // (curve/field) being chosen for key agreement. Methods implmenting an
77- // interface always assume that provided groupId is correct.
78- //
79- // In case of success, function returns secret key and ephemeral key. Otherwise
80- // error is set.
81- generate (c * Conn , groupId CurveID ) ([]byte , keyShare , error )
82- // keyAgreementClient declares an API for implementing shared secret agreement on
83- // the client side. `c` is a context of current TLS handshake, `ks` is a public key
84- // received from the server, ``privateKey`` client private key.
85- // Function returns shared secret in case of success or non nil error otherwise.
86- keyAgreementClient (c * Conn , ks keyShare , privateKey []byte ) ([]byte , error )
87- // keyAgreementServer declares an API for implementing shared secret agreement on
88- // the server side. `c` context of current TLS handshake, `ks` is a public key
89- // received from the client side of the connection, ``privateKey`` is a private key
90- // of a server.
91- // Function returns secret shared between parties and public value to exchange
92- // between parties. In case of failure `error` must be set.
93- keyAgreementServer (c * Conn , ks keyShare ) ([]byte , keyShare , error )
75+ // generate generates an ephemeral key. The caller must ensure that a
76+ // valid curve or field is given. Returns a new ephemeral secret and
77+ // public key on success and an error on failure.
78+ generate (isClient bool , rand io.Reader , groupId CurveID ) ([]byte , keyShare , error )
79+
80+ // keyAgreementClient derives a shared secret for the client given the
81+ // server's public key share and the client's private key.
82+ // It returns a shared secret in case of success or an error otherwise.
83+ keyAgreementClient (ks keyShare , privateKey []byte ) ([]byte , error )
84+
85+ // keyAgreementServer derives a shared secret for the server using the
86+ // public key provided by the client and a randomly generated secret.
87+ // It returns the shared secret and the server's public key on success
88+ // or an error otherwise.
89+ keyAgreementServer (rand io.Reader , ks keyShare ) ([]byte , keyShare , error )
9490}
9591
9692// defaultServerKEX is an abstract class defining default, common behaviour on
@@ -100,17 +96,17 @@ type defaultServerKEX struct{}
10096// defaultServerKEX is an abstract class defining default implementation of
10197// server side key agreement. It generates ephemeral key and uses it together
10298// with client public part in order to calculate shared secret.
103- func (defaultServerKEX ) keyAgreementServer (c * Conn , clientKS keyShare ) ([]byte , keyShare , error ) {
104- privateKey , publicKey , err := c .generateKeyShare (clientKS .group )
99+ func (defaultServerKEX ) keyAgreementServer (rand io.Reader , clientKS keyShare ) ([]byte , keyShare , error ) {
100+ // The first parameter does not exactly matter, this implementation
101+ // assumes that both roles perform the same computations.
102+ privateKey , publicKey , err := generateKeyShare (false , rand , clientKS .group )
105103 if err != nil {
106- c .sendAlert (alertInternalError )
107104 return nil , keyShare {}, err
108105 }
109106
110107 // Use same key agreement implementation as on the client side
111- ss , err := c . keyAgreementClient (clientKS , privateKey )
108+ ss , err := keyAgreementClient (clientKS , privateKey )
112109 if err != nil {
113- c .sendAlert (alertIllegalParameter )
114110 return nil , keyShare {}, err
115111 }
116112 return ss , publicKey , nil
@@ -122,7 +118,6 @@ type kexX25519 struct{ defaultServerKEX } // Used by X25519
122118type kexSIDHp503 struct { defaultServerKEX } // Used by SIDH/P503
123119type kexSIKEp503 struct {} // Used by SIKE/P503
124120type kexHybridSIDHp503X25519 struct {
125- defaultServerKEX
126121 classicKEX kexX25519
127122 pqKEX kexSIDHp503
128123} // Used by SIDH-ECDH hybrid scheme
@@ -272,7 +267,7 @@ CurvePreferenceLoop:
272267 c .sendAlert (alertInternalError )
273268 return errors .New ("tls: HelloRetryRequest not implemented" ) // TODO(filippo)
274269 }
275- sharedSecret , serverKS , err := c . keyAgreementServer ( ks )
270+ sharedSecret , serverKS , err := keyAgreementServer ( c . config . rand (), ks )
276271 if err != nil {
277272 return err
278273 }
@@ -639,27 +634,27 @@ func prepareDigitallySigned(hash crypto.Hash, context string, data []byte) []byt
639634// structure with keyShare.group set to supported group ID (as per 4.2.7 in RFC 8446)
640635// and keyShare.data set to public key, third argument is nil. On failure, third returned
641636// value (an error) contains error message and first two values are undefined.
642- func ( c * Conn ) generateKeyShare ( curveID CurveID ) ([]byte , keyShare , error ) {
637+ func generateKeyShare ( isClient bool , rand io. Reader , curveID CurveID ) ([]byte , keyShare , error ) {
643638 if val , ok := kexStrat [curveID ]; ok {
644- return val .generate (c , curveID )
639+ return val .generate (isClient , rand , curveID )
645640 }
646641 return nil , keyShare {}, errors .New ("tls: preferredCurves includes unsupported curve" )
647642}
648643
649644// DH key agreement. ks stores public key, secretKey stores private key used for ephemeral
650645// key agreement. Function returns shared secret in case of success or empty slice otherwise.
651- func ( c * Conn ) keyAgreementClient (ks keyShare , secretKey []byte ) ([]byte , error ) {
646+ func keyAgreementClient (ks keyShare , secretKey []byte ) ([]byte , error ) {
652647 if val , ok := kexStrat [ks .group ]; ok {
653- return val .keyAgreementClient (c , ks , secretKey )
648+ return val .keyAgreementClient (ks , secretKey )
654649 }
655650 return nil , errors .New ("tls: unsupported group" )
656651}
657652
658653// keyAgreementServer generates ephemeral keypair on the on the server side
659654// and then uses 'keyShare' (client public key) to derive shared secret
660- func ( c * Conn ) keyAgreementServer ( clientKS keyShare ) ([]byte , keyShare , error ) {
655+ func keyAgreementServer ( rand io. Reader , clientKS keyShare ) ([]byte , keyShare , error ) {
661656 if val , ok := kexStrat [clientKS .group ]; ok {
662- return val .keyAgreementServer (c , clientKS )
657+ return val .keyAgreementServer (rand , clientKS )
663658 }
664659 return nil , keyShare {}, errors .New ("unsupported group" )
665660}
@@ -1037,7 +1032,7 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
10371032
10381033 // 0-RTT is not supported yet, so use an empty PSK.
10391034 hs .keySchedule .setSecret (nil )
1040- sharedSecret , err := c . keyAgreementClient (serverHello .keyShare , hs .privateKey )
1035+ sharedSecret , err := keyAgreementClient (serverHello .keyShare , hs .privateKey )
10411036 if err != nil {
10421037 c .sendAlert (alertIllegalParameter )
10431038 return err
@@ -1221,18 +1216,18 @@ func supportedSigAlgorithmsCert(schemes []SignatureScheme) (ret []SignatureSchem
12211216// Functions below implement kex interface for different DH shared secret agreements
12221217
12231218// KEX: P-256, P-384, P-512 KEX
1224- func (kexNIST ) generate (c * Conn , groupId CurveID ) (private []byte , ks keyShare , err error ) {
1219+ func (kexNIST ) generate (isClient bool , rand io. Reader , groupId CurveID ) (private []byte , ks keyShare , err error ) {
12251220 // never fails
12261221 curve , _ := curveForCurveID (groupId )
1227- private , x , y , err := elliptic .GenerateKey (curve , c . config . rand () )
1222+ private , x , y , err := elliptic .GenerateKey (curve , rand )
12281223 if err != nil {
12291224 return nil , keyShare {}, err
12301225 }
12311226 ks .group = groupId
12321227 ks .data = elliptic .Marshal (curve , x , y )
12331228 return
12341229}
1235- func (kexNIST ) keyAgreementClient (c * Conn , ks keyShare , secretKey []byte ) ([]byte , error ) {
1230+ func (kexNIST ) keyAgreementClient (ks keyShare , secretKey []byte ) ([]byte , error ) {
12361231 // never fails
12371232 curve , _ := curveForCurveID (ks .group )
12381233 x , y := elliptic .Unmarshal (curve , ks .data )
@@ -1251,16 +1246,16 @@ func (kexNIST) keyAgreementClient(c *Conn, ks keyShare, secretKey []byte) ([]byt
12511246}
12521247
12531248// KEX: X25519
1254- func (kexX25519 ) generate (c * Conn , groupId CurveID ) ([]byte , keyShare , error ) {
1249+ func (kexX25519 ) generate (isClient bool , rand io. Reader , groupId CurveID ) ([]byte , keyShare , error ) {
12551250 var scalar , public [x25519Sz ]byte
1256- if _ , err := io .ReadFull (c . config . rand () , scalar [:]); err != nil {
1251+ if _ , err := io .ReadFull (rand , scalar [:]); err != nil {
12571252 return nil , keyShare {}, err
12581253 }
12591254 curve25519 .ScalarBaseMult (& public , & scalar )
12601255 return scalar [:], keyShare {group : X25519 , data : public [:]}, nil
12611256}
12621257
1263- func (kexX25519 ) keyAgreementClient (c * Conn , ks keyShare , secretKey []byte ) ([]byte , error ) {
1258+ func (kexX25519 ) keyAgreementClient (ks keyShare , secretKey []byte ) ([]byte , error ) {
12641259 var theirPublic , sharedKey , scalar [x25519Sz ]byte
12651260 if len (ks .data ) != x25519Sz {
12661261 return nil , errors .New ("tls: wrong shared secret size" )
@@ -1272,18 +1267,18 @@ func (kexX25519) keyAgreementClient(c *Conn, ks keyShare, secretKey []byte) ([]b
12721267}
12731268
12741269// KEX: SIDH/503
1275- func (kexSIDHp503 ) generate (c * Conn , groupId CurveID ) ([]byte , keyShare , error ) {
1276- var variant , _ = getSidhKeyVariant (c . isClient )
1270+ func (kexSIDHp503 ) generate (isClient bool , rand io. Reader , groupId CurveID ) ([]byte , keyShare , error ) {
1271+ var variant , _ = getSidhKeyVariant (isClient )
12771272 var prvKey = sidh .NewPrivateKey (sidh .FP_503 , variant )
1278- if prvKey .Generate (c . config . rand () ) != nil {
1273+ if prvKey .Generate (rand ) != nil {
12791274 return nil , keyShare {}, errors .New ("tls: private SIDH key generation failed" )
12801275 }
12811276 pubKey := prvKey .GeneratePublicKey ()
12821277 return prvKey .Export (), keyShare {group : 0 /*UNUSED*/ , data : pubKey .Export ()}, nil
12831278}
12841279
1285- func (kexSIDHp503 ) keyAgreementClient (c * Conn , ks keyShare , key []byte ) ([]byte , error ) {
1286- var prvVariant , pubVariant = getSidhKeyVariant (c . isClient )
1280+ func (kexSIDHp503 ) keyAgreementClient (isClient bool , ks keyShare , key []byte ) ([]byte , error ) {
1281+ var prvVariant , pubVariant = getSidhKeyVariant (isClient )
12871282
12881283 if len (ks .data ) != SIDHp503PubKeySz || len (key ) != SIDHp503PrvKeySz {
12891284 return nil , errors .New ("tls: wrong key size" )
@@ -1305,20 +1300,20 @@ func (kexSIDHp503) keyAgreementClient(c *Conn, ks keyShare, key []byte) ([]byte,
13051300}
13061301
13071302// KEX Hybrid SIDH/503-X25519
1308- func (kex * kexHybridSIDHp503X25519 ) generate (c * Conn , groupId CurveID ) (private []byte , ks keyShare , err error ) {
1303+ func (kex * kexHybridSIDHp503X25519 ) generate (isClient bool , rand io. Reader , groupId CurveID ) (private []byte , ks keyShare , err error ) {
13091304 var pubHybrid [SIDHp503Curve25519PubKeySz ]byte
13101305 var prvHybrid [SIDHp503Curve25519PrvKeySz ]byte
13111306
13121307 // Generate ephemeral key for classic x25519
1313- private , ks , err = kex .classicKEX .generate (c , groupId )
1308+ private , ks , err = kex .classicKEX .generate (isClient , rand , groupId )
13141309 if err != nil {
13151310 return
13161311 }
13171312 copy (prvHybrid [:], private )
13181313 copy (pubHybrid [:], ks .data )
13191314
13201315 // Generate PQ ephemeral key for SIDH
1321- private , ks , err = kex .pqKEX .generate (c , groupId )
1316+ private , ks , err = kex .pqKEX .generate (isClient , rand , groupId )
13221317 if err != nil {
13231318 return
13241319 }
@@ -1327,15 +1322,15 @@ func (kex *kexHybridSIDHp503X25519) generate(c *Conn, groupId CurveID) (private
13271322 return prvHybrid [:], keyShare {group : HybridSIDHp503Curve25519 , data : pubHybrid [:]}, nil
13281323}
13291324
1330- func (kex * kexHybridSIDHp503X25519 ) keyAgreementClient ( c * Conn , theirsKS keyShare , key []byte ) ([]byte , error ) {
1325+ func (kex * kexHybridSIDHp503X25519 ) computeSharedSecret ( isClient bool , theirsKS keyShare , key []byte ) ([]byte , error ) {
13311326 var sharedKey [SIDHp503Curve25519SharedKeySz ]byte
13321327 var ret []byte
13331328 var tmpKs keyShare
13341329
13351330 // Key agreement for classic
13361331 tmpKs .group = X25519
13371332 tmpKs .data = theirsKS .data [:x25519Sz ]
1338- ret , err := kex .classicKEX .keyAgreementClient (c , tmpKs , key [:x25519Sz ])
1333+ ret , err := kex .classicKEX .keyAgreementClient (tmpKs , key [:x25519Sz ])
13391334 if err != nil {
13401335 return nil , err
13411336 }
@@ -1344,22 +1339,39 @@ func (kex *kexHybridSIDHp503X25519) keyAgreementClient(c *Conn, theirsKS keyShar
13441339 // Key agreement for PQ
13451340 tmpKs .group = 0 /*UNUSED*/
13461341 tmpKs .data = theirsKS .data [x25519Sz :]
1347- ret , err = kex .pqKEX .keyAgreementClient (c , tmpKs , key [x25519Sz :])
1342+ ret , err = kex .pqKEX .keyAgreementClient (isClient , tmpKs , key [x25519Sz :])
13481343 if err != nil {
13491344 return nil , err
13501345 }
13511346 copy (sharedKey [x25519Sz :], ret )
13521347 return sharedKey [:], nil
13531348}
13541349
1350+ func (kex * kexHybridSIDHp503X25519 ) keyAgreementClient (theirsKS keyShare , key []byte ) ([]byte , error ) {
1351+ return kex .computeSharedSecret (true , theirsKS , key )
1352+ }
1353+
1354+ func (kex * kexHybridSIDHp503X25519 ) keyAgreementServer (rand io.Reader , clientKS keyShare ) ([]byte , keyShare , error ) {
1355+ privateKey , publicKey , err := generateKeyShare (false , rand , clientKS .group )
1356+ if err != nil {
1357+ return nil , keyShare {}, err
1358+ }
1359+
1360+ ss , err := kex .computeSharedSecret (false , clientKS , privateKey )
1361+ if err != nil {
1362+ return nil , keyShare {}, err
1363+ }
1364+ return ss , publicKey , nil
1365+ }
1366+
13551367// generate method generates SIKE key pair (ephemeral) on client side
1356- func (kexSIKEp503 ) generate (c * Conn , groupId CurveID ) ([]byte , keyShare , error ) {
1357- if ! c . isClient {
1368+ func (kexSIKEp503 ) generate (isClient bool , rand io. Reader , groupId CurveID ) ([]byte , keyShare , error ) {
1369+ if ! isClient {
13581370 return nil , keyShare {}, errors .New ("tls: internal error" )
13591371 }
13601372
13611373 var prvKey = sidh .NewPrivateKey (sidh .FP_503 , sidh .KeyVariant_SIKE )
1362- if prvKey .Generate (c . config . rand () ) != nil {
1374+ if prvKey .Generate (rand ) != nil {
13631375 return nil , keyShare {}, errors .New ("tls: private SIDH key generation failed" )
13641376 }
13651377 var pubKey = prvKey .GeneratePublicKey ()
@@ -1375,7 +1387,7 @@ func (kexSIKEp503) generate(c *Conn, groupId CurveID) ([]byte, keyShare, error)
13751387
13761388// keyAgreementClient performs KEM decapsulation. 'privateKey' is a concatenation
13771389// of (private || public) key
1378- func (kexSIKEp503 ) keyAgreementClient (c * Conn , theirsKS keyShare , privateKey []byte ) ([]byte , error ) {
1390+ func (kexSIKEp503 ) keyAgreementClient (theirsKS keyShare , privateKey []byte ) ([]byte , error ) {
13791391 // Import private key
13801392 var prvKey = sidh .NewPrivateKey (sidh .FP_503 , sidh .KeyVariant_SIKE )
13811393 var pubKey = sidh .NewPublicKey (sidh .FP_503 , sidh .KeyVariant_SIKE )
@@ -1396,33 +1408,33 @@ func (kexSIKEp503) keyAgreementClient(c *Conn, theirsKS keyShare, privateKey []b
13961408}
13971409
13981410// keyAgreementServer performs KEM encapsulation.
1399- func (kexSIKEp503 ) keyAgreementServer (c * Conn , theirsKS keyShare ) ([]byte , keyShare , error ) {
1411+ func (kexSIKEp503 ) keyAgreementServer (rand io. Reader , theirsKS keyShare ) ([]byte , keyShare , error ) {
14001412 pubKey := sidh .NewPublicKey (sidh .FP_503 , sidh .KeyVariant_SIKE )
14011413 if pubKey .Import (theirsKS .data ) != nil {
14021414 return nil , keyShare {}, errors .New ("tls: can't import public SIKE key" )
14031415 }
1404- ct , key , err := sike .Encapsulate (c . config . rand () , pubKey )
1416+ ct , key , err := sike .Encapsulate (rand , pubKey )
14051417 if err != nil {
14061418 return nil , keyShare {}, errors .New ("tls: SIKE encapsulation failed" )
14071419 }
14081420 return key , keyShare {data : ct }, nil
14091421}
14101422
14111423// KEX Hybrid SIKEp503-X25519
1412- func (kex * kexHybridSIKEp503X25519 ) generate (c * Conn , groupId CurveID ) ([]byte , keyShare , error ) {
1424+ func (kex * kexHybridSIKEp503X25519 ) generate (isClient bool , rand io. Reader , groupId CurveID ) ([]byte , keyShare , error ) {
14131425 var pubHybrid [SIKEp503Curve25519PubKeySz ]byte
14141426 var prvHybrid [SIKEp503Curve25519PrvKeySz + SIDHp503PubKeySz ]byte
14151427
14161428 // Generate ephemeral key for classic x25519
1417- private , ks , err := kex .classicKEX .generate (c , 0 )
1429+ private , ks , err := kex .classicKEX .generate (isClient , rand , 0 )
14181430 if err != nil {
14191431 return nil , keyShare {}, err
14201432 }
14211433 copy (prvHybrid [:], private )
14221434 copy (pubHybrid [:], ks .data )
14231435
14241436 // Generate PQ ephemeral key for SIDH
1425- private , ks , err = kex .pqKEX .generate (c , 0 )
1437+ private , ks , err = kex .pqKEX .generate (isClient , rand , 0 )
14261438 if err != nil {
14271439 return nil , keyShare {}, err
14281440 }
@@ -1435,7 +1447,7 @@ func (kex *kexHybridSIKEp503X25519) generate(c *Conn, groupId CurveID) ([]byte,
14351447// X25519 public key and SIKEp503 KEM generated by the server. 'privateKey' is a key stored
14361448// locally by the process. It is a concatenation of (X25519 || SIKEp503 private || SIKEp503 public) keys.
14371449// In case of success concatenation of (X25519||SIKEp503) shared secrets is returned (32+16 bytes).
1438- func (kex * kexHybridSIKEp503X25519 ) keyAgreementClient (c * Conn , theirsKS keyShare , privateKey []byte ) ([]byte , error ) {
1450+ func (kex * kexHybridSIKEp503X25519 ) keyAgreementClient (theirsKS keyShare , privateKey []byte ) ([]byte , error ) {
14391451 var ssHyb [SIKEp503Curve25519SharedKeySz ]byte
14401452 var tmpKs keyShare
14411453
@@ -1450,7 +1462,7 @@ func (kex *kexHybridSIKEp503X25519) keyAgreementClient(c *Conn, theirsKS keyShar
14501462 // Key agreement for classic
14511463 tmpKs .group = X25519
14521464 tmpKs .data = theirsKS .data [:x25519Sz ]
1453- ret , err := kex .classicKEX .keyAgreementClient (c , tmpKs , privateKey [:x25519Sz ])
1465+ ret , err := kex .classicKEX .keyAgreementClient (tmpKs , privateKey [:x25519Sz ])
14541466 if err != nil {
14551467 return nil , err
14561468 }
@@ -1459,7 +1471,7 @@ func (kex *kexHybridSIKEp503X25519) keyAgreementClient(c *Conn, theirsKS keyShar
14591471 // Key agreement for PQ
14601472 tmpKs .group = 0 /*UNUSED*/
14611473 tmpKs .data = theirsKS .data [x25519Sz :]
1462- ret , err = kex .pqKEX .keyAgreementClient (c , tmpKs , privateKey [x25519Sz :])
1474+ ret , err = kex .pqKEX .keyAgreementClient (tmpKs , privateKey [x25519Sz :])
14631475 if err != nil {
14641476 return nil , err
14651477 }
@@ -1471,7 +1483,7 @@ func (kex *kexHybridSIKEp503X25519) keyAgreementClient(c *Conn, theirsKS keyShar
14711483// contains concatenation of public keys for both X25519 and SIKEp503. In case of success
14721484// function returns X25519 and SIKEp503 shaerd secret concatenated together and concatenation of
14731485// X25519 public and SIKEp503 ciphertext that are sent to the client.
1474- func (kex * kexHybridSIKEp503X25519 ) keyAgreementServer (c * Conn , theirsKS keyShare ) ([]byte , keyShare , error ) {
1486+ func (kex * kexHybridSIKEp503X25519 ) keyAgreementServer (rand io. Reader , theirsKS keyShare ) ([]byte , keyShare , error ) {
14751487 var ssHyb [SIKEp503Curve25519SharedKeySz ]byte
14761488 var ret [SIKEp503Curve25519CtSz ]byte
14771489
@@ -1480,7 +1492,7 @@ func (kex *kexHybridSIKEp503X25519) keyAgreementServer(c *Conn, theirsKS keyShar
14801492 }
14811493
14821494 var tmpKs = keyShare {group : X25519 , data : theirsKS .data [:x25519Sz ]}
1483- ss , srvKs , err := kex .classicKEX .keyAgreementServer (c , tmpKs )
1495+ ss , srvKs , err := kex .classicKEX .keyAgreementServer (rand , tmpKs )
14841496 if err != nil {
14851497 return nil , keyShare {}, err
14861498 }
@@ -1489,7 +1501,7 @@ func (kex *kexHybridSIKEp503X25519) keyAgreementServer(c *Conn, theirsKS keyShar
14891501
14901502 tmpKs .group = 0 /*UNUSED*/
14911503 tmpKs .data = theirsKS .data [x25519Sz :]
1492- ss , srvKs , err = kex .pqKEX .keyAgreementServer (c , tmpKs )
1504+ ss , srvKs , err = kex .pqKEX .keyAgreementServer (rand , tmpKs )
14931505 if err != nil {
14941506 return nil , keyShare {}, err
14951507 }
0 commit comments