Revert "Merged all Chromoting Host code into remoting_core.dll (Windows)."
[chromium-blink-merge.git] / net / third_party / nss / ssl / ssl3ecc.c
bloba5619f8c0bb66d4f1696320d781952f34f5087f1
1 /*
2 * SSL3 Protocol
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/. */
8 /* ECC code moved here from ssl3con.c */
9 /* $Id: ssl3ecc.c,v 1.29 2012/06/11 02:38:30 emaldona%redhat.com Exp $ */
11 #include "nss.h"
12 #include "cert.h"
13 #include "ssl.h"
14 #include "cryptohi.h" /* for DSAU_ stuff */
15 #include "keyhi.h"
16 #include "secder.h"
17 #include "secitem.h"
19 #include "sslimpl.h"
20 #include "sslproto.h"
21 #include "sslerr.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"
29 #include "pk11func.h"
30 #include "secmod.h"
32 #include <stdio.h>
34 #ifdef NSS_ENABLE_ECC
37 * In NSS 3.13.2 the definition of the EC_POINT_FORM_UNCOMPRESSED macro
38 * was moved from the internal header ec.h to the public header blapit.h.
39 * Define the macro here when compiling against older system NSS headers.
41 #ifndef EC_POINT_FORM_UNCOMPRESSED
42 #define EC_POINT_FORM_UNCOMPRESSED 0x04
43 #endif
45 #ifndef PK11_SETATTRS
46 #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
47 (x)->pValue=(v); (x)->ulValueLen = (l);
48 #endif
50 #define SSL_GET_SERVER_PUBLIC_KEY(sock, type) \
51 (ss->serverCerts[type].serverKeyPair ? \
52 ss->serverCerts[type].serverKeyPair->pubKey : NULL)
54 #define SSL_IS_CURVE_NEGOTIATED(curvemsk, curveName) \
55 ((curveName > ec_noName) && \
56 (curveName < ec_pastLastName) && \
57 ((1UL << curveName) & curvemsk) != 0)
61 static SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve);
63 #define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName))
65 /* Table containing OID tags for elliptic curves named in the
66 * ECC-TLS IETF draft.
68 static const SECOidTag ecName2OIDTag[] = {
69 0,
70 SEC_OID_SECG_EC_SECT163K1, /* 1 */
71 SEC_OID_SECG_EC_SECT163R1, /* 2 */
72 SEC_OID_SECG_EC_SECT163R2, /* 3 */
73 SEC_OID_SECG_EC_SECT193R1, /* 4 */
74 SEC_OID_SECG_EC_SECT193R2, /* 5 */
75 SEC_OID_SECG_EC_SECT233K1, /* 6 */
76 SEC_OID_SECG_EC_SECT233R1, /* 7 */
77 SEC_OID_SECG_EC_SECT239K1, /* 8 */
78 SEC_OID_SECG_EC_SECT283K1, /* 9 */
79 SEC_OID_SECG_EC_SECT283R1, /* 10 */
80 SEC_OID_SECG_EC_SECT409K1, /* 11 */
81 SEC_OID_SECG_EC_SECT409R1, /* 12 */
82 SEC_OID_SECG_EC_SECT571K1, /* 13 */
83 SEC_OID_SECG_EC_SECT571R1, /* 14 */
84 SEC_OID_SECG_EC_SECP160K1, /* 15 */
85 SEC_OID_SECG_EC_SECP160R1, /* 16 */
86 SEC_OID_SECG_EC_SECP160R2, /* 17 */
87 SEC_OID_SECG_EC_SECP192K1, /* 18 */
88 SEC_OID_SECG_EC_SECP192R1, /* 19 */
89 SEC_OID_SECG_EC_SECP224K1, /* 20 */
90 SEC_OID_SECG_EC_SECP224R1, /* 21 */
91 SEC_OID_SECG_EC_SECP256K1, /* 22 */
92 SEC_OID_SECG_EC_SECP256R1, /* 23 */
93 SEC_OID_SECG_EC_SECP384R1, /* 24 */
94 SEC_OID_SECG_EC_SECP521R1, /* 25 */
97 static const PRUint16 curve2bits[] = {
98 0, /* ec_noName = 0, */
99 163, /* ec_sect163k1 = 1, */
100 163, /* ec_sect163r1 = 2, */
101 163, /* ec_sect163r2 = 3, */
102 193, /* ec_sect193r1 = 4, */
103 193, /* ec_sect193r2 = 5, */
104 233, /* ec_sect233k1 = 6, */
105 233, /* ec_sect233r1 = 7, */
106 239, /* ec_sect239k1 = 8, */
107 283, /* ec_sect283k1 = 9, */
108 283, /* ec_sect283r1 = 10, */
109 409, /* ec_sect409k1 = 11, */
110 409, /* ec_sect409r1 = 12, */
111 571, /* ec_sect571k1 = 13, */
112 571, /* ec_sect571r1 = 14, */
113 160, /* ec_secp160k1 = 15, */
114 160, /* ec_secp160r1 = 16, */
115 160, /* ec_secp160r2 = 17, */
116 192, /* ec_secp192k1 = 18, */
117 192, /* ec_secp192r1 = 19, */
118 224, /* ec_secp224k1 = 20, */
119 224, /* ec_secp224r1 = 21, */
120 256, /* ec_secp256k1 = 22, */
121 256, /* ec_secp256r1 = 23, */
122 384, /* ec_secp384r1 = 24, */
123 521, /* ec_secp521r1 = 25, */
124 65535 /* ec_pastLastName */
127 typedef struct Bits2CurveStr {
128 PRUint16 bits;
129 ECName curve;
130 } Bits2Curve;
132 static const Bits2Curve bits2curve [] = {
133 { 192, ec_secp192r1 /* = 19, fast */ },
134 { 160, ec_secp160r2 /* = 17, fast */ },
135 { 160, ec_secp160k1 /* = 15, */ },
136 { 160, ec_secp160r1 /* = 16, */ },
137 { 163, ec_sect163k1 /* = 1, */ },
138 { 163, ec_sect163r1 /* = 2, */ },
139 { 163, ec_sect163r2 /* = 3, */ },
140 { 192, ec_secp192k1 /* = 18, */ },
141 { 193, ec_sect193r1 /* = 4, */ },
142 { 193, ec_sect193r2 /* = 5, */ },
143 { 224, ec_secp224r1 /* = 21, fast */ },
144 { 224, ec_secp224k1 /* = 20, */ },
145 { 233, ec_sect233k1 /* = 6, */ },
146 { 233, ec_sect233r1 /* = 7, */ },
147 { 239, ec_sect239k1 /* = 8, */ },
148 { 256, ec_secp256r1 /* = 23, fast */ },
149 { 256, ec_secp256k1 /* = 22, */ },
150 { 283, ec_sect283k1 /* = 9, */ },
151 { 283, ec_sect283r1 /* = 10, */ },
152 { 384, ec_secp384r1 /* = 24, fast */ },
153 { 409, ec_sect409k1 /* = 11, */ },
154 { 409, ec_sect409r1 /* = 12, */ },
155 { 521, ec_secp521r1 /* = 25, fast */ },
156 { 571, ec_sect571k1 /* = 13, */ },
157 { 571, ec_sect571r1 /* = 14, */ },
158 { 65535, ec_noName }
161 typedef struct ECDHEKeyPairStr {
162 ssl3KeyPair * pair;
163 int error; /* error code of the call-once function */
164 PRCallOnceType once;
165 } ECDHEKeyPair;
167 /* arrays of ECDHE KeyPairs */
168 static ECDHEKeyPair gECDHEKeyPairs[ec_pastLastName];
170 SECStatus
171 ssl3_ECName2Params(PRArenaPool * arena, ECName curve, SECKEYECParams * params)
173 SECOidData *oidData = NULL;
175 if ((curve <= ec_noName) || (curve >= ec_pastLastName) ||
176 ((oidData = SECOID_FindOIDByTag(ecName2OIDTag[curve])) == NULL)) {
177 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
178 return SECFailure;
181 SECITEM_AllocItem(arena, params, (2 + oidData->oid.len));
183 * params->data needs to contain the ASN encoding of an object ID (OID)
184 * representing the named curve. The actual OID is in
185 * oidData->oid.data so we simply prepend 0x06 and OID length
187 params->data[0] = SEC_ASN1_OBJECT_ID;
188 params->data[1] = oidData->oid.len;
189 memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
191 return SECSuccess;
194 static ECName
195 params2ecName(SECKEYECParams * params)
197 SECItem oid = { siBuffer, NULL, 0};
198 SECOidData *oidData = NULL;
199 ECName i;
202 * params->data needs to contain the ASN encoding of an object ID (OID)
203 * representing a named curve. Here, we strip away everything
204 * before the actual OID and use the OID to look up a named curve.
206 if (params->data[0] != SEC_ASN1_OBJECT_ID) return ec_noName;
207 oid.len = params->len - 2;
208 oid.data = params->data + 2;
209 if ((oidData = SECOID_FindOID(&oid)) == NULL) return ec_noName;
210 for (i = ec_noName + 1; i < ec_pastLastName; i++) {
211 if (ecName2OIDTag[i] == oidData->offset)
212 return i;
215 return ec_noName;
218 /* Caller must set hiLevel error code. */
219 static SECStatus
220 ssl3_ComputeECDHKeyHash(SECItem ec_params, SECItem server_ecpoint,
221 SSL3Random *client_rand, SSL3Random *server_rand,
222 SSL3Hashes *hashes, PRBool bypassPKCS11)
224 PRUint8 * hashBuf;
225 PRUint8 * pBuf;
226 SECStatus rv = SECSuccess;
227 unsigned int bufLen;
229 * XXX For now, we only support named curves (the appropriate
230 * checks are made before this method is called) so ec_params
231 * takes up only two bytes. ECPoint needs to fit in 256 bytes
232 * (because the spec says the length must fit in one byte)
234 PRUint8 buf[2*SSL3_RANDOM_LENGTH + 2 + 1 + 256];
236 bufLen = 2*SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.len;
237 if (bufLen <= sizeof buf) {
238 hashBuf = buf;
239 } else {
240 hashBuf = PORT_Alloc(bufLen);
241 if (!hashBuf) {
242 return SECFailure;
246 memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
247 pBuf = hashBuf + SSL3_RANDOM_LENGTH;
248 memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
249 pBuf += SSL3_RANDOM_LENGTH;
250 memcpy(pBuf, ec_params.data, ec_params.len);
251 pBuf += ec_params.len;
252 pBuf[0] = (PRUint8)(server_ecpoint.len);
253 pBuf += 1;
254 memcpy(pBuf, server_ecpoint.data, server_ecpoint.len);
255 pBuf += server_ecpoint.len;
256 PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
258 rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11);
260 PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen));
261 PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result", hashes->md5, MD5_LENGTH));
262 PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", hashes->sha, SHA1_LENGTH));
264 if (hashBuf != buf)
265 PORT_Free(hashBuf);
266 return rv;
270 /* Called from ssl3_SendClientKeyExchange(). */
271 SECStatus
272 ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
274 PK11SymKey * pms = NULL;
275 SECStatus rv = SECFailure;
276 PRBool isTLS;
277 CK_MECHANISM_TYPE target;
278 SECKEYPublicKey *pubKey = NULL; /* Ephemeral ECDH key */
279 SECKEYPrivateKey *privKey = NULL; /* Ephemeral ECDH key */
281 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
282 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
284 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
286 /* Generate ephemeral EC keypair */
287 if (svrPubKey->keyType != ecKey) {
288 PORT_SetError(SEC_ERROR_BAD_KEY);
289 goto loser;
291 /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */
292 privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams,
293 &pubKey, ss->pkcs11PinArg);
294 if (!privKey || !pubKey) {
295 ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
296 rv = SECFailure;
297 goto loser;
299 PRINT_BUF(50, (ss, "ECDH public value:",
300 pubKey->u.ec.publicValue.data,
301 pubKey->u.ec.publicValue.len));
303 if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
304 else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
306 /* Determine the PMS */
307 pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL,
308 CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
309 CKD_NULL, NULL, NULL);
311 if (pms == NULL) {
312 SSL3AlertDescription desc = illegal_parameter;
313 (void)SSL3_SendAlert(ss, alert_fatal, desc);
314 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
315 goto loser;
318 SECKEY_DestroyPrivateKey(privKey);
319 privKey = NULL;
321 rv = ssl3_InitPendingCipherSpec(ss, pms);
322 PK11_FreeSymKey(pms); pms = NULL;
324 if (rv != SECSuccess) {
325 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
326 goto loser;
329 rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
330 pubKey->u.ec.publicValue.len + 1);
331 if (rv != SECSuccess) {
332 goto loser; /* err set by ssl3_AppendHandshake* */
335 rv = ssl3_AppendHandshakeVariable(ss,
336 pubKey->u.ec.publicValue.data,
337 pubKey->u.ec.publicValue.len, 1);
338 SECKEY_DestroyPublicKey(pubKey);
339 pubKey = NULL;
341 if (rv != SECSuccess) {
342 goto loser; /* err set by ssl3_AppendHandshake* */
345 rv = SECSuccess;
347 loser:
348 if(pms) PK11_FreeSymKey(pms);
349 if(privKey) SECKEY_DestroyPrivateKey(privKey);
350 if(pubKey) SECKEY_DestroyPublicKey(pubKey);
351 return rv;
356 ** Called from ssl3_HandleClientKeyExchange()
358 SECStatus
359 ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
360 PRUint32 length,
361 SECKEYPublicKey *srvrPubKey,
362 SECKEYPrivateKey *srvrPrivKey)
364 PK11SymKey * pms;
365 SECStatus rv;
366 SECKEYPublicKey clntPubKey;
367 CK_MECHANISM_TYPE target;
368 PRBool isTLS;
370 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
371 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
373 clntPubKey.keyType = ecKey;
374 clntPubKey.u.ec.DEREncodedParams.len =
375 srvrPubKey->u.ec.DEREncodedParams.len;
376 clntPubKey.u.ec.DEREncodedParams.data =
377 srvrPubKey->u.ec.DEREncodedParams.data;
379 rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue,
380 1, &b, &length);
381 if (rv != SECSuccess) {
382 SEND_ALERT
383 return SECFailure; /* XXX Who sets the error code?? */
386 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
388 if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
389 else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
391 /* Determine the PMS */
392 pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL,
393 CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
394 CKD_NULL, NULL, NULL);
396 if (pms == NULL) {
397 /* last gasp. */
398 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
399 return SECFailure;
402 rv = ssl3_InitPendingCipherSpec(ss, pms);
403 PK11_FreeSymKey(pms);
404 if (rv != SECSuccess) {
405 SEND_ALERT
406 return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
408 return SECSuccess;
411 ECName
412 ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits)
414 int i;
416 for ( i = 0; bits2curve[i].curve != ec_noName; i++) {
417 if (bits2curve[i].bits < requiredECCbits)
418 continue;
419 if (SSL_IS_CURVE_NEGOTIATED(curvemsk, bits2curve[i].curve)) {
420 return bits2curve[i].curve;
423 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
424 return ec_noName;
427 /* find the "weakest link". Get strength of signature key and of sym key.
428 * choose curve for the weakest of those two.
430 ECName
431 ssl3_GetCurveNameForServerSocket(sslSocket *ss)
433 SECKEYPublicKey * svrPublicKey = NULL;
434 ECName ec_curve = ec_noName;
435 int signatureKeyStrength = 521;
436 int requiredECCbits = ss->sec.secretKeyBits * 2;
438 if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa) {
439 svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_ecdh);
440 if (svrPublicKey)
441 ec_curve = params2ecName(&svrPublicKey->u.ec.DEREncodedParams);
442 if (!SSL_IS_CURVE_NEGOTIATED(ss->ssl3.hs.negotiatedECCurves, ec_curve)) {
443 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
444 return ec_noName;
446 signatureKeyStrength = curve2bits[ ec_curve ];
447 } else {
448 /* RSA is our signing cert */
449 int serverKeyStrengthInBits;
451 svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_rsa);
452 if (!svrPublicKey) {
453 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
454 return ec_noName;
457 /* currently strength in bytes */
458 serverKeyStrengthInBits = svrPublicKey->u.rsa.modulus.len;
459 if (svrPublicKey->u.rsa.modulus.data[0] == 0) {
460 serverKeyStrengthInBits--;
462 /* convert to strength in bits */
463 serverKeyStrengthInBits *= BPB;
465 signatureKeyStrength =
466 SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits);
468 if ( requiredECCbits > signatureKeyStrength )
469 requiredECCbits = signatureKeyStrength;
471 return ssl3_GetCurveWithECKeyStrength(ss->ssl3.hs.negotiatedECCurves,
472 requiredECCbits);
475 /* function to clear out the lists */
476 static SECStatus
477 ssl3_ShutdownECDHECurves(void *appData, void *nssData)
479 int i;
480 ECDHEKeyPair *keyPair = &gECDHEKeyPairs[0];
482 for (i=0; i < ec_pastLastName; i++, keyPair++) {
483 if (keyPair->pair) {
484 ssl3_FreeKeyPair(keyPair->pair);
487 memset(gECDHEKeyPairs, 0, sizeof gECDHEKeyPairs);
488 return SECSuccess;
491 static PRStatus
492 ssl3_ECRegister(void)
494 SECStatus rv;
495 rv = NSS_RegisterShutdown(ssl3_ShutdownECDHECurves, gECDHEKeyPairs);
496 if (rv != SECSuccess) {
497 gECDHEKeyPairs[ec_noName].error = PORT_GetError();
499 return (PRStatus)rv;
502 /* CallOnce function, called once for each named curve. */
503 static PRStatus
504 ssl3_CreateECDHEphemeralKeyPair(void * arg)
506 SECKEYPrivateKey * privKey = NULL;
507 SECKEYPublicKey * pubKey = NULL;
508 ssl3KeyPair * keyPair = NULL;
509 ECName ec_curve = (ECName)arg;
510 SECKEYECParams ecParams = { siBuffer, NULL, 0 };
512 PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL);
514 /* ok, no one has generated a global key for this curve yet, do so */
515 if (ssl3_ECName2Params(NULL, ec_curve, &ecParams) != SECSuccess) {
516 gECDHEKeyPairs[ec_curve].error = PORT_GetError();
517 return PR_FAILURE;
520 privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL);
521 SECITEM_FreeItem(&ecParams, PR_FALSE);
523 if (!privKey || !pubKey || !(keyPair = ssl3_NewKeyPair(privKey, pubKey))) {
524 if (privKey) {
525 SECKEY_DestroyPrivateKey(privKey);
527 if (pubKey) {
528 SECKEY_DestroyPublicKey(pubKey);
530 ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
531 gECDHEKeyPairs[ec_curve].error = PORT_GetError();
532 return PR_FAILURE;
535 gECDHEKeyPairs[ec_curve].pair = keyPair;
536 return PR_SUCCESS;
540 * Creates the ephemeral public and private ECDH keys used by
541 * server in ECDHE_RSA and ECDHE_ECDSA handshakes.
542 * For now, the elliptic curve is chosen to be the same
543 * strength as the signing certificate (ECC or RSA).
544 * We need an API to specify the curve. This won't be a real
545 * issue until we further develop server-side support for ECC
546 * cipher suites.
548 static SECStatus
549 ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve)
551 ssl3KeyPair * keyPair = NULL;
553 /* if there's no global key for this curve, make one. */
554 if (gECDHEKeyPairs[ec_curve].pair == NULL) {
555 PRStatus status;
557 status = PR_CallOnce(&gECDHEKeyPairs[ec_noName].once, ssl3_ECRegister);
558 if (status != PR_SUCCESS) {
559 PORT_SetError(gECDHEKeyPairs[ec_noName].error);
560 return SECFailure;
562 status = PR_CallOnceWithArg(&gECDHEKeyPairs[ec_curve].once,
563 ssl3_CreateECDHEphemeralKeyPair,
564 (void *)ec_curve);
565 if (status != PR_SUCCESS) {
566 PORT_SetError(gECDHEKeyPairs[ec_curve].error);
567 return SECFailure;
571 keyPair = gECDHEKeyPairs[ec_curve].pair;
572 PORT_Assert(keyPair != NULL);
573 if (!keyPair)
574 return SECFailure;
575 ss->ephemeralECDHKeyPair = ssl3_GetKeyPairRef(keyPair);
577 return SECSuccess;
580 SECStatus
581 ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
583 PRArenaPool * arena = NULL;
584 SECKEYPublicKey *peerKey = NULL;
585 PRBool isTLS;
586 SECStatus rv;
587 int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
588 SSL3AlertDescription desc = illegal_parameter;
589 SSL3Hashes hashes;
590 SECItem signature = {siBuffer, NULL, 0};
592 SECItem ec_params = {siBuffer, NULL, 0};
593 SECItem ec_point = {siBuffer, NULL, 0};
594 unsigned char paramBuf[3]; /* only for curve_type == named_curve */
596 isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
598 /* XXX This works only for named curves, revisit this when
599 * we support generic curves.
601 ec_params.len = sizeof paramBuf;
602 ec_params.data = paramBuf;
603 rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length);
604 if (rv != SECSuccess) {
605 goto loser; /* malformed. */
608 /* Fail if the curve is not a named curve */
609 if ((ec_params.data[0] != ec_type_named) ||
610 (ec_params.data[1] != 0) ||
611 !supportedCurve(ec_params.data[2])) {
612 errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
613 desc = handshake_failure;
614 goto alert_loser;
617 rv = ssl3_ConsumeHandshakeVariable(ss, &ec_point, 1, &b, &length);
618 if (rv != SECSuccess) {
619 goto loser; /* malformed. */
621 /* Fail if the ec point uses compressed representation */
622 if (ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
623 errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM;
624 desc = handshake_failure;
625 goto alert_loser;
628 rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
629 if (rv != SECSuccess) {
630 goto loser; /* malformed. */
633 if (length != 0) {
634 if (isTLS)
635 desc = decode_error;
636 goto alert_loser; /* malformed. */
639 PRINT_BUF(60, (NULL, "Server EC params", ec_params.data,
640 ec_params.len));
641 PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.len));
643 /* failures after this point are not malformed handshakes. */
644 /* TLS: send decrypt_error if signature failed. */
645 desc = isTLS ? decrypt_error : handshake_failure;
648 * check to make sure the hash is signed by right guy
650 rv = ssl3_ComputeECDHKeyHash(ec_params, ec_point,
651 &ss->ssl3.hs.client_random,
652 &ss->ssl3.hs.server_random,
653 &hashes, ss->opt.bypassPKCS11);
655 if (rv != SECSuccess) {
656 errCode =
657 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
658 goto alert_loser;
660 rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
661 isTLS, ss->pkcs11PinArg);
662 if (rv != SECSuccess) {
663 errCode =
664 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
665 goto alert_loser;
668 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
669 if (arena == NULL) {
670 goto no_memory;
673 ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
674 if (peerKey == NULL) {
675 goto no_memory;
678 peerKey->arena = arena;
679 peerKey->keyType = ecKey;
681 /* set up EC parameters in peerKey */
682 if (ssl3_ECName2Params(arena, ec_params.data[2],
683 &peerKey->u.ec.DEREncodedParams) != SECSuccess) {
684 /* we should never get here since we already
685 * checked that we are dealing with a supported curve
687 errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
688 goto alert_loser;
691 /* copy publicValue in peerKey */
692 if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue, &ec_point))
694 PORT_FreeArena(arena, PR_FALSE);
695 goto no_memory;
697 peerKey->pkcs11Slot = NULL;
698 peerKey->pkcs11ID = CK_INVALID_HANDLE;
700 ss->sec.peerKey = peerKey;
701 ss->ssl3.hs.ws = wait_cert_request;
703 return SECSuccess;
705 alert_loser:
706 (void)SSL3_SendAlert(ss, alert_fatal, desc);
707 loser:
708 PORT_SetError( errCode );
709 return SECFailure;
711 no_memory: /* no-memory error has already been set. */
712 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
713 return SECFailure;
716 SECStatus
717 ssl3_SendECDHServerKeyExchange(sslSocket *ss)
719 const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
720 SECStatus rv = SECFailure;
721 int length;
722 PRBool isTLS;
723 SECItem signed_hash = {siBuffer, NULL, 0};
724 SSL3Hashes hashes;
726 SECKEYPublicKey * ecdhePub;
727 SECItem ec_params = {siBuffer, NULL, 0};
728 unsigned char paramBuf[3];
729 ECName curve;
730 SSL3KEAType certIndex;
733 /* Generate ephemeral ECDH key pair and send the public key */
734 curve = ssl3_GetCurveNameForServerSocket(ss);
735 if (curve == ec_noName) {
736 goto loser;
738 rv = ssl3_CreateECDHEphemeralKeys(ss, curve);
739 if (rv != SECSuccess) {
740 goto loser; /* err set by AppendHandshake. */
742 ecdhePub = ss->ephemeralECDHKeyPair->pubKey;
743 PORT_Assert(ecdhePub != NULL);
744 if (!ecdhePub) {
745 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
746 return SECFailure;
749 ec_params.len = sizeof paramBuf;
750 ec_params.data = paramBuf;
751 curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams);
752 if (curve != ec_noName) {
753 ec_params.data[0] = ec_type_named;
754 ec_params.data[1] = 0x00;
755 ec_params.data[2] = curve;
756 } else {
757 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
758 goto loser;
761 rv = ssl3_ComputeECDHKeyHash(ec_params, ecdhePub->u.ec.publicValue,
762 &ss->ssl3.hs.client_random,
763 &ss->ssl3.hs.server_random,
764 &hashes, ss->opt.bypassPKCS11);
765 if (rv != SECSuccess) {
766 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
767 goto loser;
770 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
772 /* XXX SSLKEAType isn't really a good choice for
773 * indexing certificates but that's all we have
774 * for now.
776 if (kea_def->kea == kea_ecdhe_rsa)
777 certIndex = kt_rsa;
778 else /* kea_def->kea == kea_ecdhe_ecdsa */
779 certIndex = kt_ecdh;
781 rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY,
782 &signed_hash, isTLS);
783 if (rv != SECSuccess) {
784 goto loser; /* ssl3_SignHashes has set err. */
786 if (signed_hash.data == NULL) {
787 /* how can this happen and rv == SECSuccess ?? */
788 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
789 goto loser;
792 length = ec_params.len +
793 1 + ecdhePub->u.ec.publicValue.len +
794 2 + signed_hash.len;
796 rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
797 if (rv != SECSuccess) {
798 goto loser; /* err set by AppendHandshake. */
801 rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len);
802 if (rv != SECSuccess) {
803 goto loser; /* err set by AppendHandshake. */
806 rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data,
807 ecdhePub->u.ec.publicValue.len, 1);
808 if (rv != SECSuccess) {
809 goto loser; /* err set by AppendHandshake. */
812 rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
813 signed_hash.len, 2);
814 if (rv != SECSuccess) {
815 goto loser; /* err set by AppendHandshake. */
818 PORT_Free(signed_hash.data);
819 return SECSuccess;
821 loser:
822 if (signed_hash.data != NULL)
823 PORT_Free(signed_hash.data);
824 return SECFailure;
827 /* Lists of ECC cipher suites for searching and disabling. */
829 static const ssl3CipherSuite ecdh_suites[] = {
830 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
831 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
832 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
833 TLS_ECDH_ECDSA_WITH_NULL_SHA,
834 TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
835 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
836 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
837 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
838 TLS_ECDH_RSA_WITH_NULL_SHA,
839 TLS_ECDH_RSA_WITH_RC4_128_SHA,
840 0 /* end of list marker */
843 static const ssl3CipherSuite ecdh_ecdsa_suites[] = {
844 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
845 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
846 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
847 TLS_ECDH_ECDSA_WITH_NULL_SHA,
848 TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
849 0 /* end of list marker */
852 static const ssl3CipherSuite ecdh_rsa_suites[] = {
853 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
854 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
855 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
856 TLS_ECDH_RSA_WITH_NULL_SHA,
857 TLS_ECDH_RSA_WITH_RC4_128_SHA,
858 0 /* end of list marker */
861 static const ssl3CipherSuite ecdhe_ecdsa_suites[] = {
862 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
863 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
864 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
865 TLS_ECDHE_ECDSA_WITH_NULL_SHA,
866 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
867 0 /* end of list marker */
870 static const ssl3CipherSuite ecdhe_rsa_suites[] = {
871 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
872 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
873 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
874 TLS_ECDHE_RSA_WITH_NULL_SHA,
875 TLS_ECDHE_RSA_WITH_RC4_128_SHA,
876 0 /* end of list marker */
879 /* List of all ECC cipher suites */
880 static const ssl3CipherSuite ecSuites[] = {
881 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
882 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
883 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
884 TLS_ECDHE_ECDSA_WITH_NULL_SHA,
885 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
886 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
887 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
888 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
889 TLS_ECDHE_RSA_WITH_NULL_SHA,
890 TLS_ECDHE_RSA_WITH_RC4_128_SHA,
891 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
892 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
893 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
894 TLS_ECDH_ECDSA_WITH_NULL_SHA,
895 TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
896 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
897 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
898 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
899 TLS_ECDH_RSA_WITH_NULL_SHA,
900 TLS_ECDH_RSA_WITH_RC4_128_SHA,
901 0 /* end of list marker */
904 /* On this socket, Disable the ECC cipher suites in the argument's list */
905 SECStatus
906 ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite)
908 if (!suite)
909 suite = ecSuites;
910 for (; *suite; ++suite) {
911 SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
913 PORT_Assert(rv == SECSuccess); /* else is coding error */
915 return SECSuccess;
918 /* Look at the server certs configured on this socket, and disable any
919 * ECC cipher suites that are not supported by those certs.
921 void
922 ssl3_FilterECCipherSuitesByServerCerts(sslSocket * ss)
924 CERTCertificate * svrCert;
926 svrCert = ss->serverCerts[kt_rsa].serverCert;
927 if (!svrCert) {
928 ssl3_DisableECCSuites(ss, ecdhe_rsa_suites);
931 svrCert = ss->serverCerts[kt_ecdh].serverCert;
932 if (!svrCert) {
933 ssl3_DisableECCSuites(ss, ecdh_suites);
934 ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites);
935 } else {
936 SECOidTag sigTag = SECOID_GetAlgorithmTag(&svrCert->signature);
938 switch (sigTag) {
939 case SEC_OID_PKCS1_RSA_ENCRYPTION:
940 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
941 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
942 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
943 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
944 case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
945 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
946 case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
947 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
948 ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
949 break;
950 case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
951 case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
952 case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
953 case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
954 case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
955 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
956 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
957 ssl3_DisableECCSuites(ss, ecdh_rsa_suites);
958 break;
959 default:
960 ssl3_DisableECCSuites(ss, ecdh_suites);
961 break;
966 /* Ask: is ANY ECC cipher suite enabled on this socket? */
967 /* Order(N^2). Yuk. Also, this ignores export policy. */
968 PRBool
969 ssl3_IsECCEnabled(sslSocket * ss)
971 const ssl3CipherSuite * suite;
973 for (suite = ecSuites; *suite; ++suite) {
974 PRBool enabled = PR_FALSE;
975 SECStatus rv = ssl3_CipherPrefGet(ss, *suite, &enabled);
977 PORT_Assert(rv == SECSuccess); /* else is coding error */
978 if (rv == SECSuccess && enabled)
979 return PR_TRUE;
981 return PR_FALSE;
984 #define BE(n) 0, n
986 #ifndef NSS_ECC_MORE_THAN_SUITE_B
987 /* Prefabricated TLS client hello extension, Elliptic Curves List,
988 * offers only 3 curves, the Suite B curves, 23-25
990 static const PRUint8 EClist[12] = {
991 BE(10), /* Extension type */
992 BE( 8), /* octets that follow ( 3 pairs + 1 length pair) */
993 BE( 6), /* octets that follow ( 3 pairs) */
994 BE(23), BE(24), BE(25)
996 #else
997 /* Prefabricated TLS client hello extension, Elliptic Curves List,
998 * offers curves 1-25.
1000 static const PRUint8 EClist[56] = {
1001 BE(10), /* Extension type */
1002 BE(52), /* octets that follow (25 pairs + 1 length pair) */
1003 BE(50), /* octets that follow (25 pairs) */
1004 BE( 1), BE( 2), BE( 3), BE( 4), BE( 5), BE( 6), BE( 7),
1005 BE( 8), BE( 9), BE(10), BE(11), BE(12), BE(13), BE(14), BE(15),
1006 BE(16), BE(17), BE(18), BE(19), BE(20), BE(21), BE(22), BE(23),
1007 BE(24), BE(25)
1009 #endif
1011 static const PRUint8 ECPtFmt[6] = {
1012 BE(11), /* Extension type */
1013 BE( 2), /* octets that follow */
1014 1, /* octets that follow */
1015 0 /* uncompressed type only */
1018 /* Send our "canned" (precompiled) Supported Elliptic Curves extension,
1019 * which says that we support all TLS-defined named curves.
1021 PRInt32
1022 ssl3_SendSupportedCurvesXtn(
1023 sslSocket * ss,
1024 PRBool append,
1025 PRUint32 maxBytes)
1027 if (!ss || !ssl3_IsECCEnabled(ss))
1028 return 0;
1029 if (append && maxBytes >= (sizeof EClist)) {
1030 SECStatus rv = ssl3_AppendHandshake(ss, EClist, (sizeof EClist));
1031 if (rv != SECSuccess)
1032 return -1;
1033 if (!ss->sec.isServer) {
1034 TLSExtensionData *xtnData = &ss->xtnData;
1035 xtnData->advertised[xtnData->numAdvertised++] =
1036 ssl_elliptic_curves_xtn;
1039 return (sizeof EClist);
1042 /* Send our "canned" (precompiled) Supported Point Formats extension,
1043 * which says that we only support uncompressed points.
1045 PRInt32
1046 ssl3_SendSupportedPointFormatsXtn(
1047 sslSocket * ss,
1048 PRBool append,
1049 PRUint32 maxBytes)
1051 if (!ss || !ssl3_IsECCEnabled(ss))
1052 return 0;
1053 if (append && maxBytes >= (sizeof ECPtFmt)) {
1054 SECStatus rv = ssl3_AppendHandshake(ss, ECPtFmt, (sizeof ECPtFmt));
1055 if (rv != SECSuccess)
1056 return -1;
1057 if (!ss->sec.isServer) {
1058 TLSExtensionData *xtnData = &ss->xtnData;
1059 xtnData->advertised[xtnData->numAdvertised++] =
1060 ssl_ec_point_formats_xtn;
1063 return (sizeof ECPtFmt);
1066 /* Just make sure that the remote client supports uncompressed points,
1067 * Since that is all we support. Disable ECC cipher suites if it doesn't.
1069 SECStatus
1070 ssl3_HandleSupportedPointFormatsXtn(sslSocket *ss, PRUint16 ex_type,
1071 SECItem *data)
1073 int i;
1075 if (data->len < 2 || data->len > 255 || !data->data ||
1076 data->len != (unsigned int)data->data[0] + 1) {
1077 /* malformed */
1078 goto loser;
1080 for (i = data->len; --i > 0; ) {
1081 if (data->data[i] == 0) {
1082 /* indicate that we should send a reply */
1083 SECStatus rv;
1084 rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
1085 &ssl3_SendSupportedPointFormatsXtn);
1086 return rv;
1089 loser:
1090 /* evil client doesn't support uncompressed */
1091 ssl3_DisableECCSuites(ss, ecSuites);
1092 return SECFailure;
1096 #define SSL3_GET_SERVER_PUBLICKEY(sock, type) \
1097 (ss->serverCerts[type].serverKeyPair ? \
1098 ss->serverCerts[type].serverKeyPair->pubKey : NULL)
1100 /* Extract the TLS curve name for the public key in our EC server cert. */
1101 ECName ssl3_GetSvrCertCurveName(sslSocket *ss)
1103 SECKEYPublicKey *srvPublicKey;
1104 ECName ec_curve = ec_noName;
1106 srvPublicKey = SSL3_GET_SERVER_PUBLICKEY(ss, kt_ecdh);
1107 if (srvPublicKey) {
1108 ec_curve = params2ecName(&srvPublicKey->u.ec.DEREncodedParams);
1110 return ec_curve;
1113 /* Ensure that the curve in our server cert is one of the ones suppored
1114 * by the remote client, and disable all ECC cipher suites if not.
1116 SECStatus
1117 ssl3_HandleSupportedCurvesXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
1119 PRInt32 list_len;
1120 PRUint32 peerCurves = 0;
1121 PRUint32 mutualCurves = 0;
1122 PRUint16 svrCertCurveName;
1124 if (!data->data || data->len < 4 || data->len > 65535)
1125 goto loser;
1126 /* get the length of elliptic_curve_list */
1127 list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
1128 if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) {
1129 /* malformed */
1130 goto loser;
1132 /* build bit vector of peer's supported curve names */
1133 while (data->len) {
1134 PRInt32 curve_name =
1135 ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
1136 if (curve_name > ec_noName && curve_name < ec_pastLastName) {
1137 peerCurves |= (1U << curve_name);
1140 /* What curves do we support in common? */
1141 mutualCurves = ss->ssl3.hs.negotiatedECCurves &= peerCurves;
1142 if (!mutualCurves) { /* no mutually supported EC Curves */
1143 goto loser;
1146 /* if our ECC cert doesn't use one of these supported curves,
1147 * disable ECC cipher suites that require an ECC cert.
1149 svrCertCurveName = ssl3_GetSvrCertCurveName(ss);
1150 if (svrCertCurveName != ec_noName &&
1151 (mutualCurves & (1U << svrCertCurveName)) != 0) {
1152 return SECSuccess;
1154 /* Our EC cert doesn't contain a mutually supported curve.
1155 * Disable all ECC cipher suites that require an EC cert
1157 ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
1158 ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites);
1159 return SECFailure;
1161 loser:
1162 /* no common curve supported */
1163 ssl3_DisableECCSuites(ss, ecSuites);
1164 return SECFailure;
1167 #endif /* NSS_ENABLE_ECC */