1/*
2 * SSL3 Protocol
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7
8/* ECC code moved here from ssl3con.c */
9
10#include "nss.h"
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 "prtime.h"
22#include "prinrval.h"
23#include "prerror.h"
24#include "pratom.h"
25#include "prthread.h"
26#include "prinit.h"
27
28#include "pk11func.h"
29#include "secmod.h"
30
31#include <stdio.h>
32
33/* This is a bodge to allow this code to be compiled against older NSS headers
34 * that don't contain the TLS 1.2 changes. */
35#ifndef CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256
36#define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24)
37#endif
38
39#ifdef NSS_ENABLE_ECC
40
41/*
42 * In NSS 3.13.2 the definition of the EC_POINT_FORM_UNCOMPRESSED macro
43 * was moved from the internal header ec.h to the public header blapit.h.
44 * Define the macro here when compiling against older system NSS headers.
45 */
46#ifndef EC_POINT_FORM_UNCOMPRESSED
47#define EC_POINT_FORM_UNCOMPRESSED 0x04
48#endif
49
50#ifndef PK11_SETATTRS
51#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
52		(x)->pValue=(v); (x)->ulValueLen = (l);
53#endif
54
55#define SSL_GET_SERVER_PUBLIC_KEY(sock, type) \
56    (ss->serverCerts[type].serverKeyPair ? \
57    ss->serverCerts[type].serverKeyPair->pubKey : NULL)
58
59#define SSL_IS_CURVE_NEGOTIATED(curvemsk, curveName) \
60    ((curveName > ec_noName) && \
61     (curveName < ec_pastLastName) && \
62     ((1UL << curveName) & curvemsk) != 0)
63
64
65
66static SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve);
67
68#define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName))
69
70/* Table containing OID tags for elliptic curves named in the
71 * ECC-TLS IETF draft.
72 */
73static const SECOidTag ecName2OIDTag[] = {
74	0,
75	SEC_OID_SECG_EC_SECT163K1,  /*  1 */
76	SEC_OID_SECG_EC_SECT163R1,  /*  2 */
77	SEC_OID_SECG_EC_SECT163R2,  /*  3 */
78	SEC_OID_SECG_EC_SECT193R1,  /*  4 */
79	SEC_OID_SECG_EC_SECT193R2,  /*  5 */
80	SEC_OID_SECG_EC_SECT233K1,  /*  6 */
81	SEC_OID_SECG_EC_SECT233R1,  /*  7 */
82	SEC_OID_SECG_EC_SECT239K1,  /*  8 */
83	SEC_OID_SECG_EC_SECT283K1,  /*  9 */
84	SEC_OID_SECG_EC_SECT283R1,  /* 10 */
85	SEC_OID_SECG_EC_SECT409K1,  /* 11 */
86	SEC_OID_SECG_EC_SECT409R1,  /* 12 */
87	SEC_OID_SECG_EC_SECT571K1,  /* 13 */
88	SEC_OID_SECG_EC_SECT571R1,  /* 14 */
89	SEC_OID_SECG_EC_SECP160K1,  /* 15 */
90	SEC_OID_SECG_EC_SECP160R1,  /* 16 */
91	SEC_OID_SECG_EC_SECP160R2,  /* 17 */
92	SEC_OID_SECG_EC_SECP192K1,  /* 18 */
93	SEC_OID_SECG_EC_SECP192R1,  /* 19 */
94	SEC_OID_SECG_EC_SECP224K1,  /* 20 */
95	SEC_OID_SECG_EC_SECP224R1,  /* 21 */
96	SEC_OID_SECG_EC_SECP256K1,  /* 22 */
97	SEC_OID_SECG_EC_SECP256R1,  /* 23 */
98	SEC_OID_SECG_EC_SECP384R1,  /* 24 */
99	SEC_OID_SECG_EC_SECP521R1,  /* 25 */
100};
101
102static const PRUint16 curve2bits[] = {
103	  0, /*  ec_noName     = 0,   */
104	163, /*  ec_sect163k1  = 1,   */
105	163, /*  ec_sect163r1  = 2,   */
106	163, /*  ec_sect163r2  = 3,   */
107	193, /*  ec_sect193r1  = 4,   */
108	193, /*  ec_sect193r2  = 5,   */
109	233, /*  ec_sect233k1  = 6,   */
110	233, /*  ec_sect233r1  = 7,   */
111	239, /*  ec_sect239k1  = 8,   */
112	283, /*  ec_sect283k1  = 9,   */
113	283, /*  ec_sect283r1  = 10,  */
114	409, /*  ec_sect409k1  = 11,  */
115	409, /*  ec_sect409r1  = 12,  */
116	571, /*  ec_sect571k1  = 13,  */
117	571, /*  ec_sect571r1  = 14,  */
118	160, /*  ec_secp160k1  = 15,  */
119	160, /*  ec_secp160r1  = 16,  */
120	160, /*  ec_secp160r2  = 17,  */
121	192, /*  ec_secp192k1  = 18,  */
122	192, /*  ec_secp192r1  = 19,  */
123	224, /*  ec_secp224k1  = 20,  */
124	224, /*  ec_secp224r1  = 21,  */
125	256, /*  ec_secp256k1  = 22,  */
126	256, /*  ec_secp256r1  = 23,  */
127	384, /*  ec_secp384r1  = 24,  */
128	521, /*  ec_secp521r1  = 25,  */
129      65535  /*  ec_pastLastName      */
130};
131
132typedef struct Bits2CurveStr {
133    PRUint16    bits;
134    ECName      curve;
135} Bits2Curve;
136
137static const Bits2Curve bits2curve [] = {
138   {	192,     ec_secp192r1    /*  = 19,  fast */  },
139   {	160,     ec_secp160r2    /*  = 17,  fast */  },
140   {	160,     ec_secp160k1    /*  = 15,  */       },
141   {	160,     ec_secp160r1    /*  = 16,  */       },
142   {	163,     ec_sect163k1    /*  = 1,   */       },
143   {	163,     ec_sect163r1    /*  = 2,   */       },
144   {	163,     ec_sect163r2    /*  = 3,   */       },
145   {	192,     ec_secp192k1    /*  = 18,  */       },
146   {	193,     ec_sect193r1    /*  = 4,   */       },
147   {	193,     ec_sect193r2    /*  = 5,   */       },
148   {	224,     ec_secp224r1    /*  = 21,  fast */  },
149   {	224,     ec_secp224k1    /*  = 20,  */       },
150   {	233,     ec_sect233k1    /*  = 6,   */       },
151   {	233,     ec_sect233r1    /*  = 7,   */       },
152   {	239,     ec_sect239k1    /*  = 8,   */       },
153   {	256,     ec_secp256r1    /*  = 23,  fast */  },
154   {	256,     ec_secp256k1    /*  = 22,  */       },
155   {	283,     ec_sect283k1    /*  = 9,   */       },
156   {	283,     ec_sect283r1    /*  = 10,  */       },
157   {	384,     ec_secp384r1    /*  = 24,  fast */  },
158   {	409,     ec_sect409k1    /*  = 11,  */       },
159   {	409,     ec_sect409r1    /*  = 12,  */       },
160   {	521,     ec_secp521r1    /*  = 25,  fast */  },
161   {	571,     ec_sect571k1    /*  = 13,  */       },
162   {	571,     ec_sect571r1    /*  = 14,  */       },
163   {  65535,     ec_noName    }
164};
165
166typedef struct ECDHEKeyPairStr {
167    ssl3KeyPair *  pair;
168    int            error;  /* error code of the call-once function */
169    PRCallOnceType once;
170} ECDHEKeyPair;
171
172/* arrays of ECDHE KeyPairs */
173static ECDHEKeyPair gECDHEKeyPairs[ec_pastLastName];
174
175SECStatus
176ssl3_ECName2Params(PLArenaPool * arena, ECName curve, SECKEYECParams * params)
177{
178    SECOidData *oidData = NULL;
179
180    if ((curve <= ec_noName) || (curve >= ec_pastLastName) ||
181	((oidData = SECOID_FindOIDByTag(ecName2OIDTag[curve])) == NULL)) {
182        PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
183	return SECFailure;
184    }
185
186    SECITEM_AllocItem(arena, params, (2 + oidData->oid.len));
187    /*
188     * params->data needs to contain the ASN encoding of an object ID (OID)
189     * representing the named curve. The actual OID is in
190     * oidData->oid.data so we simply prepend 0x06 and OID length
191     */
192    params->data[0] = SEC_ASN1_OBJECT_ID;
193    params->data[1] = oidData->oid.len;
194    memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
195
196    return SECSuccess;
197}
198
199static ECName
200params2ecName(SECKEYECParams * params)
201{
202    SECItem oid = { siBuffer, NULL, 0};
203    SECOidData *oidData = NULL;
204    ECName i;
205
206    /*
207     * params->data needs to contain the ASN encoding of an object ID (OID)
208     * representing a named curve. Here, we strip away everything
209     * before the actual OID and use the OID to look up a named curve.
210     */
211    if (params->data[0] != SEC_ASN1_OBJECT_ID) return ec_noName;
212    oid.len = params->len - 2;
213    oid.data = params->data + 2;
214    if ((oidData = SECOID_FindOID(&oid)) == NULL) return ec_noName;
215    for (i = ec_noName + 1; i < ec_pastLastName; i++) {
216	if (ecName2OIDTag[i] == oidData->offset)
217	    return i;
218    }
219
220    return ec_noName;
221}
222
223/* Caller must set hiLevel error code. */
224static SECStatus
225ssl3_ComputeECDHKeyHash(SECOidTag hashAlg,
226			SECItem ec_params, SECItem server_ecpoint,
227			SSL3Random *client_rand, SSL3Random *server_rand,
228			SSL3Hashes *hashes, PRBool bypassPKCS11)
229{
230    PRUint8     * hashBuf;
231    PRUint8     * pBuf;
232    SECStatus     rv 		= SECSuccess;
233    unsigned int  bufLen;
234    /*
235     * XXX For now, we only support named curves (the appropriate
236     * checks are made before this method is called) so ec_params
237     * takes up only two bytes. ECPoint needs to fit in 256 bytes
238     * (because the spec says the length must fit in one byte)
239     */
240    PRUint8       buf[2*SSL3_RANDOM_LENGTH + 2 + 1 + 256];
241
242    bufLen = 2*SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.len;
243    if (bufLen <= sizeof buf) {
244    	hashBuf = buf;
245    } else {
246    	hashBuf = PORT_Alloc(bufLen);
247	if (!hashBuf) {
248	    return SECFailure;
249	}
250    }
251
252    memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
253    	pBuf = hashBuf + SSL3_RANDOM_LENGTH;
254    memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
255    	pBuf += SSL3_RANDOM_LENGTH;
256    memcpy(pBuf, ec_params.data, ec_params.len);
257    	pBuf += ec_params.len;
258    pBuf[0] = (PRUint8)(server_ecpoint.len);
259    pBuf += 1;
260    memcpy(pBuf, server_ecpoint.data, server_ecpoint.len);
261    	pBuf += server_ecpoint.len;
262    PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
263
264    rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes,
265				   bypassPKCS11);
266
267    PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen));
268    PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result",
269	      hashes->u.s.md5, MD5_LENGTH));
270    PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result",
271	      hashes->u.s.sha, SHA1_LENGTH));
272
273    if (hashBuf != buf)
274    	PORT_Free(hashBuf);
275    return rv;
276}
277
278
279/* Called from ssl3_SendClientKeyExchange(). */
280SECStatus
281ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
282{
283    PK11SymKey *	pms 		= NULL;
284    SECStatus           rv    		= SECFailure;
285    PRBool              isTLS, isTLS12;
286    CK_MECHANISM_TYPE	target;
287    SECKEYPublicKey	*pubKey = NULL;		/* Ephemeral ECDH key */
288    SECKEYPrivateKey	*privKey = NULL;	/* Ephemeral ECDH key */
289
290    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
291    PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
292
293    isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
294    isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
295
296    /* Generate ephemeral EC keypair */
297    if (svrPubKey->keyType != ecKey) {
298	PORT_SetError(SEC_ERROR_BAD_KEY);
299	goto loser;
300    }
301    /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */
302    privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams,
303	                                &pubKey, ss->pkcs11PinArg);
304    if (!privKey || !pubKey) {
305	    ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
306	    rv = SECFailure;
307	    goto loser;
308    }
309    PRINT_BUF(50, (ss, "ECDH public value:",
310					pubKey->u.ec.publicValue.data,
311					pubKey->u.ec.publicValue.len));
312
313    if (isTLS12) {
314	target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256;
315    } else if (isTLS) {
316	target = CKM_TLS_MASTER_KEY_DERIVE_DH;
317    } else {
318	target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
319    }
320
321    /*  Determine the PMS */
322    pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL,
323			    CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
324			    CKD_NULL, NULL, NULL);
325
326    if (pms == NULL) {
327	SSL3AlertDescription desc  = illegal_parameter;
328	(void)SSL3_SendAlert(ss, alert_fatal, desc);
329	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
330	goto loser;
331    }
332
333    SECKEY_DestroyPrivateKey(privKey);
334    privKey = NULL;
335
336    rv = ssl3_InitPendingCipherSpec(ss,  pms);
337    PK11_FreeSymKey(pms); pms = NULL;
338
339    if (rv != SECSuccess) {
340	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
341	goto loser;
342    }
343
344    rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
345					pubKey->u.ec.publicValue.len + 1);
346    if (rv != SECSuccess) {
347        goto loser;	/* err set by ssl3_AppendHandshake* */
348    }
349
350    rv = ssl3_AppendHandshakeVariable(ss,
351					pubKey->u.ec.publicValue.data,
352					pubKey->u.ec.publicValue.len, 1);
353    SECKEY_DestroyPublicKey(pubKey);
354    pubKey = NULL;
355
356    if (rv != SECSuccess) {
357        goto loser;	/* err set by ssl3_AppendHandshake* */
358    }
359
360    rv = SECSuccess;
361
362loser:
363    if(pms) PK11_FreeSymKey(pms);
364    if(privKey) SECKEY_DestroyPrivateKey(privKey);
365    if(pubKey) SECKEY_DestroyPublicKey(pubKey);
366    return rv;
367}
368
369
370/*
371** Called from ssl3_HandleClientKeyExchange()
372*/
373SECStatus
374ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
375				     PRUint32 length,
376                                     SECKEYPublicKey *srvrPubKey,
377                                     SECKEYPrivateKey *srvrPrivKey)
378{
379    PK11SymKey *      pms;
380    SECStatus         rv;
381    SECKEYPublicKey   clntPubKey;
382    CK_MECHANISM_TYPE	target;
383    PRBool isTLS, isTLS12;
384
385    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
386    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
387
388    clntPubKey.keyType = ecKey;
389    clntPubKey.u.ec.DEREncodedParams.len =
390	srvrPubKey->u.ec.DEREncodedParams.len;
391    clntPubKey.u.ec.DEREncodedParams.data =
392	srvrPubKey->u.ec.DEREncodedParams.data;
393
394    rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue,
395	                               1, &b, &length);
396    if (rv != SECSuccess) {
397	SEND_ALERT
398	return SECFailure;	/* XXX Who sets the error code?? */
399    }
400
401    isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
402    isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
403
404    if (isTLS12) {
405	target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256;
406    } else if (isTLS) {
407	target = CKM_TLS_MASTER_KEY_DERIVE_DH;
408    } else {
409	target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
410    }
411
412    /*  Determine the PMS */
413    pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL,
414			    CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
415			    CKD_NULL, NULL, NULL);
416
417    if (pms == NULL) {
418	/* last gasp.  */
419	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
420	return SECFailure;
421    }
422
423    rv = ssl3_InitPendingCipherSpec(ss,  pms);
424    PK11_FreeSymKey(pms);
425    if (rv != SECSuccess) {
426	SEND_ALERT
427	return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
428    }
429    return SECSuccess;
430}
431
432ECName
433ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits)
434{
435    int    i;
436
437    for ( i = 0; bits2curve[i].curve != ec_noName; i++) {
438	if (bits2curve[i].bits < requiredECCbits)
439	    continue;
440    	if (SSL_IS_CURVE_NEGOTIATED(curvemsk, bits2curve[i].curve)) {
441	    return bits2curve[i].curve;
442	}
443    }
444    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
445    return ec_noName;
446}
447
448/* find the "weakest link".  Get strength of signature key and of sym key.
449 * choose curve for the weakest of those two.
450 */
451ECName
452ssl3_GetCurveNameForServerSocket(sslSocket *ss)
453{
454    SECKEYPublicKey * svrPublicKey = NULL;
455    ECName ec_curve = ec_noName;
456    int    signatureKeyStrength = 521;
457    int    requiredECCbits = ss->sec.secretKeyBits * 2;
458
459    if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa) {
460	svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_ecdh);
461	if (svrPublicKey)
462	    ec_curve = params2ecName(&svrPublicKey->u.ec.DEREncodedParams);
463	if (!SSL_IS_CURVE_NEGOTIATED(ss->ssl3.hs.negotiatedECCurves, ec_curve)) {
464	    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
465	    return ec_noName;
466	}
467	signatureKeyStrength = curve2bits[ ec_curve ];
468    } else {
469        /* RSA is our signing cert */
470        int serverKeyStrengthInBits;
471
472        svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_rsa);
473        if (!svrPublicKey) {
474            PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
475            return ec_noName;
476        }
477
478        /* currently strength in bytes */
479        serverKeyStrengthInBits = svrPublicKey->u.rsa.modulus.len;
480        if (svrPublicKey->u.rsa.modulus.data[0] == 0) {
481            serverKeyStrengthInBits--;
482        }
483        /* convert to strength in bits */
484        serverKeyStrengthInBits *= BPB;
485
486        signatureKeyStrength =
487	    SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits);
488    }
489    if ( requiredECCbits > signatureKeyStrength )
490         requiredECCbits = signatureKeyStrength;
491
492    return ssl3_GetCurveWithECKeyStrength(ss->ssl3.hs.negotiatedECCurves,
493					  requiredECCbits);
494}
495
496/* function to clear out the lists */
497static SECStatus
498ssl3_ShutdownECDHECurves(void *appData, void *nssData)
499{
500    int i;
501    ECDHEKeyPair *keyPair = &gECDHEKeyPairs[0];
502
503    for (i=0; i < ec_pastLastName; i++, keyPair++) {
504	if (keyPair->pair) {
505	    ssl3_FreeKeyPair(keyPair->pair);
506	}
507    }
508    memset(gECDHEKeyPairs, 0, sizeof gECDHEKeyPairs);
509    return SECSuccess;
510}
511
512static PRStatus
513ssl3_ECRegister(void)
514{
515    SECStatus rv;
516    rv = NSS_RegisterShutdown(ssl3_ShutdownECDHECurves, gECDHEKeyPairs);
517    if (rv != SECSuccess) {
518	gECDHEKeyPairs[ec_noName].error = PORT_GetError();
519    }
520    return (PRStatus)rv;
521}
522
523/* CallOnce function, called once for each named curve. */
524static PRStatus
525ssl3_CreateECDHEphemeralKeyPair(void * arg)
526{
527    SECKEYPrivateKey *    privKey  = NULL;
528    SECKEYPublicKey *     pubKey   = NULL;
529    ssl3KeyPair *	  keyPair  = NULL;
530    ECName                ec_curve = (ECName)arg;
531    SECKEYECParams        ecParams = { siBuffer, NULL, 0 };
532
533    PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL);
534
535    /* ok, no one has generated a global key for this curve yet, do so */
536    if (ssl3_ECName2Params(NULL, ec_curve, &ecParams) != SECSuccess) {
537	gECDHEKeyPairs[ec_curve].error = PORT_GetError();
538	return PR_FAILURE;
539    }
540
541    privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL);
542    SECITEM_FreeItem(&ecParams, PR_FALSE);
543
544    if (!privKey || !pubKey || !(keyPair = ssl3_NewKeyPair(privKey, pubKey))) {
545	if (privKey) {
546	    SECKEY_DestroyPrivateKey(privKey);
547	}
548	if (pubKey) {
549	    SECKEY_DestroyPublicKey(pubKey);
550	}
551	ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
552	gECDHEKeyPairs[ec_curve].error = PORT_GetError();
553	return PR_FAILURE;
554    }
555
556    gECDHEKeyPairs[ec_curve].pair = keyPair;
557    return PR_SUCCESS;
558}
559
560/*
561 * Creates the ephemeral public and private ECDH keys used by
562 * server in ECDHE_RSA and ECDHE_ECDSA handshakes.
563 * For now, the elliptic curve is chosen to be the same
564 * strength as the signing certificate (ECC or RSA).
565 * We need an API to specify the curve. This won't be a real
566 * issue until we further develop server-side support for ECC
567 * cipher suites.
568 */
569static SECStatus
570ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve)
571{
572    ssl3KeyPair *	  keyPair        = NULL;
573
574    /* if there's no global key for this curve, make one. */
575    if (gECDHEKeyPairs[ec_curve].pair == NULL) {
576	PRStatus status;
577
578	status = PR_CallOnce(&gECDHEKeyPairs[ec_noName].once, ssl3_ECRegister);
579        if (status != PR_SUCCESS) {
580	    PORT_SetError(gECDHEKeyPairs[ec_noName].error);
581	    return SECFailure;
582    	}
583	status = PR_CallOnceWithArg(&gECDHEKeyPairs[ec_curve].once,
584	                            ssl3_CreateECDHEphemeralKeyPair,
585				    (void *)ec_curve);
586        if (status != PR_SUCCESS) {
587	    PORT_SetError(gECDHEKeyPairs[ec_curve].error);
588	    return SECFailure;
589    	}
590    }
591
592    keyPair = gECDHEKeyPairs[ec_curve].pair;
593    PORT_Assert(keyPair != NULL);
594    if (!keyPair)
595    	return SECFailure;
596    ss->ephemeralECDHKeyPair = ssl3_GetKeyPairRef(keyPair);
597
598    return SECSuccess;
599}
600
601SECStatus
602ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
603{
604    PLArenaPool *    arena     = NULL;
605    SECKEYPublicKey *peerKey   = NULL;
606    PRBool           isTLS, isTLS12;
607    SECStatus        rv;
608    int              errCode   = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
609    SSL3AlertDescription desc  = illegal_parameter;
610    SSL3Hashes       hashes;
611    SECItem          signature = {siBuffer, NULL, 0};
612
613    SECItem          ec_params = {siBuffer, NULL, 0};
614    SECItem          ec_point  = {siBuffer, NULL, 0};
615    unsigned char    paramBuf[3]; /* only for curve_type == named_curve */
616    SSL3SignatureAndHashAlgorithm sigAndHash;
617
618    sigAndHash.hashAlg = SEC_OID_UNKNOWN;
619
620    isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
621    isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
622
623    /* XXX This works only for named curves, revisit this when
624     * we support generic curves.
625     */
626    ec_params.len  = sizeof paramBuf;
627    ec_params.data = paramBuf;
628    rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length);
629    if (rv != SECSuccess) {
630	goto loser;		/* malformed. */
631    }
632
633    /* Fail if the curve is not a named curve */
634    if ((ec_params.data[0] != ec_type_named) ||
635	(ec_params.data[1] != 0) ||
636	!supportedCurve(ec_params.data[2])) {
637	    errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
638	    desc = handshake_failure;
639	    goto alert_loser;
640    }
641
642    rv = ssl3_ConsumeHandshakeVariable(ss, &ec_point, 1, &b, &length);
643    if (rv != SECSuccess) {
644	goto loser;		/* malformed. */
645    }
646    /* Fail if the ec point uses compressed representation */
647    if (ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
648	    errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM;
649	    desc = handshake_failure;
650	    goto alert_loser;
651    }
652
653    if (isTLS12) {
654	rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length,
655						   &sigAndHash);
656	if (rv != SECSuccess) {
657	    goto loser;		/* malformed or unsupported. */
658	}
659	rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(
660		&sigAndHash, ss->sec.peerCert);
661	if (rv != SECSuccess) {
662	    goto loser;
663	}
664    }
665
666    rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
667    if (rv != SECSuccess) {
668	goto loser;		/* malformed. */
669    }
670
671    if (length != 0) {
672	if (isTLS)
673	    desc = decode_error;
674	goto alert_loser;		/* malformed. */
675    }
676
677    PRINT_BUF(60, (NULL, "Server EC params", ec_params.data,
678	ec_params.len));
679    PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.len));
680
681    /* failures after this point are not malformed handshakes. */
682    /* TLS: send decrypt_error if signature failed. */
683    desc = isTLS ? decrypt_error : handshake_failure;
684
685    /*
686     *  check to make sure the hash is signed by right guy
687     */
688    rv = ssl3_ComputeECDHKeyHash(sigAndHash.hashAlg, ec_params, ec_point,
689				 &ss->ssl3.hs.client_random,
690				 &ss->ssl3.hs.server_random,
691				 &hashes, ss->opt.bypassPKCS11);
692
693    if (rv != SECSuccess) {
694	errCode =
695	    ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
696	goto alert_loser;
697    }
698    rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
699				isTLS, ss->pkcs11PinArg);
700    if (rv != SECSuccess)  {
701	errCode =
702	    ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
703	goto alert_loser;
704    }
705
706    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
707    if (arena == NULL) {
708	goto no_memory;
709    }
710
711    ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
712    if (peerKey == NULL) {
713	goto no_memory;
714    }
715
716    peerKey->arena                 = arena;
717    peerKey->keyType               = ecKey;
718
719    /* set up EC parameters in peerKey */
720    if (ssl3_ECName2Params(arena, ec_params.data[2],
721	    &peerKey->u.ec.DEREncodedParams) != SECSuccess) {
722	/* we should never get here since we already
723	 * checked that we are dealing with a supported curve
724	 */
725	errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
726	goto alert_loser;
727    }
728
729    /* copy publicValue in peerKey */
730    if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue,  &ec_point))
731    {
732	PORT_FreeArena(arena, PR_FALSE);
733	goto no_memory;
734    }
735    peerKey->pkcs11Slot         = NULL;
736    peerKey->pkcs11ID           = CK_INVALID_HANDLE;
737
738    ss->sec.peerKey = peerKey;
739    ss->ssl3.hs.ws = wait_cert_request;
740
741    return SECSuccess;
742
743alert_loser:
744    (void)SSL3_SendAlert(ss, alert_fatal, desc);
745loser:
746    PORT_SetError( errCode );
747    return SECFailure;
748
749no_memory:	/* no-memory error has already been set. */
750    ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
751    return SECFailure;
752}
753
754SECStatus
755ssl3_SendECDHServerKeyExchange(
756    sslSocket *ss,
757    const SSL3SignatureAndHashAlgorithm *sigAndHash)
758{
759    const ssl3KEADef * kea_def     = ss->ssl3.hs.kea_def;
760    SECStatus          rv          = SECFailure;
761    int                length;
762    PRBool             isTLS, isTLS12;
763    SECItem            signed_hash = {siBuffer, NULL, 0};
764    SSL3Hashes         hashes;
765
766    SECKEYPublicKey *  ecdhePub;
767    SECItem            ec_params = {siBuffer, NULL, 0};
768    unsigned char      paramBuf[3];
769    ECName             curve;
770    SSL3KEAType        certIndex;
771
772    /* Generate ephemeral ECDH key pair and send the public key */
773    curve = ssl3_GetCurveNameForServerSocket(ss);
774    if (curve == ec_noName) {
775    	goto loser;
776    }
777    rv = ssl3_CreateECDHEphemeralKeys(ss, curve);
778    if (rv != SECSuccess) {
779	goto loser; 	/* err set by AppendHandshake. */
780    }
781    ecdhePub = ss->ephemeralECDHKeyPair->pubKey;
782    PORT_Assert(ecdhePub != NULL);
783    if (!ecdhePub) {
784	PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
785	return SECFailure;
786    }
787
788    ec_params.len  = sizeof paramBuf;
789    ec_params.data = paramBuf;
790    curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams);
791    if (curve != ec_noName) {
792	ec_params.data[0] = ec_type_named;
793	ec_params.data[1] = 0x00;
794	ec_params.data[2] = curve;
795    } else {
796	PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
797	goto loser;
798    }
799
800    rv = ssl3_ComputeECDHKeyHash(sigAndHash->hashAlg,
801				 ec_params,
802				 ecdhePub->u.ec.publicValue,
803				 &ss->ssl3.hs.client_random,
804				 &ss->ssl3.hs.server_random,
805				 &hashes, ss->opt.bypassPKCS11);
806    if (rv != SECSuccess) {
807	ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
808	goto loser;
809    }
810
811    isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
812    isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
813
814    /* XXX SSLKEAType isn't really a good choice for
815     * indexing certificates but that's all we have
816     * for now.
817     */
818    if (kea_def->kea == kea_ecdhe_rsa)
819	certIndex = kt_rsa;
820    else /* kea_def->kea == kea_ecdhe_ecdsa */
821	certIndex = kt_ecdh;
822
823    rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY,
824			 &signed_hash, isTLS);
825    if (rv != SECSuccess) {
826	goto loser;		/* ssl3_SignHashes has set err. */
827    }
828    if (signed_hash.data == NULL) {
829	/* how can this happen and rv == SECSuccess ?? */
830	PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
831	goto loser;
832    }
833
834    length = ec_params.len +
835	     1 + ecdhePub->u.ec.publicValue.len +
836	     (isTLS12 ? 2 : 0) + 2 + signed_hash.len;
837
838    rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
839    if (rv != SECSuccess) {
840	goto loser; 	/* err set by AppendHandshake. */
841    }
842
843    rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len);
844    if (rv != SECSuccess) {
845	goto loser; 	/* err set by AppendHandshake. */
846    }
847
848    rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data,
849				      ecdhePub->u.ec.publicValue.len, 1);
850    if (rv != SECSuccess) {
851	goto loser; 	/* err set by AppendHandshake. */
852    }
853
854    if (isTLS12) {
855	rv = ssl3_AppendSignatureAndHashAlgorithm(ss, sigAndHash);
856	if (rv != SECSuccess) {
857	    goto loser; 	/* err set by AppendHandshake. */
858	}
859    }
860
861    rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
862				      signed_hash.len, 2);
863    if (rv != SECSuccess) {
864	goto loser; 	/* err set by AppendHandshake. */
865    }
866
867    PORT_Free(signed_hash.data);
868    return SECSuccess;
869
870loser:
871    if (signed_hash.data != NULL)
872    	PORT_Free(signed_hash.data);
873    return SECFailure;
874}
875
876/* Lists of ECC cipher suites for searching and disabling. */
877
878static const ssl3CipherSuite ecdh_suites[] = {
879    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
880    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
881    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
882    TLS_ECDH_ECDSA_WITH_NULL_SHA,
883    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
884    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
885    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
886    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
887    TLS_ECDH_RSA_WITH_NULL_SHA,
888    TLS_ECDH_RSA_WITH_RC4_128_SHA,
889    0 /* end of list marker */
890};
891
892static const ssl3CipherSuite ecdh_ecdsa_suites[] = {
893    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
894    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
895    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
896    TLS_ECDH_ECDSA_WITH_NULL_SHA,
897    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
898    0 /* end of list marker */
899};
900
901static const ssl3CipherSuite ecdh_rsa_suites[] = {
902    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
903    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
904    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
905    TLS_ECDH_RSA_WITH_NULL_SHA,
906    TLS_ECDH_RSA_WITH_RC4_128_SHA,
907    0 /* end of list marker */
908};
909
910static const ssl3CipherSuite ecdhe_ecdsa_suites[] = {
911    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
912    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
913    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
914    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
915    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
916    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
917    TLS_ECDHE_ECDSA_WITH_NULL_SHA,
918    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
919    0 /* end of list marker */
920};
921
922static const ssl3CipherSuite ecdhe_rsa_suites[] = {
923    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
924    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
925    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
926    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
927    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
928    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
929    TLS_ECDHE_RSA_WITH_NULL_SHA,
930    TLS_ECDHE_RSA_WITH_RC4_128_SHA,
931    0 /* end of list marker */
932};
933
934/* List of all ECC cipher suites */
935static const ssl3CipherSuite ecSuites[] = {
936    TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
937    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
938    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
939    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
940    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
941    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
942    TLS_ECDHE_ECDSA_WITH_NULL_SHA,
943    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
944    TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
945    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
946    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
947    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
948    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
949    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
950    TLS_ECDHE_RSA_WITH_NULL_SHA,
951    TLS_ECDHE_RSA_WITH_RC4_128_SHA,
952    TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
953    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
954    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
955    TLS_ECDH_ECDSA_WITH_NULL_SHA,
956    TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
957    TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
958    TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
959    TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
960    TLS_ECDH_RSA_WITH_NULL_SHA,
961    TLS_ECDH_RSA_WITH_RC4_128_SHA,
962    0 /* end of list marker */
963};
964
965/* On this socket, Disable the ECC cipher suites in the argument's list */
966SECStatus
967ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite)
968{
969    if (!suite)
970    	suite = ecSuites;
971    for (; *suite; ++suite) {
972	SECStatus rv      = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
973
974	PORT_Assert(rv == SECSuccess); /* else is coding error */
975    }
976    return SECSuccess;
977}
978
979/* Look at the server certs configured on this socket, and disable any
980 * ECC cipher suites that are not supported by those certs.
981 */
982void
983ssl3_FilterECCipherSuitesByServerCerts(sslSocket * ss)
984{
985    CERTCertificate * svrCert;
986
987    svrCert = ss->serverCerts[kt_rsa].serverCert;
988    if (!svrCert) {
989	ssl3_DisableECCSuites(ss, ecdhe_rsa_suites);
990    }
991
992    svrCert = ss->serverCerts[kt_ecdh].serverCert;
993    if (!svrCert) {
994	ssl3_DisableECCSuites(ss, ecdh_suites);
995	ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites);
996    } else {
997	SECOidTag sigTag = SECOID_GetAlgorithmTag(&svrCert->signature);
998
999	switch (sigTag) {
1000	case SEC_OID_PKCS1_RSA_ENCRYPTION:
1001	case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
1002	case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
1003	case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
1004	case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
1005	case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
1006	case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
1007	case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
1008	case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
1009	    ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
1010	    break;
1011	case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
1012	case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
1013	case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
1014	case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
1015	case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
1016	case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
1017	case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
1018	    ssl3_DisableECCSuites(ss, ecdh_rsa_suites);
1019	    break;
1020	default:
1021	    ssl3_DisableECCSuites(ss, ecdh_suites);
1022	    break;
1023	}
1024    }
1025}
1026
1027/* Ask: is ANY ECC cipher suite enabled on this socket? */
1028/* Order(N^2).  Yuk.  Also, this ignores export policy. */
1029PRBool
1030ssl3_IsECCEnabled(sslSocket * ss)
1031{
1032    const ssl3CipherSuite * suite;
1033    PK11SlotInfo *slot;
1034
1035    /* make sure we can do ECC */
1036    slot = PK11_GetBestSlot(CKM_ECDH1_DERIVE,  ss->pkcs11PinArg);
1037    if (!slot) {
1038	return PR_FALSE;
1039    }
1040    PK11_FreeSlot(slot);
1041
1042    /* make sure an ECC cipher is enabled */
1043    for (suite = ecSuites; *suite; ++suite) {
1044	PRBool    enabled = PR_FALSE;
1045	SECStatus rv      = ssl3_CipherPrefGet(ss, *suite, &enabled);
1046
1047	PORT_Assert(rv == SECSuccess); /* else is coding error */
1048	if (rv == SECSuccess && enabled)
1049	    return PR_TRUE;
1050    }
1051    return PR_FALSE;
1052}
1053
1054#define BE(n) 0, n
1055
1056/* Prefabricated TLS client hello extension, Elliptic Curves List,
1057 * offers only 3 curves, the Suite B curves, 23-25
1058 */
1059static const PRUint8 suiteBECList[12] = {
1060    BE(10),         /* Extension type */
1061    BE( 8),         /* octets that follow ( 3 pairs + 1 length pair) */
1062    BE( 6),         /* octets that follow ( 3 pairs) */
1063    BE(23), BE(24), BE(25)
1064};
1065
1066/* Prefabricated TLS client hello extension, Elliptic Curves List,
1067 * offers curves 1-25.
1068 */
1069static const PRUint8 tlsECList[56] = {
1070    BE(10),         /* Extension type */
1071    BE(52),         /* octets that follow (25 pairs + 1 length pair) */
1072    BE(50),         /* octets that follow (25 pairs) */
1073            BE( 1), BE( 2), BE( 3), BE( 4), BE( 5), BE( 6), BE( 7),
1074    BE( 8), BE( 9), BE(10), BE(11), BE(12), BE(13), BE(14), BE(15),
1075    BE(16), BE(17), BE(18), BE(19), BE(20), BE(21), BE(22), BE(23),
1076    BE(24), BE(25)
1077};
1078
1079static const PRUint8 ecPtFmt[6] = {
1080    BE(11),         /* Extension type */
1081    BE( 2),         /* octets that follow */
1082             1,     /* octets that follow */
1083                 0  /* uncompressed type only */
1084};
1085
1086/* This function already presumes we can do ECC, ssl3_IsECCEnabled must be
1087 * called before this function. It looks to see if we have a token which
1088 * is capable of doing smaller than SuiteB curves. If the token can, we
1089 * presume the token can do the whole SSL suite of curves. If it can't we
1090 * presume the token that allowed ECC to be enabled can only do suite B
1091 * curves. */
1092static PRBool
1093ssl3_SuiteBOnly(sslSocket *ss)
1094{
1095#if 0
1096    /* See if we can support small curves (like 163). If not, assume we can
1097     * only support Suite-B curves (P-256, P-384, P-521). */
1098    PK11SlotInfo *slot =
1099	PK11_GetBestSlotWithAttributes(CKM_ECDH1_DERIVE, 0, 163,
1100				       ss ? ss->pkcs11PinArg : NULL);
1101
1102    if (!slot) {
1103	/* nope, presume we can only do suite B */
1104	return PR_TRUE;
1105    }
1106    /* we can, presume we can do all curves */
1107    PK11_FreeSlot(slot);
1108    return PR_FALSE;
1109#else
1110    return PR_TRUE;
1111#endif
1112}
1113
1114/* Send our "canned" (precompiled) Supported Elliptic Curves extension,
1115 * which says that we support all TLS-defined named curves.
1116 */
1117PRInt32
1118ssl3_SendSupportedCurvesXtn(
1119			sslSocket * ss,
1120			PRBool      append,
1121			PRUint32    maxBytes)
1122{
1123    PRInt32 ecListSize = 0;
1124    const PRUint8 *ecList = NULL;
1125
1126    if (!ss || !ssl3_IsECCEnabled(ss))
1127    	return 0;
1128
1129    if (ssl3_SuiteBOnly(ss)) {
1130	ecListSize = sizeof suiteBECList;
1131	ecList = suiteBECList;
1132    } else {
1133	ecListSize = sizeof tlsECList;
1134	ecList = tlsECList;
1135    }
1136
1137    if (append && maxBytes >= ecListSize) {
1138	SECStatus rv = ssl3_AppendHandshake(ss, ecList, ecListSize);
1139	if (rv != SECSuccess)
1140	    return -1;
1141	if (!ss->sec.isServer) {
1142	    TLSExtensionData *xtnData = &ss->xtnData;
1143	    xtnData->advertised[xtnData->numAdvertised++] =
1144		ssl_elliptic_curves_xtn;
1145	}
1146    }
1147    return ecListSize;
1148}
1149
1150PRUint32
1151ssl3_GetSupportedECCurveMask(sslSocket *ss)
1152{
1153    if (ssl3_SuiteBOnly(ss)) {
1154	return SSL3_SUITE_B_SUPPORTED_CURVES_MASK;
1155    }
1156    return SSL3_ALL_SUPPORTED_CURVES_MASK;
1157}
1158
1159/* Send our "canned" (precompiled) Supported Point Formats extension,
1160 * which says that we only support uncompressed points.
1161 */
1162PRInt32
1163ssl3_SendSupportedPointFormatsXtn(
1164			sslSocket * ss,
1165			PRBool      append,
1166			PRUint32    maxBytes)
1167{
1168    if (!ss || !ssl3_IsECCEnabled(ss))
1169    	return 0;
1170    if (append && maxBytes >= (sizeof ecPtFmt)) {
1171	SECStatus rv = ssl3_AppendHandshake(ss, ecPtFmt, (sizeof ecPtFmt));
1172	if (rv != SECSuccess)
1173	    return -1;
1174	if (!ss->sec.isServer) {
1175	    TLSExtensionData *xtnData = &ss->xtnData;
1176	    xtnData->advertised[xtnData->numAdvertised++] =
1177		ssl_ec_point_formats_xtn;
1178	}
1179    }
1180    return (sizeof ecPtFmt);
1181}
1182
1183/* Just make sure that the remote client supports uncompressed points,
1184 * Since that is all we support.  Disable ECC cipher suites if it doesn't.
1185 */
1186SECStatus
1187ssl3_HandleSupportedPointFormatsXtn(sslSocket *ss, PRUint16 ex_type,
1188                                    SECItem *data)
1189{
1190    int i;
1191
1192    if (data->len < 2 || data->len > 255 || !data->data ||
1193        data->len != (unsigned int)data->data[0] + 1) {
1194    	/* malformed */
1195	goto loser;
1196    }
1197    for (i = data->len; --i > 0; ) {
1198    	if (data->data[i] == 0) {
1199	    /* indicate that we should send a reply */
1200	    SECStatus rv;
1201	    rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
1202			      &ssl3_SendSupportedPointFormatsXtn);
1203	    return rv;
1204	}
1205    }
1206loser:
1207    /* evil client doesn't support uncompressed */
1208    ssl3_DisableECCSuites(ss, ecSuites);
1209    return SECFailure;
1210}
1211
1212
1213#define SSL3_GET_SERVER_PUBLICKEY(sock, type) \
1214    (ss->serverCerts[type].serverKeyPair ? \
1215    ss->serverCerts[type].serverKeyPair->pubKey : NULL)
1216
1217/* Extract the TLS curve name for the public key in our EC server cert. */
1218ECName ssl3_GetSvrCertCurveName(sslSocket *ss)
1219{
1220    SECKEYPublicKey       *srvPublicKey;
1221    ECName		  ec_curve       = ec_noName;
1222
1223    srvPublicKey = SSL3_GET_SERVER_PUBLICKEY(ss, kt_ecdh);
1224    if (srvPublicKey) {
1225	ec_curve = params2ecName(&srvPublicKey->u.ec.DEREncodedParams);
1226    }
1227    return ec_curve;
1228}
1229
1230/* Ensure that the curve in our server cert is one of the ones suppored
1231 * by the remote client, and disable all ECC cipher suites if not.
1232 */
1233SECStatus
1234ssl3_HandleSupportedCurvesXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
1235{
1236    PRInt32  list_len;
1237    PRUint32 peerCurves   = 0;
1238    PRUint32 mutualCurves = 0;
1239    PRUint16 svrCertCurveName;
1240
1241    if (!data->data || data->len < 4 || data->len > 65535)
1242    	goto loser;
1243    /* get the length of elliptic_curve_list */
1244    list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
1245    if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) {
1246    	/* malformed */
1247	goto loser;
1248    }
1249    /* build bit vector of peer's supported curve names */
1250    while (data->len) {
1251	PRInt32  curve_name =
1252		 ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
1253	if (curve_name > ec_noName && curve_name < ec_pastLastName) {
1254	    peerCurves |= (1U << curve_name);
1255	}
1256    }
1257    /* What curves do we support in common? */
1258    mutualCurves = ss->ssl3.hs.negotiatedECCurves &= peerCurves;
1259    if (!mutualCurves) { /* no mutually supported EC Curves */
1260    	goto loser;
1261    }
1262
1263    /* if our ECC cert doesn't use one of these supported curves,
1264     * disable ECC cipher suites that require an ECC cert.
1265     */
1266    svrCertCurveName = ssl3_GetSvrCertCurveName(ss);
1267    if (svrCertCurveName != ec_noName &&
1268        (mutualCurves & (1U << svrCertCurveName)) != 0) {
1269	return SECSuccess;
1270    }
1271    /* Our EC cert doesn't contain a mutually supported curve.
1272     * Disable all ECC cipher suites that require an EC cert
1273     */
1274    ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
1275    ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites);
1276    return SECFailure;
1277
1278loser:
1279    /* no common curve supported */
1280    ssl3_DisableECCSuites(ss, ecSuites);
1281    return SECFailure;
1282}
1283
1284#endif /* NSS_ENABLE_ECC */
1285