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