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 $ */
14 #include "cryptohi.h" /* for DSAU_ stuff */
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
46 #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
47 (x)->pValue=(v); (x)->ulValueLen = (l);
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
68 static const SECOidTag ecName2OIDTag
[] = {
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
{
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, */ },
161 typedef struct ECDHEKeyPairStr
{
163 int error
; /* error code of the call-once function */
167 /* arrays of ECDHE KeyPairs */
168 static ECDHEKeyPair gECDHEKeyPairs
[ec_pastLastName
];
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
);
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
);
195 params2ecName(SECKEYECParams
* params
)
197 SECItem oid
= { siBuffer
, NULL
, 0};
198 SECOidData
*oidData
= NULL
;
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
)
218 /* Caller must set hiLevel error code. */
220 ssl3_ComputeECDHKeyHash(SECItem ec_params
, SECItem server_ecpoint
,
221 SSL3Random
*client_rand
, SSL3Random
*server_rand
,
222 SSL3Hashes
*hashes
, PRBool bypassPKCS11
)
226 SECStatus rv
= SECSuccess
;
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
) {
240 hashBuf
= PORT_Alloc(bufLen
);
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
);
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
));
270 /* Called from ssl3_SendClientKeyExchange(). */
272 ssl3_SendECDHClientKeyExchange(sslSocket
* ss
, SECKEYPublicKey
* svrPubKey
)
274 PK11SymKey
* pms
= NULL
;
275 SECStatus rv
= SECFailure
;
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
);
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
);
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
);
312 SSL3AlertDescription desc
= illegal_parameter
;
313 (void)SSL3_SendAlert(ss
, alert_fatal
, desc
);
314 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE
);
318 SECKEY_DestroyPrivateKey(privKey
);
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
);
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
);
341 if (rv
!= SECSuccess
) {
342 goto loser
; /* err set by ssl3_AppendHandshake* */
348 if(pms
) PK11_FreeSymKey(pms
);
349 if(privKey
) SECKEY_DestroyPrivateKey(privKey
);
350 if(pubKey
) SECKEY_DestroyPublicKey(pubKey
);
356 ** Called from ssl3_HandleClientKeyExchange()
359 ssl3_HandleECDHClientKeyExchange(sslSocket
*ss
, SSL3Opaque
*b
,
361 SECKEYPublicKey
*srvrPubKey
,
362 SECKEYPrivateKey
*srvrPrivKey
)
366 SECKEYPublicKey clntPubKey
;
367 CK_MECHANISM_TYPE target
;
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
,
381 if (rv
!= SECSuccess
) {
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
);
398 ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE
);
402 rv
= ssl3_InitPendingCipherSpec(ss
, pms
);
403 PK11_FreeSymKey(pms
);
404 if (rv
!= SECSuccess
) {
406 return SECFailure
; /* error code set by ssl3_InitPendingCipherSpec */
412 ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk
, int requiredECCbits
)
416 for ( i
= 0; bits2curve
[i
].curve
!= ec_noName
; i
++) {
417 if (bits2curve
[i
].bits
< requiredECCbits
)
419 if (SSL_IS_CURVE_NEGOTIATED(curvemsk
, bits2curve
[i
].curve
)) {
420 return bits2curve
[i
].curve
;
423 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP
);
427 /* find the "weakest link". Get strength of signature key and of sym key.
428 * choose curve for the weakest of those two.
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
);
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
);
446 signatureKeyStrength
= curve2bits
[ ec_curve
];
448 /* RSA is our signing cert */
449 int serverKeyStrengthInBits
;
451 svrPublicKey
= SSL_GET_SERVER_PUBLIC_KEY(ss
, kt_rsa
);
453 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP
);
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
,
475 /* function to clear out the lists */
477 ssl3_ShutdownECDHECurves(void *appData
, void *nssData
)
480 ECDHEKeyPair
*keyPair
= &gECDHEKeyPairs
[0];
482 for (i
=0; i
< ec_pastLastName
; i
++, keyPair
++) {
484 ssl3_FreeKeyPair(keyPair
->pair
);
487 memset(gECDHEKeyPairs
, 0, sizeof gECDHEKeyPairs
);
492 ssl3_ECRegister(void)
495 rv
= NSS_RegisterShutdown(ssl3_ShutdownECDHECurves
, gECDHEKeyPairs
);
496 if (rv
!= SECSuccess
) {
497 gECDHEKeyPairs
[ec_noName
].error
= PORT_GetError();
502 /* CallOnce function, called once for each named curve. */
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();
520 privKey
= SECKEY_CreateECPrivateKey(&ecParams
, &pubKey
, NULL
);
521 SECITEM_FreeItem(&ecParams
, PR_FALSE
);
523 if (!privKey
|| !pubKey
|| !(keyPair
= ssl3_NewKeyPair(privKey
, pubKey
))) {
525 SECKEY_DestroyPrivateKey(privKey
);
528 SECKEY_DestroyPublicKey(pubKey
);
530 ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL
);
531 gECDHEKeyPairs
[ec_curve
].error
= PORT_GetError();
535 gECDHEKeyPairs
[ec_curve
].pair
= keyPair
;
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
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
) {
557 status
= PR_CallOnce(&gECDHEKeyPairs
[ec_noName
].once
, ssl3_ECRegister
);
558 if (status
!= PR_SUCCESS
) {
559 PORT_SetError(gECDHEKeyPairs
[ec_noName
].error
);
562 status
= PR_CallOnceWithArg(&gECDHEKeyPairs
[ec_curve
].once
,
563 ssl3_CreateECDHEphemeralKeyPair
,
565 if (status
!= PR_SUCCESS
) {
566 PORT_SetError(gECDHEKeyPairs
[ec_curve
].error
);
571 keyPair
= gECDHEKeyPairs
[ec_curve
].pair
;
572 PORT_Assert(keyPair
!= NULL
);
575 ss
->ephemeralECDHKeyPair
= ssl3_GetKeyPairRef(keyPair
);
581 ssl3_HandleECDHServerKeyExchange(sslSocket
*ss
, SSL3Opaque
*b
, PRUint32 length
)
583 PRArenaPool
* arena
= NULL
;
584 SECKEYPublicKey
*peerKey
= NULL
;
587 int errCode
= SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH
;
588 SSL3AlertDescription desc
= illegal_parameter
;
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
;
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
;
628 rv
= ssl3_ConsumeHandshakeVariable(ss
, &signature
, 2, &b
, &length
);
629 if (rv
!= SECSuccess
) {
630 goto loser
; /* malformed. */
636 goto alert_loser
; /* malformed. */
639 PRINT_BUF(60, (NULL
, "Server EC params", ec_params
.data
,
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
) {
657 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE
);
660 rv
= ssl3_VerifySignedHashes(&hashes
, ss
->sec
.peerCert
, &signature
,
661 isTLS
, ss
->pkcs11PinArg
);
662 if (rv
!= SECSuccess
) {
664 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE
);
668 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
673 ss
->sec
.peerKey
= peerKey
= PORT_ArenaZNew(arena
, SECKEYPublicKey
);
674 if (peerKey
== NULL
) {
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
;
691 /* copy publicValue in peerKey */
692 if (SECITEM_CopyItem(arena
, &peerKey
->u
.ec
.publicValue
, &ec_point
))
694 PORT_FreeArena(arena
, PR_FALSE
);
697 peerKey
->pkcs11Slot
= NULL
;
698 peerKey
->pkcs11ID
= CK_INVALID_HANDLE
;
700 ss
->sec
.peerKey
= peerKey
;
701 ss
->ssl3
.hs
.ws
= wait_cert_request
;
706 (void)SSL3_SendAlert(ss
, alert_fatal
, desc
);
708 PORT_SetError( errCode
);
711 no_memory
: /* no-memory error has already been set. */
712 ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE
);
717 ssl3_SendECDHServerKeyExchange(sslSocket
*ss
)
719 const ssl3KEADef
* kea_def
= ss
->ssl3
.hs
.kea_def
;
720 SECStatus rv
= SECFailure
;
723 SECItem signed_hash
= {siBuffer
, NULL
, 0};
726 SECKEYPublicKey
* ecdhePub
;
727 SECItem ec_params
= {siBuffer
, NULL
, 0};
728 unsigned char paramBuf
[3];
730 SSL3KEAType certIndex
;
733 /* Generate ephemeral ECDH key pair and send the public key */
734 curve
= ssl3_GetCurveNameForServerSocket(ss
);
735 if (curve
== ec_noName
) {
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
);
745 PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE
);
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
;
757 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE
);
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
);
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
776 if (kea_def
->kea
== kea_ecdhe_rsa
)
778 else /* kea_def->kea == kea_ecdhe_ecdsa */
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
);
792 length
= ec_params
.len
+
793 1 + ecdhePub
->u
.ec
.publicValue
.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
,
814 if (rv
!= SECSuccess
) {
815 goto loser
; /* err set by AppendHandshake. */
818 PORT_Free(signed_hash
.data
);
822 if (signed_hash
.data
!= NULL
)
823 PORT_Free(signed_hash
.data
);
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 */
906 ssl3_DisableECCSuites(sslSocket
* ss
, const ssl3CipherSuite
* suite
)
910 for (; *suite
; ++suite
) {
911 SECStatus rv
= ssl3_CipherPrefSet(ss
, *suite
, PR_FALSE
);
913 PORT_Assert(rv
== SECSuccess
); /* else is coding error */
918 /* Look at the server certs configured on this socket, and disable any
919 * ECC cipher suites that are not supported by those certs.
922 ssl3_FilterECCipherSuitesByServerCerts(sslSocket
* ss
)
924 CERTCertificate
* svrCert
;
926 svrCert
= ss
->serverCerts
[kt_rsa
].serverCert
;
928 ssl3_DisableECCSuites(ss
, ecdhe_rsa_suites
);
931 svrCert
= ss
->serverCerts
[kt_ecdh
].serverCert
;
933 ssl3_DisableECCSuites(ss
, ecdh_suites
);
934 ssl3_DisableECCSuites(ss
, ecdhe_ecdsa_suites
);
936 SECOidTag sigTag
= SECOID_GetAlgorithmTag(&svrCert
->signature
);
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
);
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
);
960 ssl3_DisableECCSuites(ss
, ecdh_suites
);
966 /* Ask: is ANY ECC cipher suite enabled on this socket? */
967 /* Order(N^2). Yuk. Also, this ignores export policy. */
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
)
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)
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),
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.
1022 ssl3_SendSupportedCurvesXtn(
1027 if (!ss
|| !ssl3_IsECCEnabled(ss
))
1029 if (append
&& maxBytes
>= (sizeof EClist
)) {
1030 SECStatus rv
= ssl3_AppendHandshake(ss
, EClist
, (sizeof EClist
));
1031 if (rv
!= SECSuccess
)
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.
1046 ssl3_SendSupportedPointFormatsXtn(
1051 if (!ss
|| !ssl3_IsECCEnabled(ss
))
1053 if (append
&& maxBytes
>= (sizeof ECPtFmt
)) {
1054 SECStatus rv
= ssl3_AppendHandshake(ss
, ECPtFmt
, (sizeof ECPtFmt
));
1055 if (rv
!= SECSuccess
)
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.
1070 ssl3_HandleSupportedPointFormatsXtn(sslSocket
*ss
, PRUint16 ex_type
,
1075 if (data
->len
< 2 || data
->len
> 255 || !data
->data
||
1076 data
->len
!= (unsigned int)data
->data
[0] + 1) {
1080 for (i
= data
->len
; --i
> 0; ) {
1081 if (data
->data
[i
] == 0) {
1082 /* indicate that we should send a reply */
1084 rv
= ssl3_RegisterServerHelloExtensionSender(ss
, ex_type
,
1085 &ssl3_SendSupportedPointFormatsXtn
);
1090 /* evil client doesn't support uncompressed */
1091 ssl3_DisableECCSuites(ss
, ecSuites
);
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
);
1108 ec_curve
= params2ecName(&srvPublicKey
->u
.ec
.DEREncodedParams
);
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.
1117 ssl3_HandleSupportedCurvesXtn(sslSocket
*ss
, PRUint16 ex_type
, SECItem
*data
)
1120 PRUint32 peerCurves
= 0;
1121 PRUint32 mutualCurves
= 0;
1122 PRUint16 svrCertCurveName
;
1124 if (!data
->data
|| data
->len
< 4 || data
->len
> 65535)
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) {
1132 /* build bit vector of peer's supported curve names */
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 */
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) {
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
);
1162 /* no common curve supported */
1163 ssl3_DisableECCSuites(ss
, ecSuites
);
1167 #endif /* NSS_ENABLE_ECC */