Coverage Report

Created: 2026-06-07 07:11

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