tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ssl3ecc.c (32137B)


      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 {
     38    SECOidData *oidData = NULL;
     39 
     40    if (!params) {
     41        PORT_Assert(0);
     42        PORT_SetError(SEC_ERROR_INVALID_ARGS);
     43        return SECFailure;
     44    }
     45 
     46    if (!ecGroup || ecGroup->keaType != ssl_kea_ecdh ||
     47        (oidData = SECOID_FindOIDByTag(ecGroup->oidTag)) == NULL) {
     48        PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
     49        return SECFailure;
     50    }
     51 
     52    if (SECITEM_AllocItem(arena, params, (2 + oidData->oid.len)) == NULL) {
     53        PORT_SetError(SEC_ERROR_NO_MEMORY);
     54        return SECFailure;
     55    }
     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    params->data[0] = SEC_ASN1_OBJECT_ID;
     63    params->data[1] = oidData->oid.len;
     64    memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
     65 
     66    return SECSuccess;
     67 }
     68 
     69 const sslNamedGroupDef *
     70 ssl_ECPubKey2NamedGroup(const SECKEYPublicKey *pubKey)
     71 {
     72    SECItem oid = { siBuffer, NULL, 0 };
     73    SECOidData *oidData = NULL;
     74    PRUint32 policyFlags = 0;
     75    unsigned int i;
     76    const SECKEYECParams *params;
     77 
     78    if (pubKey->keyType != ecKey) {
     79        PORT_Assert(0);
     80        return NULL;
     81    }
     82 
     83    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    if (params->data[0] != SEC_ASN1_OBJECT_ID)
     91        return NULL;
     92    oid.len = params->len - 2;
     93    oid.data = params->data + 2;
     94    if ((oidData = SECOID_FindOID(&oid)) == NULL)
     95        return NULL;
     96    if ((NSS_GetAlgorithmPolicy(oidData->offset, &policyFlags) ==
     97         SECSuccess) &&
     98        !(policyFlags & NSS_USE_ALG_IN_SSL_KX)) {
     99        return NULL;
    100    }
    101    for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
    102        if (ssl_named_groups[i].oidTag == oidData->offset) {
    103            return &ssl_named_groups[i];
    104        }
    105    }
    106 
    107    return NULL;
    108 }
    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 {
    117    PRUint8 *hashBuf;
    118    PRUint8 *pBuf;
    119    SECStatus rv = SECSuccess;
    120    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    PRUint8 buf[2 * SSL3_RANDOM_LENGTH + 2 + 1 + 256];
    127 
    128    bufLen = 2 * SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.len;
    129    if (bufLen <= sizeof buf) {
    130        hashBuf = buf;
    131    } else {
    132        hashBuf = PORT_Alloc(bufLen);
    133        if (!hashBuf) {
    134            return SECFailure;
    135        }
    136    }
    137 
    138    memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
    139    pBuf = hashBuf + SSL3_RANDOM_LENGTH;
    140    memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
    141    pBuf += SSL3_RANDOM_LENGTH;
    142    memcpy(pBuf, ec_params.data, ec_params.len);
    143    pBuf += ec_params.len;
    144    pBuf[0] = (PRUint8)(server_ecpoint.len);
    145    pBuf += 1;
    146    memcpy(pBuf, server_ecpoint.data, server_ecpoint.len);
    147    pBuf += server_ecpoint.len;
    148    PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
    149 
    150    rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes);
    151 
    152    PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen));
    153    PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result",
    154                   hashes->u.s.md5, MD5_LENGTH));
    155    PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result",
    156                   hashes->u.s.sha, SHA1_LENGTH));
    157 
    158    if (hashBuf != buf)
    159        PORT_Free(hashBuf);
    160    return rv;
    161 }
    162 
    163 /* Called from ssl3_SendClientKeyExchange(). */
    164 SECStatus
    165 ssl3_SendECDHClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey)
    166 {
    167    PK11SymKey *pms = NULL;
    168    SECStatus rv = SECFailure;
    169    PRBool isTLS, isTLS12;
    170    CK_MECHANISM_TYPE target;
    171    const sslNamedGroupDef *groupDef;
    172    sslEphemeralKeyPair *keyPair = NULL;
    173    SECKEYPublicKey *pubKey;
    174 
    175    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    176    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
    177 
    178    isTLS = (PRBool)(ss->version > SSL_LIBRARY_VERSION_3_0);
    179    isTLS12 = (PRBool)(ss->version >= SSL_LIBRARY_VERSION_TLS_1_2);
    180 
    181    /* Generate ephemeral EC keypair */
    182    if (svrPubKey->keyType != ecKey) {
    183        PORT_SetError(SEC_ERROR_BAD_KEY);
    184        goto loser;
    185    }
    186    groupDef = ssl_ECPubKey2NamedGroup(svrPubKey);
    187    if (!groupDef) {
    188        PORT_SetError(SEC_ERROR_BAD_KEY);
    189        goto loser;
    190    }
    191    ss->sec.keaGroup = groupDef;
    192    rv = ssl_CreateECDHEphemeralKeyPair(ss, groupDef, &keyPair);
    193    if (rv != SECSuccess) {
    194        ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
    195        goto loser;
    196    }
    197 
    198    pubKey = keyPair->keys->pubKey;
    199    PRINT_BUF(50, (ss, "ECDH public value:",
    200                   pubKey->u.ec.publicValue.data,
    201                   pubKey->u.ec.publicValue.len));
    202 
    203    if (isTLS12) {
    204        target = CKM_TLS12_MASTER_KEY_DERIVE_DH;
    205    } else if (isTLS) {
    206        target = CKM_TLS_MASTER_KEY_DERIVE_DH;
    207    } else {
    208        target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
    209    }
    210 
    211    /* Determine the PMS */
    212    pms = PK11_PubDeriveWithKDF(keyPair->keys->privKey, svrPubKey,
    213                                PR_FALSE, NULL, NULL, CKM_ECDH1_DERIVE, target,
    214                                CKA_DERIVE, 0, CKD_NULL, NULL, NULL);
    215 
    216    if (pms == NULL) {
    217        (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
    218        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
    219        goto loser;
    220    }
    221 
    222    rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_client_key_exchange,
    223                                    pubKey->u.ec.publicValue.len + 1);
    224    if (rv != SECSuccess) {
    225        goto loser; /* err set by ssl3_AppendHandshake* */
    226    }
    227 
    228    rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.ec.publicValue.data,
    229                                      pubKey->u.ec.publicValue.len, 1);
    230 
    231    if (rv != SECSuccess) {
    232        goto loser; /* err set by ssl3_AppendHandshake* */
    233    }
    234 
    235    rv = ssl3_InitPendingCipherSpecs(ss, pms, PR_TRUE);
    236    if (rv != SECSuccess) {
    237        ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
    238        goto loser;
    239    }
    240 
    241    PK11_FreeSymKey(pms);
    242    ssl_FreeEphemeralKeyPair(keyPair);
    243    return SECSuccess;
    244 
    245 loser:
    246    if (pms)
    247        PK11_FreeSymKey(pms);
    248    if (keyPair)
    249        ssl_FreeEphemeralKeyPair(keyPair);
    250    return SECFailure;
    251 }
    252 
    253 /*
    254 ** Called from ssl3_HandleClientKeyExchange()
    255 */
    256 SECStatus
    257 ssl3_HandleECDHClientKeyExchange(sslSocket *ss, PRUint8 *b,
    258                                 PRUint32 length,
    259                                 sslKeyPair *serverKeyPair)
    260 {
    261    PK11SymKey *pms;
    262    SECStatus rv;
    263    SECKEYPublicKey clntPubKey;
    264    CK_MECHANISM_TYPE target;
    265    PRBool isTLS, isTLS12;
    266    int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH;
    267 
    268    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    269    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    270 
    271    clntPubKey.keyType = ecKey;
    272    clntPubKey.u.ec.DEREncodedParams.len =
    273        serverKeyPair->pubKey->u.ec.DEREncodedParams.len;
    274    clntPubKey.u.ec.DEREncodedParams.data =
    275        serverKeyPair->pubKey->u.ec.DEREncodedParams.data;
    276    clntPubKey.u.ec.encoding = ECPoint_Undefined;
    277 
    278    rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue,
    279                                       1, &b, &length);
    280    if (rv != SECSuccess) {
    281        PORT_SetError(errCode);
    282        return SECFailure;
    283    }
    284 
    285    /* we have to catch the case when the client's public key has length 0. */
    286    if (!clntPubKey.u.ec.publicValue.len) {
    287        (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
    288        PORT_SetError(errCode);
    289        return SECFailure;
    290    }
    291 
    292    isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
    293    isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
    294 
    295    if (isTLS12) {
    296        target = CKM_TLS12_MASTER_KEY_DERIVE_DH;
    297    } else if (isTLS) {
    298        target = CKM_TLS_MASTER_KEY_DERIVE_DH;
    299    } else {
    300        target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
    301    }
    302 
    303    /*  Determine the PMS */
    304    pms = PK11_PubDeriveWithKDF(serverKeyPair->privKey, &clntPubKey,
    305                                PR_FALSE, NULL, NULL,
    306                                CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
    307                                CKD_NULL, NULL, NULL);
    308 
    309    if (pms == NULL) {
    310        /* last gasp.  */
    311        errCode = ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
    312        PORT_SetError(errCode);
    313        return SECFailure;
    314    }
    315 
    316    rv = ssl3_InitPendingCipherSpecs(ss, pms, PR_TRUE);
    317    PK11_FreeSymKey(pms);
    318    if (rv != SECSuccess) {
    319        /* error code set by ssl3_InitPendingCipherSpec */
    320        return SECFailure;
    321    }
    322    ss->sec.keaGroup = ssl_ECPubKey2NamedGroup(&clntPubKey);
    323    return SECSuccess;
    324 }
    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 {
    334    SECStatus rv;
    335    SECItem ecPoint = { siBuffer, NULL, 0 };
    336 
    337    if (!length) {
    338        PORT_SetError(SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE);
    339        return SECFailure;
    340    }
    341 
    342    /* Fail if the ec point uses compressed representation */
    343    if (b[0] != EC_POINT_FORM_UNCOMPRESSED &&
    344        ecGroup->name != ssl_grp_ec_curve25519) {
    345        PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
    346        return SECFailure;
    347    }
    348 
    349    peerKey->keyType = ecKey;
    350    /* Set up the encoded params */
    351    rv = ssl_NamedGroup2ECParams(peerKey->arena, ecGroup,
    352                                 &peerKey->u.ec.DEREncodedParams);
    353    if (rv != SECSuccess) {
    354        ssl_MapLowLevelError(SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE);
    355        return SECFailure;
    356    }
    357    peerKey->u.ec.encoding = ECPoint_Undefined;
    358 
    359    /* copy publicValue in peerKey */
    360    ecPoint.data = b;
    361    ecPoint.len = length;
    362 
    363    rv = SECITEM_CopyItem(peerKey->arena, &peerKey->u.ec.publicValue, &ecPoint);
    364    if (rv != SECSuccess) {
    365        return SECFailure;
    366    }
    367 
    368    return SECSuccess;
    369 }
    370 
    371 const sslNamedGroupDef *
    372 ssl_GetECGroupWithStrength(sslSocket *ss, unsigned int requiredECCbits)
    373 {
    374    int i;
    375 
    376    PORT_Assert(ss);
    377 
    378    for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
    379        const sslNamedGroupDef *group = ss->namedGroupPreferences[i];
    380        if (group && group->keaType == ssl_kea_ecdh &&
    381            group->bits >= requiredECCbits) {
    382            return group;
    383        }
    384    }
    385 
    386    PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
    387    return NULL;
    388 }
    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 {
    395    const sslServerCert *cert = ss->sec.serverCert;
    396    unsigned int certKeySize;
    397    const ssl3BulkCipherDef *bulkCipher;
    398    unsigned int requiredECCbits;
    399 
    400    PORT_Assert(cert);
    401    if (!cert || !cert->serverKeyPair || !cert->serverKeyPair->pubKey) {
    402        PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
    403        return NULL;
    404    }
    405 
    406    if (SSL_CERT_IS(cert, ssl_auth_rsa_sign) ||
    407        SSL_CERT_IS(cert, ssl_auth_rsa_pss)) {
    408        certKeySize = SECKEY_PublicKeyStrengthInBits(cert->serverKeyPair->pubKey);
    409        certKeySize = SSL_RSASTRENGTH_TO_ECSTRENGTH(certKeySize);
    410    } 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        PORT_Assert(cert->namedCurve->keaType == ssl_kea_ecdh);
    414        PORT_Assert(ssl_NamedGroupEnabled(ss, cert->namedCurve));
    415        if (!ssl_NamedGroupEnabled(ss, cert->namedCurve)) {
    416            return NULL;
    417        }
    418        certKeySize = cert->namedCurve->bits;
    419    } else {
    420        PORT_Assert(0);
    421        return NULL;
    422    }
    423    bulkCipher = ssl_GetBulkCipherDef(ss->ssl3.hs.suite_def);
    424    requiredECCbits = bulkCipher->key_size * BPB * 2;
    425    PORT_Assert(requiredECCbits ||
    426                ss->ssl3.hs.suite_def->bulk_cipher_alg == cipher_null);
    427    if (requiredECCbits > certKeySize) {
    428        requiredECCbits = certKeySize;
    429    }
    430 
    431    return ssl_GetECGroupWithStrength(ss, requiredECCbits);
    432 }
    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 {
    444    SECKEYPrivateKey *privk = NULL;
    445    CK_MECHANISM_TYPE type = CKM_NSS_ECDHE_NO_PAIRWISE_CHECK_KEY_PAIR_GEN;
    446 
    447    PK11SlotInfo *slot = PK11_GetInternalSlot();
    448    if (!slot || !PK11_DoesMechanism(slot, type) || PK11_IsFIPS()) {
    449        if (slot) {
    450            PK11_FreeSlot(slot);
    451        }
    452        return SECKEY_CreateECPrivateKey(param, pubk, cx);
    453    }
    454 
    455    privk = PK11_GenerateKeyPairWithOpFlags(slot, type, param, pubk,
    456                                            PK11_ATTR_SESSION | PK11_ATTR_INSENSITIVE | PK11_ATTR_PUBLIC,
    457                                            CKF_DERIVE, CKF_DERIVE, cx);
    458    if (!privk) {
    459        privk = PK11_GenerateKeyPairWithOpFlags(slot, type, param, pubk,
    460                                                PK11_ATTR_SESSION | PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE,
    461                                                CKF_DERIVE, CKF_DERIVE, cx);
    462    }
    463 
    464    PK11_FreeSlot(slot);
    465    return privk;
    466 }
    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 {
    474    SECKEYPrivateKey *privKey = NULL;
    475    SECKEYPublicKey *pubKey = NULL;
    476    SECKEYECParams ecParams = { siBuffer, NULL, 0 };
    477    sslEphemeralKeyPair *pair;
    478 
    479    if (ssl_NamedGroup2ECParams(NULL, ecGroup, &ecParams) != SECSuccess) {
    480        return SECFailure;
    481    }
    482    privKey = ssl_CreateECDHEPrivateKey(&ecParams, &pubKey, ss->pkcs11PinArg);
    483    SECITEM_FreeItem(&ecParams, PR_FALSE);
    484 
    485    if (!privKey || !pubKey ||
    486        !(pair = ssl_NewEphemeralKeyPair(ecGroup, privKey, pubKey))) {
    487        if (privKey) {
    488            SECKEY_DestroyPrivateKey(privKey);
    489        }
    490        if (pubKey) {
    491            SECKEY_DestroyPublicKey(pubKey);
    492        }
    493        ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
    494        return SECFailure;
    495    }
    496 
    497    *keyPair = pair;
    498    SSL_TRC(50, ("%d: SSL[%d]: Create ECDH ephemeral key %d",
    499                 SSL_GETPID(), ss ? ss->fd : NULL, ecGroup->name));
    500    PRINT_BUF(50, (ss, "Public Key", pubKey->u.ec.publicValue.data,
    501                   pubKey->u.ec.publicValue.len));
    502 #ifdef TRACE
    503    if (ssl_trace >= 50) {
    504        SECItem d = { siBuffer, NULL, 0 };
    505        SECStatus rv = PK11_ReadRawAttribute(PK11_TypePrivKey, privKey,
    506                                             CKA_VALUE, &d);
    507        if (rv == SECSuccess) {
    508            PRINT_BUF(50, (ss, "Private Key", d.data, d.len));
    509            SECITEM_FreeItem(&d, PR_FALSE);
    510        } else {
    511            SSL_TRC(50, ("Error extracting private key"));
    512        }
    513    }
    514 #endif
    515    return SECSuccess;
    516 }
    517 
    518 SECStatus
    519 ssl3_HandleECDHServerKeyExchange(sslSocket *ss, PRUint8 *b, PRUint32 length)
    520 {
    521    PLArenaPool *arena = NULL;
    522    SECKEYPublicKey *peerKey = NULL;
    523    PRBool isTLS;
    524    SECStatus rv;
    525    int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
    526    SSL3AlertDescription desc = illegal_parameter;
    527    SSL3Hashes hashes;
    528    SECItem signature = { siBuffer, NULL, 0 };
    529    SSLHashType hashAlg;
    530    SSLSignatureScheme sigScheme;
    531 
    532    SECItem ec_params = { siBuffer, NULL, 0 };
    533    SECItem ec_point = { siBuffer, NULL, 0 };
    534    unsigned char paramBuf[3];
    535    const sslNamedGroupDef *ecGroup;
    536 
    537    isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
    538 
    539    ec_params.len = sizeof paramBuf;
    540    ec_params.data = paramBuf;
    541    rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length);
    542    if (rv != SECSuccess) {
    543        goto loser; /* malformed. */
    544    }
    545 
    546    /* Fail if the curve is not a named curve */
    547    if (ec_params.data[0] != ec_type_named) {
    548        errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
    549        desc = handshake_failure;
    550        goto alert_loser;
    551    }
    552    ecGroup = ssl_LookupNamedGroup(ec_params.data[1] << 8 | ec_params.data[2]);
    553    if (!ecGroup || ecGroup->keaType != ssl_kea_ecdh) {
    554        errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
    555        desc = handshake_failure;
    556        goto alert_loser;
    557    }
    558 
    559    rv = ssl3_ConsumeHandshakeVariable(ss, &ec_point, 1, &b, &length);
    560    if (rv != SECSuccess) {
    561        goto loser; /* malformed. */
    562    }
    563 
    564    /* Fail if the provided point has length 0. */
    565    if (!ec_point.len) {
    566        /* desc and errCode are initialized already */
    567        goto alert_loser;
    568    }
    569 
    570    /* Fail if the ec point is not uncompressed for any curve that's not 25519. */
    571    if (ecGroup->name != ssl_grp_ec_curve25519 &&
    572        ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
    573        errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM;
    574        desc = handshake_failure;
    575        goto alert_loser;
    576    }
    577 
    578    PORT_Assert(ss->ssl3.prSpec->version <= SSL_LIBRARY_VERSION_TLS_1_2);
    579    if (ss->ssl3.prSpec->version == SSL_LIBRARY_VERSION_TLS_1_2) {
    580        rv = ssl_ConsumeSignatureScheme(ss, &b, &length, &sigScheme);
    581        if (rv != SECSuccess) {
    582            errCode = PORT_GetError();
    583            goto alert_loser; /* malformed or unsupported. */
    584        }
    585        rv = ssl_CheckSignatureSchemeConsistency(
    586            ss, sigScheme, &ss->sec.peerCert->subjectPublicKeyInfo);
    587        if (rv != SECSuccess) {
    588            errCode = PORT_GetError();
    589            goto alert_loser;
    590        }
    591        hashAlg = ssl_SignatureSchemeToHashType(sigScheme);
    592    } else {
    593        /* Use ssl_hash_none to represent the MD5+SHA1 combo. */
    594        hashAlg = ssl_hash_none;
    595        sigScheme = ssl_sig_none;
    596    }
    597 
    598    rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
    599    if (rv != SECSuccess) {
    600        goto loser; /* malformed. */
    601    }
    602 
    603    if (length != 0) {
    604        if (isTLS)
    605            desc = decode_error;
    606        goto alert_loser; /* malformed. */
    607    }
    608 
    609    PRINT_BUF(60, (NULL, "Server EC params", ec_params.data, ec_params.len));
    610    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    desc = isTLS ? decrypt_error : handshake_failure;
    615 
    616    /*
    617     *  check to make sure the hash is signed by right guy
    618     */
    619    rv = ssl3_ComputeECDHKeyHash(hashAlg, ec_params, ec_point,
    620                                 ss->ssl3.hs.client_random,
    621                                 ss->ssl3.hs.server_random,
    622                                 &hashes);
    623 
    624    if (rv != SECSuccess) {
    625        errCode =
    626            ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
    627        goto alert_loser;
    628    }
    629    rv = ssl3_VerifySignedHashes(ss, sigScheme, &hashes, &signature);
    630    if (rv != SECSuccess) {
    631        errCode =
    632            ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
    633        goto alert_loser;
    634    }
    635 
    636    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    637    if (arena == NULL) {
    638        errCode = SEC_ERROR_NO_MEMORY;
    639        goto loser;
    640    }
    641 
    642    peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
    643    if (peerKey == NULL) {
    644        errCode = SEC_ERROR_NO_MEMORY;
    645        goto loser;
    646    }
    647    peerKey->arena = arena;
    648 
    649    /* create public key from point data */
    650    rv = ssl_ImportECDHKeyShare(peerKey, ec_point.data, ec_point.len,
    651                                ecGroup);
    652    if (rv != SECSuccess) {
    653        /* error code is set */
    654        desc = handshake_failure;
    655        errCode = PORT_GetError();
    656        goto alert_loser;
    657    }
    658    peerKey->pkcs11Slot = NULL;
    659    peerKey->pkcs11ID = CK_INVALID_HANDLE;
    660 
    661    ss->sec.peerKey = peerKey;
    662    return SECSuccess;
    663 
    664 alert_loser:
    665    (void)SSL3_SendAlert(ss, alert_fatal, desc);
    666 loser:
    667    if (arena) {
    668        PORT_FreeArena(arena, PR_FALSE);
    669    }
    670    PORT_SetError(errCode);
    671    return SECFailure;
    672 }
    673 
    674 SECStatus
    675 ssl3_SendECDHServerKeyExchange(sslSocket *ss)
    676 {
    677    SECStatus rv = SECFailure;
    678    int length;
    679    PRBool isTLS12;
    680    SECItem signed_hash = { siBuffer, NULL, 0 };
    681    SSLHashType hashAlg;
    682    SSL3Hashes hashes;
    683 
    684    SECItem ec_params = { siBuffer, NULL, 0 };
    685    unsigned char paramBuf[3];
    686    const sslNamedGroupDef *ecGroup;
    687    sslEphemeralKeyPair *keyPair;
    688    SECKEYPublicKey *pubKey;
    689 
    690    /* Generate ephemeral ECDH key pair and send the public key */
    691    ecGroup = ssl_GetECGroupForServerSocket(ss);
    692    if (!ecGroup) {
    693        goto loser;
    694    }
    695 
    696    PORT_Assert(PR_CLIST_IS_EMPTY(&ss->ephemeralKeyPairs));
    697    if (ss->opt.reuseServerECDHEKey) {
    698        rv = ssl_CreateStaticECDHEKey(ss, ecGroup);
    699        if (rv != SECSuccess) {
    700            goto loser;
    701        }
    702        keyPair = (sslEphemeralKeyPair *)PR_NEXT_LINK(&ss->ephemeralKeyPairs);
    703    } else {
    704        rv = ssl_CreateECDHEphemeralKeyPair(ss, ecGroup, &keyPair);
    705        if (rv != SECSuccess) {
    706            goto loser;
    707        }
    708        PR_APPEND_LINK(&keyPair->link, &ss->ephemeralKeyPairs);
    709    }
    710 
    711    PORT_Assert(keyPair);
    712    if (!keyPair) {
    713        PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
    714        return SECFailure;
    715    }
    716 
    717    ec_params.len = sizeof(paramBuf);
    718    ec_params.data = paramBuf;
    719    PORT_Assert(keyPair->group);
    720    PORT_Assert(keyPair->group->keaType == ssl_kea_ecdh);
    721    ec_params.data[0] = ec_type_named;
    722    ec_params.data[1] = keyPair->group->name >> 8;
    723    ec_params.data[2] = keyPair->group->name & 0xff;
    724 
    725    pubKey = keyPair->keys->pubKey;
    726    if (ss->version == SSL_LIBRARY_VERSION_TLS_1_2) {
    727        hashAlg = ssl_SignatureSchemeToHashType(ss->ssl3.hs.signatureScheme);
    728    } else {
    729        /* Use ssl_hash_none to represent the MD5+SHA1 combo. */
    730        hashAlg = ssl_hash_none;
    731    }
    732    rv = ssl3_ComputeECDHKeyHash(hashAlg, ec_params,
    733                                 pubKey->u.ec.publicValue,
    734                                 ss->ssl3.hs.client_random,
    735                                 ss->ssl3.hs.server_random,
    736                                 &hashes);
    737    if (rv != SECSuccess) {
    738        ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
    739        goto loser;
    740    }
    741 
    742    isTLS12 = (PRBool)(ss->version >= SSL_LIBRARY_VERSION_TLS_1_2);
    743 
    744    rv = ssl3_SignHashes(ss, &hashes,
    745                         ss->sec.serverCert->serverKeyPair->privKey, &signed_hash);
    746    if (rv != SECSuccess) {
    747        goto loser; /* ssl3_SignHashes has set err. */
    748    }
    749 
    750    length = ec_params.len +
    751             1 + pubKey->u.ec.publicValue.len +
    752             (isTLS12 ? 2 : 0) + 2 + signed_hash.len;
    753 
    754    rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_server_key_exchange, length);
    755    if (rv != SECSuccess) {
    756        goto loser; /* err set by AppendHandshake. */
    757    }
    758 
    759    rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len);
    760    if (rv != SECSuccess) {
    761        goto loser; /* err set by AppendHandshake. */
    762    }
    763 
    764    rv = ssl3_AppendHandshakeVariable(ss, pubKey->u.ec.publicValue.data,
    765                                      pubKey->u.ec.publicValue.len, 1);
    766    if (rv != SECSuccess) {
    767        goto loser; /* err set by AppendHandshake. */
    768    }
    769 
    770    if (isTLS12) {
    771        rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.signatureScheme, 2);
    772        if (rv != SECSuccess) {
    773            goto loser; /* err set by AppendHandshake. */
    774        }
    775    }
    776 
    777    rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
    778                                      signed_hash.len, 2);
    779    if (rv != SECSuccess) {
    780        goto loser; /* err set by AppendHandshake. */
    781    }
    782 
    783    PORT_Free(signed_hash.data);
    784    return SECSuccess;
    785 
    786 loser:
    787    if (signed_hash.data != NULL)
    788        PORT_Free(signed_hash.data);
    789    return SECFailure;
    790 }
    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 {
    856    const ssl3CipherSuite *suite;
    857 
    858    for (suite = list; *suite; ++suite) {
    859        PRBool enabled = PR_FALSE;
    860        SECStatus rv = ssl3_CipherPrefGet(ss, *suite, &enabled);
    861 
    862        PORT_Assert(rv == SECSuccess); /* else is coding error */
    863        if (rv == SECSuccess && enabled)
    864            return PR_TRUE;
    865    }
    866    return PR_FALSE;
    867 }
    868 
    869 /* Ask: is ANY ECC cipher suite enabled on this socket? */
    870 PRBool
    871 ssl_IsECCEnabled(const sslSocket *ss)
    872 {
    873    PK11SlotInfo *slot;
    874 
    875    /* make sure we can do ECC */
    876    slot = PK11_GetBestSlot(CKM_ECDH1_DERIVE, ss->pkcs11PinArg);
    877    if (!slot) {
    878        return PR_FALSE;
    879    }
    880    PK11_FreeSlot(slot);
    881 
    882    /* make sure an ECC cipher is enabled */
    883    return ssl_IsSuiteEnabled(ss, ssl_all_ec_suites);
    884 }
    885 
    886 PRBool
    887 ssl_IsDHEEnabled(const sslSocket *ss)
    888 {
    889    return ssl_IsSuiteEnabled(ss, ssl_dhe_suites);
    890 }
    891 
    892 /* Send our Supported Groups extension. */
    893 SECStatus
    894 ssl_SendSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
    895                           sslBuffer *buf, PRBool *added)
    896 {
    897    unsigned int i;
    898    PRBool ec;
    899    PRBool ec_hybrid = PR_FALSE;
    900    PRBool ff = PR_FALSE;
    901    PRBool found = PR_FALSE;
    902    SECStatus rv;
    903    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    if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) {
    908        ec = ssl_IsECCEnabled(ss);
    909        if (ss->opt.requireDHENamedGroups) {
    910            ff = ssl_IsDHEEnabled(ss);
    911        }
    912        if (!ec && !ff) {
    913            return SECSuccess;
    914        }
    915    } else {
    916        ec = ec_hybrid = ff = PR_TRUE;
    917    }
    918 
    919    /* Mark the location of the length. */
    920    rv = sslBuffer_Skip(buf, 2, &lengthOffset);
    921    if (rv != SECSuccess) {
    922        return SECFailure;
    923    }
    924 
    925    for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
    926        const sslNamedGroupDef *group = ss->namedGroupPreferences[i];
    927        if (!group) {
    928            continue;
    929        }
    930        if (group->keaType == ssl_kea_ecdh && !ec) {
    931            continue;
    932        }
    933        if (group->keaType == ssl_kea_ecdh_hybrid && !ec_hybrid) {
    934            continue;
    935        }
    936        if (group->keaType == ssl_kea_dh && !ff) {
    937            continue;
    938        }
    939 
    940        found = PR_TRUE;
    941        rv = sslBuffer_AppendNumber(buf, group->name, 2);
    942        if (rv != SECSuccess) {
    943            return SECFailure;
    944        }
    945    }
    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    if (!ss->sec.isServer &&
    952        ss->opt.enableGrease &&
    953        ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3) {
    954        rv = sslBuffer_AppendNumber(buf, ss->ssl3.hs.grease->idx[grease_group], 2);
    955        if (rv != SECSuccess) {
    956            return SECFailure;
    957        }
    958        found = PR_TRUE;
    959    }
    960 
    961    if (!found) {
    962        /* We added nothing, don't send the extension. */
    963        return SECSuccess;
    964    }
    965 
    966    rv = sslBuffer_InsertLength(buf, lengthOffset, 2);
    967    if (rv != SECSuccess) {
    968        return SECFailure;
    969    }
    970 
    971    *added = PR_TRUE;
    972    return SECSuccess;
    973 }
    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 {
    982    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    if (!ss || !ssl_IsECCEnabled(ss) ||
    988        ss->vrange.min >= SSL_LIBRARY_VERSION_TLS_1_3 ||
    989        (ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3)) {
    990        return SECSuccess;
    991    }
    992    rv = sslBuffer_AppendNumber(buf, 1, 1); /* length */
    993    if (rv != SECSuccess) {
    994        return SECFailure;
    995    }
    996    rv = sslBuffer_AppendNumber(buf, 0, 1); /* uncompressed type only */
    997    if (rv != SECSuccess) {
    998        return SECFailure;
    999    }
   1000 
   1001    *added = PR_TRUE;
   1002    return SECSuccess;
   1003 }