Coverage Report

Created: 2018-09-25 14:53

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