1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * SSL3 Protocol
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 
9 /* ECC code moved here from ssl3con.c */
10 
11 #include "cert.h"
12 #include "ssl.h"
13 #include "cryptohi.h" /* for DSAU_ stuff */
14 #include "keyhi.h"
15 #include "secder.h"
16 #include "secitem.h"
17 
18 #include "sslimpl.h"
19 #include "sslproto.h"
20 #include "sslerr.h"
21 #include "ssl3ext.h"
22 #include "prtime.h"
23 #include "prinrval.h"
24 #include "prerror.h"
25 #include "pratom.h"
26 #include "prthread.h"
27 #include "prinit.h"
28 
29 #include "pk11func.h"
30 #include "secmod.h"
31 
32 #include <stdio.h>
33 
34 SECStatus
ssl_NamedGroup2ECParams(PLArenaPool * arena,const sslNamedGroupDef * ecGroup,SECKEYECParams * params)35 ssl_NamedGroup2ECParams(PLArenaPool *arena, const sslNamedGroupDef *ecGroup,
36                         SECKEYECParams *params)
37 {
38     SECOidData *oidData = NULL;
39 
40     if (!params) {
41         PORT_Assert(0);
42         PORT_SetError(SEC_ERROR_INVALID_ARGS);
43         return SECFailure;
44     }
45 
46     if (!ecGroup || ecGroup->keaType != ssl_kea_ecdh ||
47         (oidData = SECOID_FindOIDByTag(ecGroup->oidTag)) == NULL) {
48         PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
49         return SECFailure;
50     }
51 
52     if (SECITEM_AllocItem(arena, params, (2 + oidData->oid.len)) == NULL) {
53         PORT_SetError(SEC_ERROR_NO_MEMORY);
54         return SECFailure;
55     }
56 
57     /*
58      * params->data needs to contain the ASN encoding of an object ID (OID)
59      * representing the named curve. The actual OID is in
60      * oidData->oid.data so we simply prepend 0x06 and OID length
61      */
62     params->data[0] = SEC_ASN1_OBJECT_ID;
63     params->data[1] = oidData->oid.len;
64     memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
65 
66     return SECSuccess;
67 }
68 
69 const sslNamedGroupDef *
ssl_ECPubKey2NamedGroup(const SECKEYPublicKey * pubKey)70 ssl_ECPubKey2NamedGroup(const SECKEYPublicKey *pubKey)
71 {
72     SECItem oid = { siBuffer, NULL, 0 };
73     SECOidData *oidData = NULL;
74     PRUint32 policyFlags = 0;
75     unsigned int i;
76     const SECKEYECParams *params;
77 
78     if (pubKey->keyType != ecKey) {
79         PORT_Assert(0);
80         return NULL;
81     }
82 
83     params = &pubKey->u.ec.DEREncodedParams;
84 
85     /*
86      * params->data needs to contain the ASN encoding of an object ID (OID)
87      * representing a named curve. Here, we strip away everything
88      * before the actual OID and use the OID to look up a named curve.
89      */
90     if (params->data[0] != SEC_ASN1_OBJECT_ID)
91         return NULL;
92     oid.len = params->len - 2;
93     oid.data = params->data + 2;
94     if ((oidData = SECOID_FindOID(&oid)) == NULL)
95         return NULL;
96     if ((NSS_GetAlgorithmPolicy(oidData->offset, &policyFlags) ==
97          SECSuccess) &&
98         !(policyFlags & NSS_USE_ALG_IN_SSL_KX)) {
99         return NULL;
100     }
101     for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
102         if (ssl_named_groups[i].oidTag == oidData->offset) {
103             return &ssl_named_groups[i];
104         }
105     }
106 
107     return NULL;
108 }
109 
110 /* Caller must set hiLevel error code. */
111 static SECStatus
ssl3_ComputeECDHKeyHash(SSLHashType hashAlg,SECItem ec_params,SECItem server_ecpoint,PRUint8 * client_rand,PRUint8 * server_rand,SSL3Hashes * hashes)112 ssl3_ComputeECDHKeyHash(SSLHashType hashAlg,
113                         SECItem ec_params, SECItem server_ecpoint,
114                         PRUint8 *client_rand, PRUint8 *server_rand,
115                         SSL3Hashes *hashes)
116 {
117     PRUint8 *hashBuf;
118     PRUint8 *pBuf;
119     SECStatus rv = SECSuccess;
120     unsigned int bufLen;
121     /*
122      * We only support named curves (the appropriate checks are made before this
123      * method is called) so ec_params takes up only two bytes. ECPoint needs to
124      * fit in 256 bytes because the spec says the length must fit in one byte.
125      */
126     PRUint8 buf[2 * SSL3_RANDOM_LENGTH + 2 + 1 + 256];
127 
128     bufLen = 2 * SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.len;
129     if (bufLen <= sizeof buf) {
130         hashBuf = buf;
131     } else {
132         hashBuf = PORT_Alloc(bufLen);
133         if (!hashBuf) {
134             return SECFailure;
135         }
136     }
137 
138     memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
139     pBuf = hashBuf + SSL3_RANDOM_LENGTH;
140     memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
141     pBuf += SSL3_RANDOM_LENGTH;
142     memcpy(pBuf, ec_params.data, ec_params.len);
143     pBuf += ec_params.len;
144     pBuf[0] = (PRUint8)(server_ecpoint.len);
145     pBuf += 1;
146     memcpy(pBuf, server_ecpoint.data, server_ecpoint.len);
147     pBuf += server_ecpoint.len;
148     PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
149 
150     rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes);
151 
152     PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen));
153     PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result",
154                    hashes->u.s.md5, MD5_LENGTH));
155     PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result",
156                    hashes->u.s.sha, SHA1_LENGTH));
157 
158     if (hashBuf != buf)
159         PORT_Free(hashBuf);
160     return rv;
161 }
162 
163 /* Called from ssl3_SendClientKeyExchange(). */
164 SECStatus
ssl3_SendECDHClientKeyExchange(sslSocket * ss,SECKEYPublicKey * svrPubKey)165 ssl3_SendECDHClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey)
166 {
167     PK11SymKey *pms = NULL;
168     SECStatus rv = SECFailure;
169     PRBool isTLS, isTLS12;
170     CK_MECHANISM_TYPE target;
171     const sslNamedGroupDef *groupDef;
172     sslEphemeralKeyPair *keyPair = NULL;
173     SECKEYPublicKey *pubKey;
174 
175     PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
176     PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
177 
178     isTLS = (PRBool)(ss->version > SSL_LIBRARY_VERSION_3_0);
179     isTLS12 = (PRBool)(ss->version >= SSL_LIBRARY_VERSION_TLS_1_2);
180 
181     /* Generate ephemeral EC keypair */
182     if (svrPubKey->keyType != ecKey) {
183         PORT_SetError(SEC_ERROR_BAD_KEY);
184         goto loser;
185     }
186     groupDef = ssl_ECPubKey2NamedGroup(svrPubKey);
187     if (!groupDef) {
188         PORT_SetError(SEC_ERROR_BAD_KEY);
189         goto loser;
190     }
191     ss->sec.keaGroup = groupDef;
192     rv = ssl_CreateECDHEphemeralKeyPair(ss, groupDef, &keyPair);
193     if (rv != SECSuccess) {
194         ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
195         goto loser;
196     }
197 
198     pubKey = keyPair->keys->pubKey;
199     PRINT_BUF(50, (ss, "ECDH public value:",
200                    pubKey->u.ec.publicValue.data,
201                    pubKey->u.ec.publicValue.len));
202 
203     if (isTLS12) {
204         target = CKM_TLS12_MASTER_KEY_DERIVE_DH;
205     } else if (isTLS) {
206         target = CKM_TLS_MASTER_KEY_DERIVE_DH;
207     } else {
208         target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
209     }
210 
211     /* Determine the PMS */
212     pms = PK11_PubDeriveWithKDF(keyPair->keys->privKey, svrPubKey,
213                                 PR_FALSE, NULL, NULL, CKM_ECDH1_DERIVE, target,
214                                 CKA_DERIVE, 0, CKD_NULL, NULL, NULL);
215 
216     if (pms == NULL) {
217         (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
218         ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
219         goto loser;
220     }
221 
222     rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_client_key_exchange,
223                                     pubKey->u.ec.publicValue.len + 1);
224     if (rv != SECSuccess) {
225         goto loser; /* err set by ssl3_AppendHandshake* */
226     }
227 
228     rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.ec.publicValue.data,
229                                       pubKey->u.ec.publicValue.len, 1);
230 
231     if (rv != SECSuccess) {
232         goto loser; /* err set by ssl3_AppendHandshake* */
233     }
234 
235     rv = ssl3_InitPendingCipherSpecs(ss, pms, PR_TRUE);
236     if (rv != SECSuccess) {
237         ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
238         goto loser;
239     }
240 
241     PK11_FreeSymKey(pms);
242     ssl_FreeEphemeralKeyPair(keyPair);
243     return SECSuccess;
244 
245 loser:
246     if (pms)
247         PK11_FreeSymKey(pms);
248     if (keyPair)
249         ssl_FreeEphemeralKeyPair(keyPair);
250     return SECFailure;
251 }
252 
253 /*
254 ** Called from ssl3_HandleClientKeyExchange()
255 */
256 SECStatus
ssl3_HandleECDHClientKeyExchange(sslSocket * ss,PRUint8 * b,PRUint32 length,sslKeyPair * serverKeyPair)257 ssl3_HandleECDHClientKeyExchange(sslSocket *ss, PRUint8 *b,
258                                  PRUint32 length,
259                                  sslKeyPair *serverKeyPair)
260 {
261     PK11SymKey *pms;
262     SECStatus rv;
263     SECKEYPublicKey clntPubKey;
264     CK_MECHANISM_TYPE target;
265     PRBool isTLS, isTLS12;
266     int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH;
267 
268     PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
269     PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
270 
271     clntPubKey.keyType = ecKey;
272     clntPubKey.u.ec.DEREncodedParams.len =
273         serverKeyPair->pubKey->u.ec.DEREncodedParams.len;
274     clntPubKey.u.ec.DEREncodedParams.data =
275         serverKeyPair->pubKey->u.ec.DEREncodedParams.data;
276     clntPubKey.u.ec.encoding = ECPoint_Undefined;
277 
278     rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue,
279                                        1, &b, &length);
280     if (rv != SECSuccess) {
281         PORT_SetError(errCode);
282         return SECFailure;
283     }
284 
285     /* we have to catch the case when the client's public key has length 0. */
286     if (!clntPubKey.u.ec.publicValue.len) {
287         (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
288         PORT_SetError(errCode);
289         return SECFailure;
290     }
291 
292     isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
293     isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
294 
295     if (isTLS12) {
296         target = CKM_TLS12_MASTER_KEY_DERIVE_DH;
297     } else if (isTLS) {
298         target = CKM_TLS_MASTER_KEY_DERIVE_DH;
299     } else {
300         target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
301     }
302 
303     /*  Determine the PMS */
304     pms = PK11_PubDeriveWithKDF(serverKeyPair->privKey, &clntPubKey,
305                                 PR_FALSE, NULL, NULL,
306                                 CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
307                                 CKD_NULL, NULL, NULL);
308 
309     if (pms == NULL) {
310         /* last gasp.  */
311         errCode = ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
312         PORT_SetError(errCode);
313         return SECFailure;
314     }
315 
316     rv = ssl3_InitPendingCipherSpecs(ss, pms, PR_TRUE);
317     PK11_FreeSymKey(pms);
318     if (rv != SECSuccess) {
319         /* error code set by ssl3_InitPendingCipherSpec */
320         return SECFailure;
321     }
322     ss->sec.keaGroup = ssl_ECPubKey2NamedGroup(&clntPubKey);
323     return SECSuccess;
324 }
325 
326 /*
327 ** Take an encoded key share and make a public key out of it.
328 */
329 SECStatus
ssl_ImportECDHKeyShare(SECKEYPublicKey * peerKey,PRUint8 * b,PRUint32 length,const sslNamedGroupDef * ecGroup)330 ssl_ImportECDHKeyShare(SECKEYPublicKey *peerKey,
331                        PRUint8 *b, PRUint32 length,
332                        const sslNamedGroupDef *ecGroup)
333 {
334     SECStatus rv;
335     SECItem ecPoint = { siBuffer, NULL, 0 };
336 
337     if (!length) {
338         PORT_SetError(SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE);
339         return SECFailure;
340     }
341 
342     /* Fail if the ec point uses compressed representation */
343     if (b[0] != EC_POINT_FORM_UNCOMPRESSED &&
344         ecGroup->name != ssl_grp_ec_curve25519) {
345         PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
346         return SECFailure;
347     }
348 
349     peerKey->keyType = ecKey;
350     /* Set up the encoded params */
351     rv = ssl_NamedGroup2ECParams(peerKey->arena, ecGroup,
352                                  &peerKey->u.ec.DEREncodedParams);
353     if (rv != SECSuccess) {
354         ssl_MapLowLevelError(SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE);
355         return SECFailure;
356     }
357     peerKey->u.ec.encoding = ECPoint_Undefined;
358 
359     /* copy publicValue in peerKey */
360     ecPoint.data = b;
361     ecPoint.len = length;
362 
363     rv = SECITEM_CopyItem(peerKey->arena, &peerKey->u.ec.publicValue, &ecPoint);
364     if (rv != SECSuccess) {
365         return SECFailure;
366     }
367 
368     return SECSuccess;
369 }
370 
371 const sslNamedGroupDef *
ssl_GetECGroupWithStrength(sslSocket * ss,unsigned int requiredECCbits)372 ssl_GetECGroupWithStrength(sslSocket *ss, unsigned int requiredECCbits)
373 {
374     int i;
375 
376     PORT_Assert(ss);
377 
378     for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
379         const sslNamedGroupDef *group = ss->namedGroupPreferences[i];
380         if (group && group->keaType == ssl_kea_ecdh &&
381             group->bits >= requiredECCbits) {
382             return group;
383         }
384     }
385 
386     PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
387     return NULL;
388 }
389 
390 /* Find the "weakest link".  Get the strength of the signature and symmetric
391  * keys and choose a curve based on the weakest of those two. */
392 const sslNamedGroupDef *
ssl_GetECGroupForServerSocket(sslSocket * ss)393 ssl_GetECGroupForServerSocket(sslSocket *ss)
394 {
395     const sslServerCert *cert = ss->sec.serverCert;
396     unsigned int certKeySize;
397     const ssl3BulkCipherDef *bulkCipher;
398     unsigned int requiredECCbits;
399 
400     PORT_Assert(cert);
401     if (!cert || !cert->serverKeyPair || !cert->serverKeyPair->pubKey) {
402         PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
403         return NULL;
404     }
405 
406     if (SSL_CERT_IS(cert, ssl_auth_rsa_sign) ||
407         SSL_CERT_IS(cert, ssl_auth_rsa_pss)) {
408         certKeySize = SECKEY_PublicKeyStrengthInBits(cert->serverKeyPair->pubKey);
409         certKeySize = SSL_RSASTRENGTH_TO_ECSTRENGTH(certKeySize);
410     } else if (SSL_CERT_IS_EC(cert)) {
411         /* We won't select a certificate unless the named curve has been
412          * negotiated (or supported_curves was absent), double check that. */
413         PORT_Assert(cert->namedCurve->keaType == ssl_kea_ecdh);
414         PORT_Assert(ssl_NamedGroupEnabled(ss, cert->namedCurve));
415         if (!ssl_NamedGroupEnabled(ss, cert->namedCurve)) {
416             return NULL;
417         }
418         certKeySize = cert->namedCurve->bits;
419     } else {
420         PORT_Assert(0);
421         return NULL;
422     }
423     bulkCipher = ssl_GetBulkCipherDef(ss->ssl3.hs.suite_def);
424     requiredECCbits = bulkCipher->key_size * BPB * 2;
425     PORT_Assert(requiredECCbits ||
426                 ss->ssl3.hs.suite_def->bulk_cipher_alg == cipher_null);
427     if (requiredECCbits > certKeySize) {
428         requiredECCbits = certKeySize;
429     }
430 
431     return ssl_GetECGroupWithStrength(ss, requiredECCbits);
432 }
433 
434 /* Create an ECDHE key pair for a given curve */
435 SECStatus
ssl_CreateECDHEphemeralKeyPair(const sslSocket * ss,const sslNamedGroupDef * ecGroup,sslEphemeralKeyPair ** keyPair)436 ssl_CreateECDHEphemeralKeyPair(const sslSocket *ss,
437                                const sslNamedGroupDef *ecGroup,
438                                sslEphemeralKeyPair **keyPair)
439 {
440     SECKEYPrivateKey *privKey = NULL;
441     SECKEYPublicKey *pubKey = NULL;
442     SECKEYECParams ecParams = { siBuffer, NULL, 0 };
443     sslEphemeralKeyPair *pair;
444 
445     if (ssl_NamedGroup2ECParams(NULL, ecGroup, &ecParams) != SECSuccess) {
446         return SECFailure;
447     }
448     privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, ss->pkcs11PinArg);
449     SECITEM_FreeItem(&ecParams, PR_FALSE);
450 
451     if (!privKey || !pubKey ||
452         !(pair = ssl_NewEphemeralKeyPair(ecGroup, privKey, pubKey))) {
453         if (privKey) {
454             SECKEY_DestroyPrivateKey(privKey);
455         }
456         if (pubKey) {
457             SECKEY_DestroyPublicKey(pubKey);
458         }
459         ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
460         return SECFailure;
461     }
462 
463     *keyPair = pair;
464     SSL_TRC(50, ("%d: SSL[%d]: Create ECDH ephemeral key %d",
465                  SSL_GETPID(), ss ? ss->fd : NULL, ecGroup->name));
466     PRINT_BUF(50, (ss, "Public Key", pubKey->u.ec.publicValue.data,
467                    pubKey->u.ec.publicValue.len));
468 #ifdef TRACE
469     if (ssl_trace >= 50) {
470         SECItem d = { siBuffer, NULL, 0 };
471         SECStatus rv = PK11_ReadRawAttribute(PK11_TypePrivKey, privKey,
472                                              CKA_VALUE, &d);
473         if (rv == SECSuccess) {
474             PRINT_BUF(50, (ss, "Private Key", d.data, d.len));
475             SECITEM_FreeItem(&d, PR_FALSE);
476         } else {
477             SSL_TRC(50, ("Error extracting private key"));
478         }
479     }
480 #endif
481     return SECSuccess;
482 }
483 
484 SECStatus
ssl3_HandleECDHServerKeyExchange(sslSocket * ss,PRUint8 * b,PRUint32 length)485 ssl3_HandleECDHServerKeyExchange(sslSocket *ss, PRUint8 *b, PRUint32 length)
486 {
487     PLArenaPool *arena = NULL;
488     SECKEYPublicKey *peerKey = NULL;
489     PRBool isTLS;
490     SECStatus rv;
491     int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
492     SSL3AlertDescription desc = illegal_parameter;
493     SSL3Hashes hashes;
494     SECItem signature = { siBuffer, NULL, 0 };
495     SSLHashType hashAlg;
496     SSLSignatureScheme sigScheme;
497 
498     SECItem ec_params = { siBuffer, NULL, 0 };
499     SECItem ec_point = { siBuffer, NULL, 0 };
500     unsigned char paramBuf[3];
501     const sslNamedGroupDef *ecGroup;
502 
503     isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
504 
505     ec_params.len = sizeof paramBuf;
506     ec_params.data = paramBuf;
507     rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length);
508     if (rv != SECSuccess) {
509         goto loser; /* malformed. */
510     }
511 
512     /* Fail if the curve is not a named curve */
513     if (ec_params.data[0] != ec_type_named) {
514         errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
515         desc = handshake_failure;
516         goto alert_loser;
517     }
518     ecGroup = ssl_LookupNamedGroup(ec_params.data[1] << 8 | ec_params.data[2]);
519     if (!ecGroup || ecGroup->keaType != ssl_kea_ecdh) {
520         errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
521         desc = handshake_failure;
522         goto alert_loser;
523     }
524 
525     rv = ssl3_ConsumeHandshakeVariable(ss, &ec_point, 1, &b, &length);
526     if (rv != SECSuccess) {
527         goto loser; /* malformed. */
528     }
529 
530     /* Fail if the provided point has length 0. */
531     if (!ec_point.len) {
532         /* desc and errCode are initialized already */
533         goto alert_loser;
534     }
535 
536     /* Fail if the ec point is not uncompressed for any curve that's not 25519. */
537     if (ecGroup->name != ssl_grp_ec_curve25519 &&
538         ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
539         errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM;
540         desc = handshake_failure;
541         goto alert_loser;
542     }
543 
544     PORT_Assert(ss->ssl3.prSpec->version <= SSL_LIBRARY_VERSION_TLS_1_2);
545     if (ss->ssl3.prSpec->version == SSL_LIBRARY_VERSION_TLS_1_2) {
546         rv = ssl_ConsumeSignatureScheme(ss, &b, &length, &sigScheme);
547         if (rv != SECSuccess) {
548             errCode = PORT_GetError();
549             goto alert_loser; /* malformed or unsupported. */
550         }
551         rv = ssl_CheckSignatureSchemeConsistency(
552             ss, sigScheme, &ss->sec.peerCert->subjectPublicKeyInfo);
553         if (rv != SECSuccess) {
554             errCode = PORT_GetError();
555             goto alert_loser;
556         }
557         hashAlg = ssl_SignatureSchemeToHashType(sigScheme);
558     } else {
559         /* Use ssl_hash_none to represent the MD5+SHA1 combo. */
560         hashAlg = ssl_hash_none;
561         sigScheme = ssl_sig_none;
562     }
563 
564     rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
565     if (rv != SECSuccess) {
566         goto loser; /* malformed. */
567     }
568 
569     if (length != 0) {
570         if (isTLS)
571             desc = decode_error;
572         goto alert_loser; /* malformed. */
573     }
574 
575     PRINT_BUF(60, (NULL, "Server EC params", ec_params.data, ec_params.len));
576     PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.len));
577 
578     /* failures after this point are not malformed handshakes. */
579     /* TLS: send decrypt_error if signature failed. */
580     desc = isTLS ? decrypt_error : handshake_failure;
581 
582     /*
583      *  check to make sure the hash is signed by right guy
584      */
585     rv = ssl3_ComputeECDHKeyHash(hashAlg, ec_params, ec_point,
586                                  ss->ssl3.hs.client_random,
587                                  ss->ssl3.hs.server_random,
588                                  &hashes);
589 
590     if (rv != SECSuccess) {
591         errCode =
592             ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
593         goto alert_loser;
594     }
595     rv = ssl3_VerifySignedHashes(ss, sigScheme, &hashes, &signature);
596     if (rv != SECSuccess) {
597         errCode =
598             ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
599         goto alert_loser;
600     }
601 
602     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
603     if (arena == NULL) {
604         errCode = SEC_ERROR_NO_MEMORY;
605         goto loser;
606     }
607 
608     peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
609     if (peerKey == NULL) {
610         errCode = SEC_ERROR_NO_MEMORY;
611         goto loser;
612     }
613     peerKey->arena = arena;
614 
615     /* create public key from point data */
616     rv = ssl_ImportECDHKeyShare(peerKey, ec_point.data, ec_point.len,
617                                 ecGroup);
618     if (rv != SECSuccess) {
619         /* error code is set */
620         desc = handshake_failure;
621         errCode = PORT_GetError();
622         goto alert_loser;
623     }
624     peerKey->pkcs11Slot = NULL;
625     peerKey->pkcs11ID = CK_INVALID_HANDLE;
626 
627     ss->sec.peerKey = peerKey;
628     return SECSuccess;
629 
630 alert_loser:
631     (void)SSL3_SendAlert(ss, alert_fatal, desc);
632 loser:
633     if (arena) {
634         PORT_FreeArena(arena, PR_FALSE);
635     }
636     PORT_SetError(errCode);
637     return SECFailure;
638 }
639 
640 SECStatus
ssl3_SendECDHServerKeyExchange(sslSocket * ss)641 ssl3_SendECDHServerKeyExchange(sslSocket *ss)
642 {
643     SECStatus rv = SECFailure;
644     int length;
645     PRBool isTLS12;
646     SECItem signed_hash = { siBuffer, NULL, 0 };
647     SSLHashType hashAlg;
648     SSL3Hashes hashes;
649 
650     SECItem ec_params = { siBuffer, NULL, 0 };
651     unsigned char paramBuf[3];
652     const sslNamedGroupDef *ecGroup;
653     sslEphemeralKeyPair *keyPair;
654     SECKEYPublicKey *pubKey;
655 
656     /* Generate ephemeral ECDH key pair and send the public key */
657     ecGroup = ssl_GetECGroupForServerSocket(ss);
658     if (!ecGroup) {
659         goto loser;
660     }
661 
662     PORT_Assert(PR_CLIST_IS_EMPTY(&ss->ephemeralKeyPairs));
663     if (ss->opt.reuseServerECDHEKey) {
664         rv = ssl_CreateStaticECDHEKey(ss, ecGroup);
665         if (rv != SECSuccess) {
666             goto loser;
667         }
668         keyPair = (sslEphemeralKeyPair *)PR_NEXT_LINK(&ss->ephemeralKeyPairs);
669     } else {
670         rv = ssl_CreateECDHEphemeralKeyPair(ss, ecGroup, &keyPair);
671         if (rv != SECSuccess) {
672             goto loser;
673         }
674         PR_APPEND_LINK(&keyPair->link, &ss->ephemeralKeyPairs);
675     }
676 
677     PORT_Assert(keyPair);
678     if (!keyPair) {
679         PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
680         return SECFailure;
681     }
682 
683     ec_params.len = sizeof(paramBuf);
684     ec_params.data = paramBuf;
685     PORT_Assert(keyPair->group);
686     PORT_Assert(keyPair->group->keaType == ssl_kea_ecdh);
687     ec_params.data[0] = ec_type_named;
688     ec_params.data[1] = keyPair->group->name >> 8;
689     ec_params.data[2] = keyPair->group->name & 0xff;
690 
691     pubKey = keyPair->keys->pubKey;
692     if (ss->version == SSL_LIBRARY_VERSION_TLS_1_2) {
693         hashAlg = ssl_SignatureSchemeToHashType(ss->ssl3.hs.signatureScheme);
694     } else {
695         /* Use ssl_hash_none to represent the MD5+SHA1 combo. */
696         hashAlg = ssl_hash_none;
697     }
698     rv = ssl3_ComputeECDHKeyHash(hashAlg, ec_params,
699                                  pubKey->u.ec.publicValue,
700                                  ss->ssl3.hs.client_random,
701                                  ss->ssl3.hs.server_random,
702                                  &hashes);
703     if (rv != SECSuccess) {
704         ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
705         goto loser;
706     }
707 
708     isTLS12 = (PRBool)(ss->version >= SSL_LIBRARY_VERSION_TLS_1_2);
709 
710     rv = ssl3_SignHashes(ss, &hashes,
711                          ss->sec.serverCert->serverKeyPair->privKey, &signed_hash);
712     if (rv != SECSuccess) {
713         goto loser; /* ssl3_SignHashes has set err. */
714     }
715 
716     length = ec_params.len +
717              1 + pubKey->u.ec.publicValue.len +
718              (isTLS12 ? 2 : 0) + 2 + signed_hash.len;
719 
720     rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_server_key_exchange, length);
721     if (rv != SECSuccess) {
722         goto loser; /* err set by AppendHandshake. */
723     }
724 
725     rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len);
726     if (rv != SECSuccess) {
727         goto loser; /* err set by AppendHandshake. */
728     }
729 
730     rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.ec.publicValue.data,
731                                       pubKey->u.ec.publicValue.len, 1);
732     if (rv != SECSuccess) {
733         goto loser; /* err set by AppendHandshake. */
734     }
735 
736     if (isTLS12) {
737         rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.signatureScheme, 2);
738         if (rv != SECSuccess) {
739             goto loser; /* err set by AppendHandshake. */
740         }
741     }
742 
743     rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
744                                       signed_hash.len, 2);
745     if (rv != SECSuccess) {
746         goto loser; /* err set by AppendHandshake. */
747     }
748 
749     PORT_Free(signed_hash.data);
750     return SECSuccess;
751 
752 loser:
753     if (signed_hash.data != NULL)
754         PORT_Free(signed_hash.data);
755     return SECFailure;
756 }
757 
758 /* List of all ECC cipher suites */
759 static const ssl3CipherSuite ssl_all_ec_suites[] = {
760     TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
761     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
762     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
763     TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
764     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
765     TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
766     TLS_ECDHE_ECDSA_WITH_NULL_SHA,
767     TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
768     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
769     TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
770     TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
771     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
772     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
773     TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
774     TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
775     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
776     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
777     TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
778     TLS_ECDHE_RSA_WITH_NULL_SHA,
779     TLS_ECDHE_RSA_WITH_RC4_128_SHA,
780     TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
781     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
782     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
783     TLS_ECDH_ECDSA_WITH_NULL_SHA,
784     TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
785     TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
786     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
787     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
788     TLS_ECDH_RSA_WITH_NULL_SHA,
789     TLS_ECDH_RSA_WITH_RC4_128_SHA,
790     0 /* end of list marker */
791 };
792 
793 static const ssl3CipherSuite ssl_dhe_suites[] = {
794     TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
795     TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
796     TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
797     TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
798     TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
799     TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
800     TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
801     TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
802     TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
803     TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
804     TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
805     TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
806     TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
807     TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
808     TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
809     TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
810     TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
811     TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
812     TLS_DHE_DSS_WITH_RC4_128_SHA,
813     TLS_DHE_RSA_WITH_DES_CBC_SHA,
814     TLS_DHE_DSS_WITH_DES_CBC_SHA,
815     0
816 };
817 
818 /* Order(N^2).  Yuk. */
819 static PRBool
ssl_IsSuiteEnabled(const sslSocket * ss,const ssl3CipherSuite * list)820 ssl_IsSuiteEnabled(const sslSocket *ss, const ssl3CipherSuite *list)
821 {
822     const ssl3CipherSuite *suite;
823 
824     for (suite = list; *suite; ++suite) {
825         PRBool enabled = PR_FALSE;
826         SECStatus rv = ssl3_CipherPrefGet(ss, *suite, &enabled);
827 
828         PORT_Assert(rv == SECSuccess); /* else is coding error */
829         if (rv == SECSuccess && enabled)
830             return PR_TRUE;
831     }
832     return PR_FALSE;
833 }
834 
835 /* Ask: is ANY ECC cipher suite enabled on this socket? */
836 PRBool
ssl_IsECCEnabled(const sslSocket * ss)837 ssl_IsECCEnabled(const sslSocket *ss)
838 {
839     PK11SlotInfo *slot;
840 
841     /* make sure we can do ECC */
842     slot = PK11_GetBestSlot(CKM_ECDH1_DERIVE, ss->pkcs11PinArg);
843     if (!slot) {
844         return PR_FALSE;
845     }
846     PK11_FreeSlot(slot);
847 
848     /* make sure an ECC cipher is enabled */
849     return ssl_IsSuiteEnabled(ss, ssl_all_ec_suites);
850 }
851 
852 PRBool
ssl_IsDHEEnabled(const sslSocket * ss)853 ssl_IsDHEEnabled(const sslSocket *ss)
854 {
855     return ssl_IsSuiteEnabled(ss, ssl_dhe_suites);
856 }
857 
858 /* Send our Supported Groups extension. */
859 SECStatus
ssl_SendSupportedGroupsXtn(const sslSocket * ss,TLSExtensionData * xtnData,sslBuffer * buf,PRBool * added)860 ssl_SendSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
861                            sslBuffer *buf, PRBool *added)
862 {
863     unsigned int i;
864     PRBool ec;
865     PRBool ff = PR_FALSE;
866     PRBool found = PR_FALSE;
867     SECStatus rv;
868     unsigned int lengthOffset;
869 
870     /* We only send FF supported groups if we require DH named groups
871      * or if TLS 1.3 is a possibility. */
872     if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) {
873         ec = ssl_IsECCEnabled(ss);
874         if (ss->opt.requireDHENamedGroups) {
875             ff = ssl_IsDHEEnabled(ss);
876         }
877         if (!ec && !ff) {
878             return SECSuccess;
879         }
880     } else {
881         ec = ff = PR_TRUE;
882     }
883 
884     /* Mark the location of the length. */
885     rv = sslBuffer_Skip(buf, 2, &lengthOffset);
886     if (rv != SECSuccess) {
887         return SECFailure;
888     }
889 
890     for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
891         const sslNamedGroupDef *group = ss->namedGroupPreferences[i];
892         if (!group) {
893             continue;
894         }
895         if (group->keaType == ssl_kea_ecdh && !ec) {
896             continue;
897         }
898         if (group->keaType == ssl_kea_dh && !ff) {
899             continue;
900         }
901 
902         found = PR_TRUE;
903         rv = sslBuffer_AppendNumber(buf, group->name, 2);
904         if (rv != SECSuccess) {
905             return SECFailure;
906         }
907     }
908 
909     if (!found) {
910         /* We added nothing, don't send the extension. */
911         return SECSuccess;
912     }
913 
914     rv = sslBuffer_InsertLength(buf, lengthOffset, 2);
915     if (rv != SECSuccess) {
916         return SECFailure;
917     }
918 
919     *added = PR_TRUE;
920     return SECSuccess;
921 }
922 
923 /* Send our "canned" (precompiled) Supported Point Formats extension,
924  * which says that we only support uncompressed points.
925  */
926 SECStatus
ssl3_SendSupportedPointFormatsXtn(const sslSocket * ss,TLSExtensionData * xtnData,sslBuffer * buf,PRBool * added)927 ssl3_SendSupportedPointFormatsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
928                                   sslBuffer *buf, PRBool *added)
929 {
930     SECStatus rv;
931 
932     /* No point in doing this unless we have a socket that supports ECC.
933      * Similarly, no point if we are going to do TLS 1.3 only or we have already
934      * picked TLS 1.3 (server) given that it doesn't use point formats. */
935     if (!ss || !ssl_IsECCEnabled(ss) ||
936         ss->vrange.min >= SSL_LIBRARY_VERSION_TLS_1_3 ||
937         (ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3)) {
938         return SECSuccess;
939     }
940     rv = sslBuffer_AppendNumber(buf, 1, 1); /* length */
941     if (rv != SECSuccess) {
942         return SECFailure;
943     }
944     rv = sslBuffer_AppendNumber(buf, 0, 1); /* uncompressed type only */
945     if (rv != SECSuccess) {
946         return SECFailure;
947     }
948 
949     *added = PR_TRUE;
950     return SECSuccess;
951 }
952