/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * TLS 1.3 Protocol
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "stdarg.h"
#include "cert.h"
#include "ssl.h"
#include "keyhi.h"
#include "pk11func.h"
#include "prerr.h"
#include "secitem.h"
#include "secmod.h"
#include "sslimpl.h"
#include "sslproto.h"
#include "sslerr.h"
#include "ssl3exthandle.h"
#include "tls13hkdf.h"
#include "tls13con.h"
#include "tls13err.h"
#include "tls13esni.h"
#include "tls13exthandle.h"
#include "tls13hashstate.h"

static SECStatus tls13_SetCipherSpec(sslSocket *ss, PRUint16 epoch,
                                     CipherSpecDirection install,
                                     PRBool deleteSecret);
static SECStatus tls13_AESGCM(
    ssl3KeyMaterial *keys,
    PRBool doDecrypt,
    unsigned char *out, int *outlen, int maxout,
    const unsigned char *in, int inlen,
    const unsigned char *additionalData, int additionalDataLen);
static SECStatus tls13_ChaCha20Poly1305(
    ssl3KeyMaterial *keys,
    PRBool doDecrypt,
    unsigned char *out, int *outlen, int maxout,
    const unsigned char *in, int inlen,
    const unsigned char *additionalData, int additionalDataLen);
static SECStatus tls13_SendServerHelloSequence(sslSocket *ss);
static SECStatus tls13_SendEncryptedExtensions(sslSocket *ss);
static void tls13_SetKeyExchangeType(sslSocket *ss, const sslNamedGroupDef *group);
static SECStatus tls13_HandleClientKeyShare(sslSocket *ss,
                                            TLS13KeyShareEntry *peerShare);
static SECStatus tls13_SendHelloRetryRequest(
    sslSocket *ss, const sslNamedGroupDef *selectedGroup,
    const PRUint8 *token, unsigned int tokenLen);

static SECStatus tls13_HandleServerKeyShare(sslSocket *ss);
static SECStatus tls13_HandleEncryptedExtensions(sslSocket *ss, PRUint8 *b,
                                                 PRUint32 length);
static SECStatus tls13_SendCertificate(sslSocket *ss);
static SECStatus tls13_HandleCertificate(
    sslSocket *ss, PRUint8 *b, PRUint32 length);
static SECStatus tls13_ReinjectHandshakeTranscript(sslSocket *ss);
static SECStatus tls13_HandleCertificateRequest(sslSocket *ss, PRUint8 *b,
                                                PRUint32 length);
static SECStatus
tls13_SendCertificateVerify(sslSocket *ss, SECKEYPrivateKey *privKey);
static SECStatus tls13_HandleCertificateVerify(
    sslSocket *ss, PRUint8 *b, PRUint32 length);
static SECStatus tls13_RecoverWrappedSharedSecret(sslSocket *ss,
                                                  sslSessionID *sid);
static SECStatus
tls13_DeriveSecretWrap(sslSocket *ss, PK11SymKey *key,
                       const char *prefix,
                       const char *suffix,
                       const char *keylogLabel,
                       PK11SymKey **dest);
static SECStatus
tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key,
                   const char *label,
                   unsigned int labelLen,
                   const SSL3Hashes *hashes,
                   PK11SymKey **dest);
static SECStatus tls13_SendEndOfEarlyData(sslSocket *ss);
static SECStatus tls13_HandleEndOfEarlyData(sslSocket *ss, PRUint8 *b,
                                            PRUint32 length);
static SECStatus tls13_SendFinished(sslSocket *ss, PK11SymKey *baseKey);
static SECStatus tls13_ComputePskBinderHash(sslSocket *ss, unsigned int prefix,
                                            SSL3Hashes *hashes);
static SECStatus tls13_VerifyFinished(sslSocket *ss, SSLHandshakeType message,
                                      PK11SymKey *secret,
                                      PRUint8 *b, PRUint32 length,
                                      const SSL3Hashes *hashes);
static SECStatus tls13_ClientHandleFinished(sslSocket *ss,
                                            PRUint8 *b, PRUint32 length);
static SECStatus tls13_ServerHandleFinished(sslSocket *ss,
                                            PRUint8 *b, PRUint32 length);
static SECStatus tls13_SendNewSessionTicket(sslSocket *ss,
                                            const PRUint8 *appToken,
                                            unsigned int appTokenLen);
static SECStatus tls13_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b,
                                              PRUint32 length);
static SECStatus tls13_ComputeEarlySecrets(sslSocket *ss);
static SECStatus tls13_ComputeHandshakeSecrets(sslSocket *ss);
static SECStatus tls13_ComputeApplicationSecrets(sslSocket *ss);
static SECStatus tls13_ComputeFinalSecrets(sslSocket *ss);
static SECStatus tls13_ComputeFinished(
    sslSocket *ss, PK11SymKey *baseKey, const SSL3Hashes *hashes,
    PRBool sending, PRUint8 *output, unsigned int *outputLen,
    unsigned int maxOutputLen);
static SECStatus tls13_SendClientSecondRound(sslSocket *ss);
static SECStatus tls13_FinishHandshake(sslSocket *ss);

const char kHkdfLabelClient[] = "c";
const char kHkdfLabelServer[] = "s";
const char kHkdfLabelDerivedSecret[] = "derived";
const char kHkdfLabelPskBinderKey[] = "res binder";
const char kHkdfLabelEarlyTrafficSecret[] = "e traffic";
const char kHkdfLabelEarlyExporterSecret[] = "e exp master";
const char kHkdfLabelHandshakeTrafficSecret[] = "hs traffic";
const char kHkdfLabelApplicationTrafficSecret[] = "ap traffic";
const char kHkdfLabelFinishedSecret[] = "finished";
const char kHkdfLabelResumptionMasterSecret[] = "res master";
const char kHkdfLabelExporterMasterSecret[] = "exp master";
const char kHkdfLabelResumption[] = "resumption";
const char kHkdfLabelTrafficUpdate[] = "traffic upd";
const char kHkdfPurposeKey[] = "key";
const char kHkdfPurposeIv[] = "iv";

const char keylogLabelClientEarlyTrafficSecret[] = "CLIENT_EARLY_TRAFFIC_SECRET";
const char keylogLabelClientHsTrafficSecret[] = "CLIENT_HANDSHAKE_TRAFFIC_SECRET";
const char keylogLabelServerHsTrafficSecret[] = "SERVER_HANDSHAKE_TRAFFIC_SECRET";
const char keylogLabelClientTrafficSecret[] = "CLIENT_TRAFFIC_SECRET_0";
const char keylogLabelServerTrafficSecret[] = "SERVER_TRAFFIC_SECRET_0";
const char keylogLabelEarlyExporterSecret[] = "EARLY_EXPORTER_SECRET";
const char keylogLabelExporterSecret[] = "EXPORTER_SECRET";

/* Belt and suspenders in case we ever add a TLS 1.4. */
PR_STATIC_ASSERT(SSL_LIBRARY_VERSION_MAX_SUPPORTED <=
                 SSL_LIBRARY_VERSION_TLS_1_3);

void
tls13_FatalError(sslSocket *ss, PRErrorCode prError, SSL3AlertDescription desc)
{
    PORT_Assert(desc != internal_error); /* These should never happen */
    (void)SSL3_SendAlert(ss, alert_fatal, desc);
    PORT_SetError(prError);
}

#ifdef TRACE
#define STATE_CASE(a) \
    case a:           \
        return #a
static char *
tls13_HandshakeState(SSL3WaitState st)
{
    switch (st) {
        STATE_CASE(idle_handshake);
        STATE_CASE(wait_client_hello);
        STATE_CASE(wait_end_of_early_data);
        STATE_CASE(wait_client_cert);
        STATE_CASE(wait_client_key);
        STATE_CASE(wait_cert_verify);
        STATE_CASE(wait_change_cipher);
        STATE_CASE(wait_finished);
        STATE_CASE(wait_server_hello);
        STATE_CASE(wait_certificate_status);
        STATE_CASE(wait_server_cert);
        STATE_CASE(wait_server_key);
        STATE_CASE(wait_cert_request);
        STATE_CASE(wait_hello_done);
        STATE_CASE(wait_new_session_ticket);
        STATE_CASE(wait_encrypted_extensions);
        default:
            break;
    }
    PORT_Assert(0);
    return "unknown";
}
#endif

#define TLS13_WAIT_STATE_MASK 0x80

#define TLS13_BASE_WAIT_STATE(ws) (ws & ~TLS13_WAIT_STATE_MASK)
/* We don't mask idle_handshake because other parts of the code use it*/
#define TLS13_WAIT_STATE(ws) (((ws == idle_handshake) || (ws == wait_server_hello)) ? ws : ws | TLS13_WAIT_STATE_MASK)
#define TLS13_CHECK_HS_STATE(ss, err, ...)                          \
    tls13_CheckHsState(ss, err, #err, __func__, __FILE__, __LINE__, \
                       __VA_ARGS__,                                 \
                       wait_invalid)
void
tls13_SetHsState(sslSocket *ss, SSL3WaitState ws,
                 const char *func, const char *file, int line)
{
#ifdef TRACE
    const char *new_state_name =
        tls13_HandshakeState(ws);

    SSL_TRC(3, ("%d: TLS13[%d]: %s state change from %s->%s in %s (%s:%d)",
                SSL_GETPID(), ss->fd, SSL_ROLE(ss),
                tls13_HandshakeState(TLS13_BASE_WAIT_STATE(ss->ssl3.hs.ws)),
                new_state_name,
                func, file, line));
#endif

    ss->ssl3.hs.ws = TLS13_WAIT_STATE(ws);
}

static PRBool
tls13_InHsStateV(sslSocket *ss, va_list ap)
{
    SSL3WaitState ws;

    while ((ws = va_arg(ap, SSL3WaitState)) != wait_invalid) {
        if (TLS13_WAIT_STATE(ws) == ss->ssl3.hs.ws) {
            return PR_TRUE;
        }
    }
    return PR_FALSE;
}

PRBool
tls13_InHsState(sslSocket *ss, ...)
{
    PRBool found;
    va_list ap;

    va_start(ap, ss);
    found = tls13_InHsStateV(ss, ap);
    va_end(ap);

    return found;
}

static SECStatus
tls13_CheckHsState(sslSocket *ss, int err, const char *error_name,
                   const char *func, const char *file, int line,
                   ...)
{
    va_list ap;
    va_start(ap, line);
    if (tls13_InHsStateV(ss, ap)) {
        va_end(ap);
        return SECSuccess;
    }
    va_end(ap);

    SSL_TRC(3, ("%d: TLS13[%d]: error %s state is (%s) at %s (%s:%d)",
                SSL_GETPID(), ss->fd,
                error_name,
                tls13_HandshakeState(TLS13_BASE_WAIT_STATE(ss->ssl3.hs.ws)),
                func, file, line));
    tls13_FatalError(ss, err, unexpected_message);
    return SECFailure;
}

SSLHashType
tls13_GetHashForCipherSuite(ssl3CipherSuite suite)
{
    const ssl3CipherSuiteDef *cipherDef =
        ssl_LookupCipherSuiteDef(suite);
    PORT_Assert(cipherDef);
    if (!cipherDef) {
        return ssl_hash_none;
    }
    return cipherDef->prf_hash;
}

SSLHashType
tls13_GetHash(const sslSocket *ss)
{
    /* All TLS 1.3 cipher suites must have an explict PRF hash. */
    PORT_Assert(ss->ssl3.hs.suite_def->prf_hash != ssl_hash_none);
    return ss->ssl3.hs.suite_def->prf_hash;
}

unsigned int
tls13_GetHashSizeForHash(SSLHashType hash)
{
    switch (hash) {
        case ssl_hash_sha256:
            return 32;
        case ssl_hash_sha384:
            return 48;
        default:
            PORT_Assert(0);
    }
    return 32;
}

unsigned int
tls13_GetHashSize(const sslSocket *ss)
{
    return tls13_GetHashSizeForHash(tls13_GetHash(ss));
}

static CK_MECHANISM_TYPE
tls13_GetHkdfMechanismForHash(SSLHashType hash)
{
    switch (hash) {
        case ssl_hash_sha256:
            return CKM_NSS_HKDF_SHA256;
        case ssl_hash_sha384:
            return CKM_NSS_HKDF_SHA384;
        default:
            PORT_Assert(0);
    }
    return CKM_NSS_HKDF_SHA256;
}

CK_MECHANISM_TYPE
tls13_GetHkdfMechanism(sslSocket *ss)
{
    return tls13_GetHkdfMechanismForHash(tls13_GetHash(ss));
}

static CK_MECHANISM_TYPE
tls13_GetHmacMechanism(sslSocket *ss)
{
    switch (tls13_GetHash(ss)) {
        case ssl_hash_sha256:
            return CKM_SHA256_HMAC;
        case ssl_hash_sha384:
            return CKM_SHA384_HMAC;
        default:
            PORT_Assert(0);
    }
    return CKM_SHA256_HMAC;
}

SECStatus
tls13_ComputeHash(sslSocket *ss, SSL3Hashes *hashes,
                  const PRUint8 *buf, unsigned int len)
{
    SECStatus rv;

    rv = PK11_HashBuf(ssl3_HashTypeToOID(tls13_GetHash(ss)),
                      hashes->u.raw, buf, len);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        return SECFailure;
    }
    hashes->len = tls13_GetHashSize(ss);

    return SECSuccess;
}

SECStatus
tls13_CreateKeyShare(sslSocket *ss, const sslNamedGroupDef *groupDef,
                     sslEphemeralKeyPair **keyPair)
{
    SECStatus rv;
    const ssl3DHParams *params;

    PORT_Assert(groupDef);
    switch (groupDef->keaType) {
        case ssl_kea_ecdh:
            rv = ssl_CreateECDHEphemeralKeyPair(ss, groupDef, keyPair);
            if (rv != SECSuccess) {
                return SECFailure;
            }
            break;
        case ssl_kea_dh:
            params = ssl_GetDHEParams(groupDef);
            PORT_Assert(params->name != ssl_grp_ffdhe_custom);
            rv = ssl_CreateDHEKeyPair(groupDef, params, keyPair);
            if (rv != SECSuccess) {
                return SECFailure;
            }
            break;
        default:
            PORT_Assert(0);
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
            return SECFailure;
    }

    return rv;
}

SECStatus
tls13_AddKeyShare(sslSocket *ss, const sslNamedGroupDef *groupDef)
{
    sslEphemeralKeyPair *keyPair = NULL;
    SECStatus rv;

    rv = tls13_CreateKeyShare(ss, groupDef, &keyPair);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    PR_APPEND_LINK(&keyPair->link, &ss->ephemeralKeyPairs);
    return SECSuccess;
}

SECStatus
SSL_SendAdditionalKeyShares(PRFileDesc *fd, unsigned int count)
{
    sslSocket *ss = ssl_FindSocket(fd);
    if (!ss) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    ss->additionalShares = count;
    return SECSuccess;
}

/*
 * Generate shares for ECDHE and FFDHE.  This picks the first enabled group of
 * the requisite type and creates a share for that.
 *
 * Called from ssl3_SendClientHello.
 */
SECStatus
tls13_SetupClientHello(sslSocket *ss)
{
    unsigned int i;
    SSL3Statistics *ssl3stats = SSL_GetStatistics();
    NewSessionTicket *session_ticket = NULL;
    sslSessionID *sid = ss->sec.ci.sid;
    unsigned int numShares = 0;
    SECStatus rv;

    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
    PORT_Assert(PR_CLIST_IS_EMPTY(&ss->ephemeralKeyPairs));

    /* Do encrypted SNI. This may create a key share as a side effect. */
    rv = tls13_ClientSetupESNI(ss);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    /* Select the first enabled group.
     * TODO(ekr@rtfm.com): be smarter about offering the group
     * that the other side negotiated if we are resuming. */
    for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
        if (!ss->namedGroupPreferences[i]) {
            continue;
        }
        rv = tls13_AddKeyShare(ss, ss->namedGroupPreferences[i]);
        if (rv != SECSuccess) {
            return SECFailure;
        }
        if (++numShares > ss->additionalShares) {
            break;
        }
    }

    if (PR_CLIST_IS_EMPTY(&ss->ephemeralKeyPairs)) {
        PORT_SetError(SSL_ERROR_NO_CIPHERS_SUPPORTED);
        return SECFailure;
    }

    /* Below here checks if we can do stateless resumption. */
    if (sid->cached == never_cached ||
        sid->version < SSL_LIBRARY_VERSION_TLS_1_3) {
        return SECSuccess;
    }

    /* The caller must be holding sid->u.ssl3.lock for reading. */
    session_ticket = &sid->u.ssl3.locked.sessionTicket;
    PORT_Assert(session_ticket && session_ticket->ticket.data);

    if (ssl_TicketTimeValid(session_ticket)) {
        ss->statelessResume = PR_TRUE;
    }

    if (ss->statelessResume) {
        PORT_Assert(ss->sec.ci.sid);
        rv = tls13_RecoverWrappedSharedSecret(ss, ss->sec.ci.sid);
        if (rv != SECSuccess) {
            FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
            SSL_AtomicIncrementLong(&ssl3stats->sch_sid_cache_not_ok);
            ssl_UncacheSessionID(ss);
            ssl_FreeSID(ss->sec.ci.sid);
            ss->sec.ci.sid = NULL;
            return SECFailure;
        }

        ss->ssl3.hs.cipher_suite = ss->sec.ci.sid->u.ssl3.cipherSuite;
        rv = ssl3_SetupCipherSuite(ss, PR_FALSE);
        if (rv != SECSuccess) {
            FATAL_ERROR(ss, PORT_GetError(), internal_error);
            return SECFailure;
        }

        rv = tls13_ComputeEarlySecrets(ss);
        if (rv != SECSuccess) {
            FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
            return SECFailure;
        }
    }

    return SECSuccess;
}

static SECStatus
tls13_ImportDHEKeyShare(SECKEYPublicKey *peerKey,
                        PRUint8 *b, PRUint32 length,
                        SECKEYPublicKey *pubKey)
{
    SECStatus rv;
    SECItem publicValue = { siBuffer, NULL, 0 };

    publicValue.data = b;
    publicValue.len = length;
    if (!ssl_IsValidDHEShare(&pubKey->u.dh.prime, &publicValue)) {
        PORT_SetError(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
        return SECFailure;
    }

    peerKey->keyType = dhKey;
    rv = SECITEM_CopyItem(peerKey->arena, &peerKey->u.dh.prime,
                          &pubKey->u.dh.prime);
    if (rv != SECSuccess)
        return SECFailure;
    rv = SECITEM_CopyItem(peerKey->arena, &peerKey->u.dh.base,
                          &pubKey->u.dh.base);
    if (rv != SECSuccess)
        return SECFailure;
    rv = SECITEM_CopyItem(peerKey->arena, &peerKey->u.dh.publicValue,
                          &publicValue);
    if (rv != SECSuccess)
        return SECFailure;

    return SECSuccess;
}

SECStatus
tls13_HandleKeyShare(sslSocket *ss,
                     TLS13KeyShareEntry *entry,
                     sslKeyPair *keyPair,
                     SSLHashType hash,
                     PK11SymKey **out)
{
    PORTCheapArenaPool arena;
    SECKEYPublicKey *peerKey;
    CK_MECHANISM_TYPE mechanism;
    PRErrorCode errorCode;
    PK11SymKey *key;
    SECStatus rv;
    int keySize = 0;

    PORT_InitCheapArena(&arena, DER_DEFAULT_CHUNKSIZE);
    peerKey = PORT_ArenaZNew(&arena.arena, SECKEYPublicKey);
    if (peerKey == NULL) {
        goto loser;
    }
    peerKey->arena = &arena.arena;
    peerKey->pkcs11Slot = NULL;
    peerKey->pkcs11ID = CK_INVALID_HANDLE;

    switch (entry->group->keaType) {
        case ssl_kea_ecdh:
            rv = ssl_ImportECDHKeyShare(peerKey,
                                        entry->key_exchange.data,
                                        entry->key_exchange.len,
                                        entry->group);
            mechanism = CKM_ECDH1_DERIVE;
            break;
        case ssl_kea_dh:
            rv = tls13_ImportDHEKeyShare(peerKey,
                                         entry->key_exchange.data,
                                         entry->key_exchange.len,
                                         keyPair->pubKey);
            mechanism = CKM_DH_PKCS_DERIVE;
            keySize = peerKey->u.dh.publicValue.len;
            break;
        default:
            PORT_Assert(0);
            goto loser;
    }
    if (rv != SECSuccess) {
        goto loser;
    }

    key = PK11_PubDeriveWithKDF(
        keyPair->privKey, peerKey, PR_FALSE, NULL, NULL, mechanism,
        tls13_GetHkdfMechanismForHash(hash), CKA_DERIVE, keySize, CKD_NULL, NULL, NULL);
    if (!key) {
        ssl_MapLowLevelError(SSL_ERROR_KEY_EXCHANGE_FAILURE);
        goto loser;
    }
    *out = key;
    PORT_DestroyCheapArena(&arena);
    return SECSuccess;

loser:
    PORT_DestroyCheapArena(&arena);
    errorCode = PORT_GetError(); /* don't overwrite the error code */
    tls13_FatalError(ss, errorCode, illegal_parameter);
    return SECFailure;
}

static PRBool
tls13_UseServerSecret(sslSocket *ss, CipherSpecDirection direction)
{
    return ss->sec.isServer == (direction == CipherSpecWrite);
}

static PK11SymKey **
tls13_TrafficSecretRef(sslSocket *ss, CipherSpecDirection direction)
{
    if (tls13_UseServerSecret(ss, direction)) {
        return &ss->ssl3.hs.serverTrafficSecret;
    }
    return &ss->ssl3.hs.clientTrafficSecret;
}

SECStatus
tls13_UpdateTrafficKeys(sslSocket *ss, CipherSpecDirection direction)
{
    PK11SymKey **secret;
    PK11SymKey *updatedSecret;
    PRUint16 epoch;
    SECStatus rv;

    secret = tls13_TrafficSecretRef(ss, direction);
    rv = tls13_HkdfExpandLabel(*secret, tls13_GetHash(ss),
                               NULL, 0,
                               kHkdfLabelTrafficUpdate,
                               strlen(kHkdfLabelTrafficUpdate),
                               tls13_GetHmacMechanism(ss),
                               tls13_GetHashSize(ss),
                               &updatedSecret);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    PK11_FreeSymKey(*secret);
    *secret = updatedSecret;

    ssl_GetSpecReadLock(ss);
    if (direction == CipherSpecRead) {
        epoch = ss->ssl3.crSpec->epoch;
    } else {
        epoch = ss->ssl3.cwSpec->epoch;
    }
    ssl_ReleaseSpecReadLock(ss);

    if (epoch == PR_UINT16_MAX) {
        /* Good chance that this is an overflow from too many updates. */
        FATAL_ERROR(ss, SSL_ERROR_TOO_MANY_KEY_UPDATES, internal_error);
        return SECFailure;
    }
    ++epoch;

    rv = tls13_SetCipherSpec(ss, epoch, direction, PR_FALSE);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        return SECFailure;
    }

    return SECSuccess;
}

SECStatus
tls13_SendKeyUpdate(sslSocket *ss, tls13KeyUpdateRequest request, PRBool buffer)
{
    SECStatus rv;

    SSL_TRC(3, ("%d: TLS13[%d]: %s send key update, response %s",
                SSL_GETPID(), ss->fd, SSL_ROLE(ss),
                (request == update_requested) ? "requested"
                                              : "not requested"));

    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    if (!ss->firstHsDone) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    rv = TLS13_CHECK_HS_STATE(ss, SEC_ERROR_LIBRARY_FAILURE,
                              idle_handshake);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    /* Not supported. */
    if (IS_DTLS(ss)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    ssl_GetXmitBufLock(ss);
    rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_key_update, 1);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        goto loser;
    }
    rv = ssl3_AppendHandshakeNumber(ss, request, 1);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        goto loser;
    }

    /* If we have been asked to buffer, then do so.  This allows us to coalesce
     * a KeyUpdate with a pending write. */
    rv = ssl3_FlushHandshake(ss, buffer ? ssl_SEND_FLAG_FORCE_INTO_BUFFER : 0);
    if (rv != SECSuccess) {
        goto loser; /* error code set by ssl3_FlushHandshake */
    }
    ssl_ReleaseXmitBufLock(ss);

    rv = tls13_UpdateTrafficKeys(ss, CipherSpecWrite);
    if (rv != SECSuccess) {
        goto loser; /* error code set by tls13_UpdateTrafficKeys */
    }

    return SECSuccess;

loser:
    ssl_ReleaseXmitBufLock(ss);
    return SECFailure;
}

SECStatus
SSLExp_KeyUpdate(PRFileDesc *fd, PRBool requestUpdate)
{
    SECStatus rv;
    sslSocket *ss = ssl_FindSocket(fd);
    if (!ss) {
        return SECFailure;
    }

    if (!ss->firstHsDone) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    rv = TLS13_CHECK_HS_STATE(ss, SEC_ERROR_INVALID_ARGS,
                              idle_handshake);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    ssl_GetSSL3HandshakeLock(ss);
    rv = tls13_SendKeyUpdate(ss, requestUpdate ? update_requested : update_not_requested,
                             PR_FALSE /* don't buffer */);

    /* Remember that we are the ones that initiated this KeyUpdate. */
    if (rv == SECSuccess) {
        ss->ssl3.peerRequestedKeyUpdate = PR_FALSE;
    }
    ssl_ReleaseSSL3HandshakeLock(ss);
    return rv;
}

/*
 * enum {
 *     update_not_requested(0), update_requested(1), (255)
 * } KeyUpdateRequest;
 *
 * struct {
 *     KeyUpdateRequest request_update;
 * } KeyUpdate;
 */
static SECStatus
tls13_HandleKeyUpdate(sslSocket *ss, PRUint8 *b, unsigned int length)
{
    SECStatus rv;
    PRUint32 update;

    SSL_TRC(3, ("%d: TLS13[%d]: %s handle key update",
                SSL_GETPID(), ss->fd, SSL_ROLE(ss)));

    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    PORT_Assert(ss->firstHsDone);
    if (!ss->firstHsDone) {
        FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE, unexpected_message);
        return SECFailure;
    }

    rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE,
                              idle_handshake);
    if (rv != SECSuccess) {
        /* We should never be idle_handshake prior to firstHsDone. */
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        return SECFailure;
    }

    rv = ssl3_ConsumeHandshakeNumber(ss, &update, 1, &b, &length);
    if (rv != SECSuccess) {
        return SECFailure; /* Error code set already. */
    }
    if (length != 0) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_KEY_UPDATE, decode_error);
        return SECFailure;
    }
    if (!(update == update_requested ||
          update == update_not_requested)) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_KEY_UPDATE, decode_error);
        return SECFailure;
    }

    rv = tls13_UpdateTrafficKeys(ss, CipherSpecRead);
    if (rv != SECSuccess) {
        return SECFailure; /* Error code set by tls13_UpdateTrafficKeys. */
    }

    if (update == update_requested) {
        PRBool sendUpdate;
        if (ss->ssl3.peerRequestedKeyUpdate) {
            /* Only send an update if we have sent with the current spec.  This
             * prevents us from being forced to crank forward pointlessly. */
            ssl_GetSpecReadLock(ss);
            sendUpdate = ss->ssl3.cwSpec->nextSeqNum > 0;
            ssl_ReleaseSpecReadLock(ss);
        } else {
            sendUpdate = PR_TRUE;
        }
        if (sendUpdate) {
            /* Respond immediately (don't buffer). */
            rv = tls13_SendKeyUpdate(ss, update_not_requested, PR_FALSE);
            if (rv != SECSuccess) {
                return SECFailure; /* Error already set. */
            }
        }
        ss->ssl3.peerRequestedKeyUpdate = PR_TRUE;
    }

    return SECSuccess;
}

SECStatus
tls13_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
    if (ss->sec.isServer && ss->ssl3.hs.zeroRttIgnore != ssl_0rtt_ignore_none) {
        SSL_TRC(3, ("%d: TLS13[%d]: %s successfully decrypted handshake after"
                    "failed 0-RTT",
                    SSL_GETPID(), ss->fd));
        ss->ssl3.hs.zeroRttIgnore = ssl_0rtt_ignore_none;
    }

    /* TODO(ekr@rtfm.com): Would it be better to check all the states here? */
    switch (ss->ssl3.hs.msg_type) {
        case ssl_hs_certificate:
            return tls13_HandleCertificate(ss, b, length);

        case ssl_hs_certificate_request:
            return tls13_HandleCertificateRequest(ss, b, length);

        case ssl_hs_certificate_verify:
            return tls13_HandleCertificateVerify(ss, b, length);

        case ssl_hs_encrypted_extensions:
            return tls13_HandleEncryptedExtensions(ss, b, length);

        case ssl_hs_new_session_ticket:
            return tls13_HandleNewSessionTicket(ss, b, length);

        case ssl_hs_finished:
            if (ss->sec.isServer) {
                return tls13_ServerHandleFinished(ss, b, length);
            } else {
                return tls13_ClientHandleFinished(ss, b, length);
            }

        case ssl_hs_end_of_early_data:
            return tls13_HandleEndOfEarlyData(ss, b, length);

        case ssl_hs_key_update:
            return tls13_HandleKeyUpdate(ss, b, length);

        default:
            FATAL_ERROR(ss, SSL_ERROR_RX_UNKNOWN_HANDSHAKE, unexpected_message);
            return SECFailure;
    }

    PORT_Assert(0); /* Unreached */
    return SECFailure;
}

static SECStatus
tls13_RecoverWrappedSharedSecret(sslSocket *ss, sslSessionID *sid)
{
    PK11SymKey *wrapKey; /* wrapping key */
    SECItem wrappedMS = { siBuffer, NULL, 0 };
    SSLHashType hashType;

    SSL_TRC(3, ("%d: TLS13[%d]: recovering static secret (%s)",
                SSL_GETPID(), ss->fd, SSL_ROLE(ss)));

    /* Now find the hash used as the PRF for the previous handshake. */
    hashType = tls13_GetHashForCipherSuite(sid->u.ssl3.cipherSuite);

    /* If we are the server, we compute the wrapping key, but if we
     * are the client, its coordinates are stored with the ticket. */
    if (ss->sec.isServer) {
        wrapKey = ssl3_GetWrappingKey(ss, NULL,
                                      sid->u.ssl3.masterWrapMech,
                                      ss->pkcs11PinArg);
    } else {
        PK11SlotInfo *slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
                                               sid->u.ssl3.masterSlotID);
        if (!slot)
            return SECFailure;

        wrapKey = PK11_GetWrapKey(slot,
                                  sid->u.ssl3.masterWrapIndex,
                                  sid->u.ssl3.masterWrapMech,
                                  sid->u.ssl3.masterWrapSeries,
                                  ss->pkcs11PinArg);
        PK11_FreeSlot(slot);
    }
    if (!wrapKey) {
        return SECFailure;
    }

    wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
    wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;

    /* unwrap the "master secret" which is actually RMS. */
    ss->ssl3.hs.resumptionMasterSecret = PK11_UnwrapSymKeyWithFlags(
        wrapKey, sid->u.ssl3.masterWrapMech,
        NULL, &wrappedMS,
        CKM_SSL3_MASTER_KEY_DERIVE,
        CKA_DERIVE,
        tls13_GetHashSizeForHash(hashType),
        CKF_SIGN | CKF_VERIFY);
    PK11_FreeSymKey(wrapKey);
    if (!ss->ssl3.hs.resumptionMasterSecret) {
        return SECFailure;
    }

    PRINT_KEY(50, (ss, "Recovered RMS", ss->ssl3.hs.resumptionMasterSecret));

    return SECSuccess;
}

/* Key Derivation Functions.
 *
 *                 0
 *                 |
 *                 v
 *   PSK ->  HKDF-Extract = Early Secret
 *                 |
 *                 +-----> Derive-Secret(., "ext binder" | "res binder", "")
 *                 |                     = binder_key
 *                 |
 *                 +-----> Derive-Secret(., "c e traffic",
 *                 |                     ClientHello)
 *                 |                     = client_early_traffic_secret
 *                 |
 *                 +-----> Derive-Secret(., "e exp master",
 *                 |                     ClientHello)
 *                 |                     = early_exporter_secret
 *                 v
 *           Derive-Secret(., "derived", "")
 *                 |
 *                 v
 *(EC)DHE -> HKDF-Extract = Handshake Secret
 *                 |
 *                 +-----> Derive-Secret(., "c hs traffic",
 *                 |                     ClientHello...ServerHello)
 *                 |                     = client_handshake_traffic_secret
 *                 |
 *                 +-----> Derive-Secret(., "s hs traffic",
 *                 |                     ClientHello...ServerHello)
 *                 |                     = server_handshake_traffic_secret
 *                 v
 *           Derive-Secret(., "derived", "")
 *                 |
 *                 v
 *      0 -> HKDF-Extract = Master Secret
 *                 |
 *                 +-----> Derive-Secret(., "c ap traffic",
 *                 |                     ClientHello...Server Finished)
 *                 |                     = client_traffic_secret_0
 *                 |
 *                 +-----> Derive-Secret(., "s ap traffic",
 *                 |                     ClientHello...Server Finished)
 *                 |                     = server_traffic_secret_0
 *                 |
 *                 +-----> Derive-Secret(., "exp master",
 *                 |                     ClientHello...Server Finished)
 *                 |                     = exporter_secret
 *                 |
 *                 +-----> Derive-Secret(., "res master",
 *                                       ClientHello...Client Finished)
 *                                       = resumption_master_secret
 *
 */

static SECStatus
tls13_ComputeEarlySecrets(sslSocket *ss)
{
    SECStatus rv = SECSuccess;

    SSL_TRC(5, ("%d: TLS13[%d]: compute early secrets (%s)",
                SSL_GETPID(), ss->fd, SSL_ROLE(ss)));

    /* Extract off the resumptionMasterSecret (if present), else pass the NULL
     * resumptionMasterSecret which will be internally translated to zeroes. */
    PORT_Assert(!ss->ssl3.hs.currentSecret);
    rv = tls13_HkdfExtract(NULL, ss->ssl3.hs.resumptionMasterSecret,
                           tls13_GetHash(ss), &ss->ssl3.hs.currentSecret);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    PORT_Assert(ss->statelessResume == (ss->ssl3.hs.resumptionMasterSecret != NULL));
    if (ss->statelessResume) {
        PK11_FreeSymKey(ss->ssl3.hs.resumptionMasterSecret);
        ss->ssl3.hs.resumptionMasterSecret = NULL;

        rv = tls13_DeriveSecretNullHash(ss, ss->ssl3.hs.currentSecret,
                                        kHkdfLabelPskBinderKey,
                                        strlen(kHkdfLabelPskBinderKey),
                                        &ss->ssl3.hs.pskBinderKey);
        if (rv != SECSuccess) {
            return SECFailure;
        }
    }
    PORT_Assert(!ss->ssl3.hs.resumptionMasterSecret);

    return SECSuccess;
}

/* This derives the early traffic and early exporter secrets. */
static SECStatus
tls13_DeriveEarlySecrets(sslSocket *ss)
{
    SECStatus rv;

    rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret,
                                kHkdfLabelClient,
                                kHkdfLabelEarlyTrafficSecret,
                                keylogLabelClientEarlyTrafficSecret,
                                &ss->ssl3.hs.clientEarlyTrafficSecret);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret,
                                NULL, kHkdfLabelEarlyExporterSecret,
                                keylogLabelEarlyExporterSecret,
                                &ss->ssl3.hs.earlyExporterSecret);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    return SECSuccess;
}

static SECStatus
tls13_ComputeHandshakeSecrets(sslSocket *ss)
{
    SECStatus rv;
    PK11SymKey *derivedSecret = NULL;
    PK11SymKey *newSecret = NULL;

    SSL_TRC(5, ("%d: TLS13[%d]: compute handshake secrets (%s)",
                SSL_GETPID(), ss->fd, SSL_ROLE(ss)));

    /* First update |currentSecret| to add |dheSecret|, if any. */
    PORT_Assert(ss->ssl3.hs.currentSecret);
    PORT_Assert(ss->ssl3.hs.dheSecret);

    /* Expand before we extract. */
    rv = tls13_DeriveSecretNullHash(ss, ss->ssl3.hs.currentSecret,
                                    kHkdfLabelDerivedSecret,
                                    strlen(kHkdfLabelDerivedSecret),
                                    &derivedSecret);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        return rv;
    }

    rv = tls13_HkdfExtract(derivedSecret, ss->ssl3.hs.dheSecret,
                           tls13_GetHash(ss), &newSecret);
    PK11_FreeSymKey(derivedSecret);

    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        return rv;
    }
    PK11_FreeSymKey(ss->ssl3.hs.dheSecret);
    ss->ssl3.hs.dheSecret = NULL;
    PK11_FreeSymKey(ss->ssl3.hs.currentSecret);
    ss->ssl3.hs.currentSecret = newSecret;

    /* Now compute |*HsTrafficSecret| */
    rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret,
                                kHkdfLabelClient,
                                kHkdfLabelHandshakeTrafficSecret,
                                keylogLabelClientHsTrafficSecret,
                                &ss->ssl3.hs.clientHsTrafficSecret);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        return rv;
    }
    rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret,
                                kHkdfLabelServer,
                                kHkdfLabelHandshakeTrafficSecret,
                                keylogLabelServerHsTrafficSecret,
                                &ss->ssl3.hs.serverHsTrafficSecret);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        return rv;
    }

    SSL_TRC(5, ("%d: TLS13[%d]: compute master secret (%s)",
                SSL_GETPID(), ss->fd, SSL_ROLE(ss)));

    /* Crank HKDF forward to make master secret, which we
     * stuff in current secret. */
    rv = tls13_DeriveSecretNullHash(ss, ss->ssl3.hs.currentSecret,
                                    kHkdfLabelDerivedSecret,
                                    strlen(kHkdfLabelDerivedSecret),
                                    &derivedSecret);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        return rv;
    }
    rv = tls13_HkdfExtract(derivedSecret,
                           NULL,
                           tls13_GetHash(ss),
                           &newSecret);
    PK11_FreeSymKey(derivedSecret);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    PK11_FreeSymKey(ss->ssl3.hs.currentSecret);
    ss->ssl3.hs.currentSecret = newSecret;

    return SECSuccess;
}

static SECStatus
tls13_ComputeApplicationSecrets(sslSocket *ss)
{
    SECStatus rv;

    rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret,
                                kHkdfLabelClient,
                                kHkdfLabelApplicationTrafficSecret,
                                keylogLabelClientTrafficSecret,
                                &ss->ssl3.hs.clientTrafficSecret);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret,
                                kHkdfLabelServer,
                                kHkdfLabelApplicationTrafficSecret,
                                keylogLabelServerTrafficSecret,
                                &ss->ssl3.hs.serverTrafficSecret);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret,
                                NULL, kHkdfLabelExporterMasterSecret,
                                keylogLabelExporterSecret,
                                &ss->ssl3.hs.exporterSecret);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    return SECSuccess;
}

static SECStatus
tls13_ComputeFinalSecrets(sslSocket *ss)
{
    SECStatus rv;

    PORT_Assert(!ss->ssl3.crSpec->masterSecret);
    PORT_Assert(!ss->ssl3.cwSpec->masterSecret);

    rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret,
                                NULL, kHkdfLabelResumptionMasterSecret,
                                NULL,
                                &ss->ssl3.hs.resumptionMasterSecret);
    PK11_FreeSymKey(ss->ssl3.hs.currentSecret);
    ss->ssl3.hs.currentSecret = NULL;
    if (rv != SECSuccess) {
        return SECFailure;
    }

    return SECSuccess;
}

static void
tls13_RestoreCipherInfo(sslSocket *ss, sslSessionID *sid)
{
    /* Set these to match the cached value.
     * TODO(ekr@rtfm.com): Make a version with the "true" values.
     * Bug 1256137.
     */
    ss->sec.authType = sid->authType;
    ss->sec.authKeyBits = sid->authKeyBits;
    ss->sec.originalKeaGroup = ssl_LookupNamedGroup(sid->keaGroup);
    ss->sec.signatureScheme = sid->sigScheme;
}

/* Check whether resumption-PSK is allowed. */
static PRBool
tls13_CanResume(sslSocket *ss, const sslSessionID *sid)
{
    const sslServerCert *sc;

    if (!sid) {
        return PR_FALSE;
    }

    if (sid->version != ss->version) {
        return PR_FALSE;
    }

    if (tls13_GetHashForCipherSuite(sid->u.ssl3.cipherSuite) != tls13_GetHashForCipherSuite(ss->ssl3.hs.cipher_suite)) {
        return PR_FALSE;
    }

    /* Server sids don't remember the server cert we previously sent, but they
     * do remember the type of certificate we originally used, so we can locate
     * it again, provided that the current ssl socket has had its server certs
     * configured the same as the previous one. */
    sc = ssl_FindServerCert(ss, sid->authType, sid->namedCurve);
    if (!sc || !sc->serverCert) {
        return PR_FALSE;
    }

    return PR_TRUE;
}

static PRBool
tls13_CanNegotiateZeroRtt(sslSocket *ss, const sslSessionID *sid)
{
    PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_sent);

    if (!sid)
        return PR_FALSE;
    PORT_Assert(ss->statelessResume);
    if (!ss->statelessResume)
        return PR_FALSE;
    if (ss->ssl3.hs.cipher_suite != sid->u.ssl3.cipherSuite)
        return PR_FALSE;
    if (!ss->opt.enable0RttData)
        return PR_FALSE;
    if (!(sid->u.ssl3.locked.sessionTicket.flags & ticket_allow_early_data))
        return PR_FALSE;
    if (SECITEM_CompareItem(&ss->xtnData.nextProto,
                            &sid->u.ssl3.alpnSelection) != 0)
        return PR_FALSE;

    if (tls13_IsReplay(ss, sid)) {
        return PR_FALSE;
    }

    return PR_TRUE;
}

/* Called from tls13_HandleClientHelloPart2 to update the state of 0-RTT handling.
 *
 * 0-RTT is only permitted if:
 * 1. The early data extension was present.
 * 2. We are resuming a session.
 * 3. The 0-RTT option is set.
 * 4. The ticket allowed 0-RTT.
 * 5. We negotiated the same ALPN value as in the ticket.
 */
static void
tls13_NegotiateZeroRtt(sslSocket *ss, const sslSessionID *sid)
{
    SSL_TRC(3, ("%d: TLS13[%d]: negotiate 0-RTT %p",
                SSL_GETPID(), ss->fd, sid));

    /* tls13_ServerHandleEarlyDataXtn sets this to ssl_0rtt_sent, so this will
     * be ssl_0rtt_none unless early_data is present. */
    if (ss->ssl3.hs.zeroRttState == ssl_0rtt_none) {
        return;
    }

    /* If we rejected 0-RTT on the first ClientHello, then we can just say that
     * there is no 0-RTT for the second.  We shouldn't get any more.  Reset the
     * ignore state so that we treat decryption failure normally. */
    if (ss->ssl3.hs.zeroRttIgnore == ssl_0rtt_ignore_hrr) {
        PORT_Assert(ss->ssl3.hs.helloRetry);
        ss->ssl3.hs.zeroRttState = ssl_0rtt_none;
        ss->ssl3.hs.zeroRttIgnore = ssl_0rtt_ignore_none;
        return;
    }

    if (!tls13_CanNegotiateZeroRtt(ss, sid)) {
        SSL_TRC(3, ("%d: TLS13[%d]: ignore 0-RTT",
                    SSL_GETPID(), ss->fd));
        ss->ssl3.hs.zeroRttState = ssl_0rtt_ignored;
        ss->ssl3.hs.zeroRttIgnore = ssl_0rtt_ignore_trial;
        return;
    }

    SSL_TRC(3, ("%d: TLS13[%d]: enable 0-RTT",
                SSL_GETPID(), ss->fd));
    PORT_Assert(ss->statelessResume);
    ss->ssl3.hs.zeroRttState = ssl_0rtt_accepted;
    ss->ssl3.hs.zeroRttIgnore = ssl_0rtt_ignore_none;
}

/* Check if the offered group is acceptable. */
static PRBool
tls13_isGroupAcceptable(const sslNamedGroupDef *offered,
                        const sslNamedGroupDef *preferredGroup)
{
    /* We accept epsilon (e) bits around the offered group size. */
    const unsigned int e = 2;

    PORT_Assert(offered);
    PORT_Assert(preferredGroup);

    if (offered->bits >= preferredGroup->bits - e &&
        offered->bits <= preferredGroup->bits + e) {
        return PR_TRUE;
    }

    return PR_FALSE;
}

/* Find remote key share for given group and return it.
 * Returns NULL if no key share is found. */
static TLS13KeyShareEntry *
tls13_FindKeyShareEntry(sslSocket *ss, const sslNamedGroupDef *group)
{
    PRCList *cur_p = PR_NEXT_LINK(&ss->xtnData.remoteKeyShares);
    while (cur_p != &ss->xtnData.remoteKeyShares) {
        TLS13KeyShareEntry *offer = (TLS13KeyShareEntry *)cur_p;
        if (offer->group == group) {
            return offer;
        }
        cur_p = PR_NEXT_LINK(cur_p);
    }
    return NULL;
}

static SECStatus
tls13_NegotiateKeyExchange(sslSocket *ss,
                           const sslNamedGroupDef **requestedGroup,
                           TLS13KeyShareEntry **clientShare)
{
    unsigned int index;
    TLS13KeyShareEntry *entry = NULL;
    const sslNamedGroupDef *preferredGroup = NULL;

    /* We insist on DHE. */
    if (ss->statelessResume) {
        if (!ssl3_ExtensionNegotiated(ss, ssl_tls13_psk_key_exchange_modes_xtn)) {
            FATAL_ERROR(ss, SSL_ERROR_MISSING_PSK_KEY_EXCHANGE_MODES,
                        missing_extension);
            return SECFailure;
        }
        if (!memchr(ss->xtnData.psk_ke_modes.data, tls13_psk_dh_ke,
                    ss->xtnData.psk_ke_modes.len)) {
            SSL_TRC(3, ("%d: TLS13[%d]: client offered PSK without DH",
                        SSL_GETPID(), ss->fd));
            ss->statelessResume = PR_FALSE;
        }
    }

    /* Now figure out which key share we like the best out of the
     * mutually supported groups, regardless of what the client offered
     * for key shares.
     */
    if (!ssl3_ExtensionNegotiated(ss, ssl_supported_groups_xtn)) {
        FATAL_ERROR(ss, SSL_ERROR_MISSING_SUPPORTED_GROUPS_EXTENSION,
                    missing_extension);
        return SECFailure;
    }

    SSL_TRC(3, ("%d: TLS13[%d]: selected KE = %s",
                SSL_GETPID(), ss->fd, ss->statelessResume ? "PSK + (EC)DHE" : "(EC)DHE"));

    /* Find the preferred group and an according client key share available. */
    for (index = 0; index < SSL_NAMED_GROUP_COUNT; ++index) {
        /* Continue to the next group if this one is not enabled. */
        if (!ss->namedGroupPreferences[index]) {
            /* There's a gap in the preferred groups list. Assume this is a group
             * that's not supported by the client but preferred by the server. */
            if (preferredGroup) {
                entry = NULL;
                break;
            }
            continue;
        }

        /* Check if the client sent a key share for this group. */
        entry = tls13_FindKeyShareEntry(ss, ss->namedGroupPreferences[index]);

        if (preferredGroup) {
            /* We already found our preferred group but the group didn't have a share. */
            if (entry) {
                /* The client sent a key share with group ss->namedGroupPreferences[index] */
                if (tls13_isGroupAcceptable(ss->namedGroupPreferences[index],
                                            preferredGroup)) {
                    /* This is not the preferred group, but it's acceptable */
                    preferredGroup = ss->namedGroupPreferences[index];
                } else {
                    /* The proposed group is not acceptable. */
                    entry = NULL;
                }
            }
            break;
        } else {
            /* The first enabled group is the preferred group. */
            preferredGroup = ss->namedGroupPreferences[index];
            if (entry) {
                break;
            }
        }
    }

    if (!preferredGroup) {
        FATAL_ERROR(ss, SSL_ERROR_NO_CYPHER_OVERLAP, handshake_failure);
        return SECFailure;
    }
    SSL_TRC(3, ("%d: TLS13[%d]: group = %d", SSL_GETPID(), ss->fd,
                preferredGroup->name));

    /* Either provide a share, or provide a group that should be requested in a
     * HelloRetryRequest, but not both. */
    if (entry) {
        PORT_Assert(preferredGroup == entry->group);
        *clientShare = entry;
        *requestedGroup = NULL;
    } else {
        *clientShare = NULL;
        *requestedGroup = preferredGroup;
    }
    return SECSuccess;
}

SECStatus
tls13_SelectServerCert(sslSocket *ss)
{
    PRCList *cursor;
    SECStatus rv;

    if (!ssl3_ExtensionNegotiated(ss, ssl_signature_algorithms_xtn)) {
        FATAL_ERROR(ss, SSL_ERROR_MISSING_SIGNATURE_ALGORITHMS_EXTENSION,
                    missing_extension);
        return SECFailure;
    }

    /* This picks the first certificate that has:
     * a) the right authentication method, and
     * b) the right named curve (EC only)
     *
     * We might want to do some sort of ranking here later.  For now, it's all
     * based on what order they are configured in. */
    for (cursor = PR_NEXT_LINK(&ss->serverCerts);
         cursor != &ss->serverCerts;
         cursor = PR_NEXT_LINK(cursor)) {
        sslServerCert *cert = (sslServerCert *)cursor;

        if (SSL_CERT_IS_ONLY(cert, ssl_auth_rsa_decrypt)) {
            continue;
        }

        rv = ssl_PickSignatureScheme(ss,
                                     cert->serverCert,
                                     cert->serverKeyPair->pubKey,
                                     cert->serverKeyPair->privKey,
                                     ss->xtnData.sigSchemes,
                                     ss->xtnData.numSigSchemes,
                                     PR_FALSE);
        if (rv == SECSuccess) {
            /* Found one. */
            ss->sec.serverCert = cert;
            ss->sec.authType = ss->ssl3.hs.kea_def_mutable.authKeyType =
                ssl_SignatureSchemeToAuthType(ss->ssl3.hs.signatureScheme);
            ss->sec.authKeyBits = cert->serverKeyBits;
            return SECSuccess;
        }
    }

    FATAL_ERROR(ss, SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM,
                handshake_failure);
    return SECFailure;
}

/* Note: |requestedGroup| is non-NULL when we send a key_share extension. */
static SECStatus
tls13_MaybeSendHelloRetry(sslSocket *ss, const sslNamedGroupDef *requestedGroup,
                          PRBool *hrrSent)
{
    SSLHelloRetryRequestAction action = ssl_hello_retry_accept;
    PRUint8 token[256] = { 0 };
    unsigned int tokenLen = 0;
    SECStatus rv;

    if (ss->hrrCallback) {
        action = ss->hrrCallback(!ss->ssl3.hs.helloRetry,
                                 ss->xtnData.applicationToken.data,
                                 ss->xtnData.applicationToken.len,
                                 token, &tokenLen, sizeof(token),
                                 ss->hrrCallbackArg);
    }

    /* These use SSL3_SendAlert directly to avoid an assertion in
     * tls13_FatalError(), which is ordinarily OK. */
    if (action == ssl_hello_retry_request && ss->ssl3.hs.helloRetry) {
        (void)SSL3_SendAlert(ss, alert_fatal, internal_error);
        PORT_SetError(SSL_ERROR_APP_CALLBACK_ERROR);
        return SECFailure;
    }

    if (action != ssl_hello_retry_request && tokenLen) {
        (void)SSL3_SendAlert(ss, alert_fatal, internal_error);
        PORT_SetError(SSL_ERROR_APP_CALLBACK_ERROR);
        return SECFailure;
    }

    if (tokenLen > sizeof(token)) {
        (void)SSL3_SendAlert(ss, alert_fatal, internal_error);
        PORT_SetError(SSL_ERROR_APP_CALLBACK_ERROR);
        return SECFailure;
    }

    if (action == ssl_hello_retry_fail) {
        FATAL_ERROR(ss, SSL_ERROR_APPLICATION_ABORT, handshake_failure);
        return SECFailure;
    }

    if (!requestedGroup && action != ssl_hello_retry_request) {
        return SECSuccess;
    }

    rv = tls13_SendHelloRetryRequest(ss, requestedGroup, token, tokenLen);
    if (rv != SECSuccess) {
        return SECFailure; /* Code already set. */
    }

    *hrrSent = PR_TRUE;
    return SECSuccess;
}

static SECStatus
tls13_NegotiateAuthentication(sslSocket *ss)
{
    SECStatus rv;

    if (ss->statelessResume) {
        SSL_TRC(3, ("%d: TLS13[%d]: selected PSK authentication",
                    SSL_GETPID(), ss->fd));
        ss->ssl3.hs.signatureScheme = ssl_sig_none;
        ss->ssl3.hs.kea_def_mutable.authKeyType = ssl_auth_psk;
        return SECSuccess;
    }

    SSL_TRC(3, ("%d: TLS13[%d]: selected certificate authentication",
                SSL_GETPID(), ss->fd));
    /* We've now established that we need to sign.... */
    rv = tls13_SelectServerCert(ss);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    return SECSuccess;
}

/* Called from ssl3_HandleClientHello after we have parsed the
 * ClientHello and are sure that we are going to do TLS 1.3
 * or fail. */
SECStatus
tls13_HandleClientHelloPart2(sslSocket *ss,
                             const SECItem *suites,
                             sslSessionID *sid,
                             const PRUint8 *msg,
                             unsigned int len)
{
    SECStatus rv;
    SSL3Statistics *ssl3stats = SSL_GetStatistics();
    const sslNamedGroupDef *requestedGroup = NULL;
    TLS13KeyShareEntry *clientShare = NULL;
    ssl3CipherSuite previousCipherSuite = 0;
    const sslNamedGroupDef *previousGroup = NULL;
    PRBool hrr = PR_FALSE;

    ss->ssl3.hs.endOfFlight = PR_TRUE;

    if (ssl3_ExtensionNegotiated(ss, ssl_tls13_early_data_xtn)) {
        ss->ssl3.hs.zeroRttState = ssl_0rtt_sent;
    }

#ifndef PARANOID
    /* Look for a matching cipher suite. */
    if (ssl3_config_match_init(ss) == 0) { /* no ciphers are working/supported by PK11 */
        FATAL_ERROR(ss, PORT_GetError(), internal_error);
        goto loser;
    }
#endif

    /* Negotiate cipher suite. */
    rv = ssl3_NegotiateCipherSuite(ss, suites, PR_FALSE);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SSL_ERROR_NO_CYPHER_OVERLAP, handshake_failure);
        goto loser;
    }

    /* If we are going around again, then we should make sure that the cipher
     * suite selection doesn't change. That's a sign of client shennanigans. */
    if (ss->ssl3.hs.helloRetry) {

        /* Update sequence numbers before checking the cookie so that any alerts
         * we generate are sent with the right sequence numbers. */
        if (IS_DTLS(ss)) {
            /* Count the first ClientHello and the HelloRetryRequest. */
            ss->ssl3.hs.sendMessageSeq = 1;
            ss->ssl3.hs.recvMessageSeq = 1;
            ssl_GetSpecWriteLock(ss);
            /* Increase the write sequence number.  The read sequence number
             * will be reset after this to early data or handshake. */
            ss->ssl3.cwSpec->nextSeqNum = 1;
            ssl_ReleaseSpecWriteLock(ss);
        }

        if (!ssl3_ExtensionNegotiated(ss, ssl_tls13_cookie_xtn) ||
            !ss->xtnData.cookie.len) {
            FATAL_ERROR(ss, SSL_ERROR_MISSING_COOKIE_EXTENSION,
                        missing_extension);
            goto loser;
        }
        PRINT_BUF(50, (ss, "Client sent cookie",
                       ss->xtnData.cookie.data, ss->xtnData.cookie.len));

        rv = tls13_RecoverHashState(ss, ss->xtnData.cookie.data,
                                    ss->xtnData.cookie.len,
                                    &previousCipherSuite,
                                    &previousGroup);
        if (rv != SECSuccess) {
            FATAL_ERROR(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO, illegal_parameter);
            goto loser;
        }
    }

    /* Now merge the ClientHello into the hash state. */
    rv = ssl_HashHandshakeMessage(ss, ssl_hs_client_hello, msg, len);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        goto loser;
    }

    /* Now create a synthetic kea_def that we can tweak. */
    ss->ssl3.hs.kea_def_mutable = *ss->ssl3.hs.kea_def;
    ss->ssl3.hs.kea_def = &ss->ssl3.hs.kea_def_mutable;

    /* Note: We call this quite a bit earlier than with TLS 1.2 and
     * before. */
    rv = ssl3_ServerCallSNICallback(ss);
    if (rv != SECSuccess) {
        goto loser; /* An alert has already been sent. */
    }

    /* Check if we could in principle resume. */
    if (ss->statelessResume) {
        PORT_Assert(sid);
        if (!sid) {
            FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
            return SECFailure;
        }
        if (!tls13_CanResume(ss, sid)) {
            ss->statelessResume = PR_FALSE;
        }
    }

    /* Select key exchange. */
    rv = tls13_NegotiateKeyExchange(ss, &requestedGroup, &clientShare);
    if (rv != SECSuccess) {
        goto loser;
    }
    /* We should get either one of these, but not both. */
    PORT_Assert((requestedGroup && !clientShare) ||
                (!requestedGroup && clientShare));

    /* After HelloRetryRequest, check consistency of cipher and group. */
    if (ss->ssl3.hs.helloRetry) {
        PORT_Assert(previousCipherSuite);
        if (ss->ssl3.hs.cipher_suite != previousCipherSuite) {
            FATAL_ERROR(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO,
                        illegal_parameter);
            goto loser;
        }
        if (!clientShare) {
            FATAL_ERROR(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO,
                        illegal_parameter);
            goto loser;
        }

        /* If we requested a new key share, check that the client provided just
         * one of the right type. */
        if (previousGroup) {
            if (PR_PREV_LINK(&ss->xtnData.remoteKeyShares) !=
                PR_NEXT_LINK(&ss->xtnData.remoteKeyShares)) {
                FATAL_ERROR(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO,
                            illegal_parameter);
                goto loser;
            }
            if (clientShare->group != previousGroup) {
                FATAL_ERROR(ss, SSL_ERROR_BAD_2ND_CLIENT_HELLO,
                            illegal_parameter);
                goto loser;
            }
        }
    }

    rv = tls13_MaybeSendHelloRetry(ss, requestedGroup, &hrr);
    if (rv != SECSuccess) {
        goto loser;
    }
    if (hrr) {
        if (sid) { /* Free the sid. */
            ssl_UncacheSessionID(ss);
            ssl_FreeSID(sid);
        }
        PORT_Assert(ss->ssl3.hs.helloRetry);
        return SECSuccess;
    }

    /* Select the authentication (this is also handshake shape). */
    rv = tls13_NegotiateAuthentication(ss);
    if (rv != SECSuccess) {
        goto loser;
    }

    if (ss->statelessResume) {
        /* We are now committed to trying to resume. */
        PORT_Assert(sid);

        /* Check that the negotiated SNI and the cached SNI match. */
        if (SECITEM_CompareItem(&sid->u.ssl3.srvName,
                                &ss->ssl3.hs.srvVirtName) != SECEqual) {
            FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO,
                        handshake_failure);
            goto loser;
        }

        ss->sec.serverCert = ssl_FindServerCert(ss, sid->authType,
                                                sid->namedCurve);
        PORT_Assert(ss->sec.serverCert);

        rv = tls13_RecoverWrappedSharedSecret(ss, sid);
        if (rv != SECSuccess) {
            SSL_AtomicIncrementLong(&ssl3stats->hch_sid_cache_not_ok);
            FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
            goto loser;
        }
        tls13_RestoreCipherInfo(ss, sid);

        ss->sec.localCert = CERT_DupCertificate(ss->sec.serverCert->serverCert);
        if (sid->peerCert != NULL) {
            ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
        }

        ssl3_RegisterExtensionSender(
            ss, &ss->xtnData,
            ssl_tls13_pre_shared_key_xtn, tls13_ServerSendPreSharedKeyXtn);

        tls13_NegotiateZeroRtt(ss, sid);
    } else {
        if (sid) { /* we had a sid, but it's no longer valid, free it */
            SSL_AtomicIncrementLong(&ssl3stats->hch_sid_cache_not_ok);
            ssl_UncacheSessionID(ss);
            ssl_FreeSID(sid);
            sid = NULL;
        }
        tls13_NegotiateZeroRtt(ss, NULL);
    }

    /* Need to compute early secrets. */
    rv = tls13_ComputeEarlySecrets(ss);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        return SECFailure;
    }

    /* Now that we have the binder key check the binder. */
    if (ss->statelessResume) {
        SSL3Hashes hashes;

        PORT_Assert(ss->ssl3.hs.messages.len > ss->xtnData.pskBindersLen);
        rv = tls13_ComputePskBinderHash(
            ss,
            ss->ssl3.hs.messages.len - ss->xtnData.pskBindersLen,
            &hashes);
        if (rv != SECSuccess) {
            FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
            goto loser;
        }

        rv = tls13_VerifyFinished(ss, ssl_hs_client_hello,
                                  ss->ssl3.hs.pskBinderKey,
                                  ss->xtnData.pskBinder.data,
                                  ss->xtnData.pskBinder.len,
                                  &hashes);
        if (rv != SECSuccess) {
            goto loser;
        }
    }

    /* This needs to go after we verify the psk binder. */
    rv = ssl3_InitHandshakeHashes(ss);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* If this is TLS 1.3 we are expecting a ClientKeyShare
     * extension. Missing/absent extension cause failure
     * below. */
    rv = tls13_HandleClientKeyShare(ss, clientShare);
    if (rv != SECSuccess) {
        goto loser; /* An alert was sent already. */
    }

    /* From this point we are either committed to resumption, or not. */
    if (ss->statelessResume) {
        SSL_AtomicIncrementLong(&ssl3stats->hch_sid_cache_hits);
        SSL_AtomicIncrementLong(&ssl3stats->hch_sid_stateless_resumes);
    } else {
        if (sid) {
            /* We had a sid, but it's no longer valid, free it. */
            SSL_AtomicIncrementLong(&ssl3stats->hch_sid_cache_not_ok);
            ssl_UncacheSessionID(ss);
            ssl_FreeSID(sid);
        } else {
            SSL_AtomicIncrementLong(&ssl3stats->hch_sid_cache_misses);
        }

        sid = ssl3_NewSessionID(ss, PR_TRUE);
        if (!sid) {
            FATAL_ERROR(ss, PORT_GetError(), internal_error);
            return SECFailure;
        }
    }
    /* Take ownership of the session. */
    ss->sec.ci.sid = sid;
    sid = NULL;

    if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
        rv = tls13_DeriveEarlySecrets(ss);
        if (rv != SECSuccess) {
            FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
            return SECFailure;
        }
    }

    ssl_GetXmitBufLock(ss);
    rv = tls13_SendServerHelloSequence(ss);
    ssl_ReleaseXmitBufLock(ss);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, PORT_GetError(), handshake_failure);
        return SECFailure;
    }

    return SECSuccess;

loser:
    if (sid) {
        ssl_UncacheSessionID(ss);
        ssl_FreeSID(sid);
    }
    return SECFailure;
}

SECStatus
SSLExp_HelloRetryRequestCallback(PRFileDesc *fd,
                                 SSLHelloRetryRequestCallback cb, void *arg)
{
    sslSocket *ss = ssl_FindSocket(fd);
    if (!ss) {
        return SECFailure; /* Code already set. */
    }

    ss->hrrCallback = cb;
    ss->hrrCallbackArg = arg;
    return SECSuccess;
}

/*
 * struct {
 *     ProtocolVersion server_version;
 *     CipherSuite cipher_suite;
 *     Extension extensions<2..2^16-1>;
 * } HelloRetryRequest;
 *
 * Note: this function takes an empty buffer and returns
 * a non-empty one on success, in which case the caller must
 * eventually clean up.
 */
SECStatus
tls13_ConstructHelloRetryRequest(sslSocket *ss,
                                 ssl3CipherSuite cipherSuite,
                                 const sslNamedGroupDef *selectedGroup,
                                 PRUint8 *cookie, unsigned int cookieLen,
                                 sslBuffer *buffer)
{
    SECStatus rv;
    sslBuffer extensionsBuf = SSL_BUFFER_EMPTY;
    PORT_Assert(buffer->len == 0);

    /* Note: cookie is pointing to a stack variable, so is only valid
     * now. */
    ss->xtnData.selectedGroup = selectedGroup;
    ss->xtnData.cookie.data = cookie;
    ss->xtnData.cookie.len = cookieLen;
    rv = ssl_ConstructExtensions(ss, &extensionsBuf,
                                 ssl_hs_hello_retry_request);
    if (rv != SECSuccess) {
        goto loser;
    }
    /* These extensions can't be empty. */
    PORT_Assert(SSL_BUFFER_LEN(&extensionsBuf) > 0);

    /* Clean up cookie so we're not pointing at random memory. */
    ss->xtnData.cookie.data = NULL;
    ss->xtnData.cookie.len = 0;

    rv = ssl_ConstructServerHello(ss, PR_TRUE, &extensionsBuf, buffer);
    if (rv != SECSuccess) {
        goto loser;
    }
    sslBuffer_Clear(&extensionsBuf);
    return SECSuccess;

loser:
    sslBuffer_Clear(&extensionsBuf);
    sslBuffer_Clear(buffer);
    return SECFailure;
}

static SECStatus
tls13_SendHelloRetryRequest(sslSocket *ss,
                            const sslNamedGroupDef *requestedGroup,
                            const PRUint8 *appToken, unsigned int appTokenLen)
{
    SECStatus rv;
    unsigned int cookieLen;
    PRUint8 cookie[1024];
    sslBuffer messageBuf = SSL_BUFFER_EMPTY;

    SSL_TRC(3, ("%d: TLS13[%d]: send hello retry request handshake",
                SSL_GETPID(), ss->fd));

    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    /* Compute the cookie we are going to need. */
    rv = tls13_MakeHrrCookie(ss, requestedGroup,
                             appToken, appTokenLen,
                             cookie, &cookieLen, sizeof(cookie));
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        return SECFailure;
    }

    /* Now build the body of the message. */
    rv = tls13_ConstructHelloRetryRequest(ss, ss->ssl3.hs.cipher_suite,
                                          requestedGroup,
                                          cookie, cookieLen, &messageBuf);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        return SECFailure;
    }

    /* And send it. */
    ssl_GetXmitBufLock(ss);
    rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_server_hello,
                                    SSL_BUFFER_LEN(&messageBuf));
    if (rv != SECSuccess) {
        goto loser;
    }
    rv = ssl3_AppendBufferToHandshake(ss, &messageBuf);
    if (rv != SECSuccess) {
        goto loser;
    }
    sslBuffer_Clear(&messageBuf); /* Done with messageBuf */

    if (ss->ssl3.hs.fakeSid.len) {
        PRInt32 sent;

        PORT_Assert(!IS_DTLS(ss));
        rv = ssl3_SendChangeCipherSpecsInt(ss);
        if (rv != SECSuccess) {
            goto loser;
        }
        /* ssl3_SendChangeCipherSpecsInt() only flushes to the output buffer, so we
         * have to force a send. */
        sent = ssl_SendSavedWriteData(ss);
        if (sent < 0 && PORT_GetError() != PR_WOULD_BLOCK_ERROR) {
            PORT_SetError(SSL_ERROR_SOCKET_WRITE_FAILURE);
            goto loser;
        }
    } else {
        rv = ssl3_FlushHandshake(ss, 0);
        if (rv != SECSuccess) {
            goto loser; /* error code set by ssl3_FlushHandshake */
        }
    }

    /* We depend on this being exactly one record and one message. */
    PORT_Assert(!IS_DTLS(ss) || (ss->ssl3.hs.sendMessageSeq == 1 &&
                                 ss->ssl3.cwSpec->nextSeqNum == 1));
    ssl_ReleaseXmitBufLock(ss);

    ss->ssl3.hs.helloRetry = PR_TRUE;

    /* We received early data but have to ignore it because we sent a retry. */
    if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) {
        ss->ssl3.hs.zeroRttState = ssl_0rtt_ignored;
        ss->ssl3.hs.zeroRttIgnore = ssl_0rtt_ignore_hrr;
    }

    return SECSuccess;

loser:
    sslBuffer_Clear(&messageBuf);
    ssl_ReleaseXmitBufLock(ss);
    return SECFailure;
}

/* Called from tls13_HandleClientHello.
 *
 * Caller must hold Handshake and RecvBuf locks.
 */

static SECStatus
tls13_HandleClientKeyShare(sslSocket *ss, TLS13KeyShareEntry *peerShare)
{
    SECStatus rv;
    sslEphemeralKeyPair *keyPair; /* ours */

    SSL_TRC(3, ("%d: TLS13[%d]: handle client_key_share handshake",
                SSL_GETPID(), ss->fd));

    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert(peerShare);

    tls13_SetKeyExchangeType(ss, peerShare->group);

    /* Generate our key */
    rv = tls13_AddKeyShare(ss, peerShare->group);
    if (rv != SECSuccess) {
        return rv;
    }

    /* We should have exactly one key share. */
    PORT_Assert(!PR_CLIST_IS_EMPTY(&ss->ephemeralKeyPairs));
    PORT_Assert(PR_PREV_LINK(&ss->ephemeralKeyPairs) ==
                PR_NEXT_LINK(&ss->ephemeralKeyPairs));

    keyPair = ((sslEphemeralKeyPair *)PR_NEXT_LINK(&ss->ephemeralKeyPairs));
    ss->sec.keaKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->keys->pubKey);

    /* Register the sender */
    rv = ssl3_RegisterExtensionSender(ss, &ss->xtnData, ssl_tls13_key_share_xtn,
                                      tls13_ServerSendKeyShareXtn);
    if (rv != SECSuccess) {
        return SECFailure; /* Error code set already. */
    }

    rv = tls13_HandleKeyShare(ss, peerShare, keyPair->keys,
                              tls13_GetHash(ss),
                              &ss->ssl3.hs.dheSecret);
    return rv; /* Error code set already. */
}

/*
 *     [draft-ietf-tls-tls13-11] Section 6.3.3.2
 *
 *     opaque DistinguishedName<1..2^16-1>;
 *
 *     struct {
 *         opaque certificate_extension_oid<1..2^8-1>;
 *         opaque certificate_extension_values<0..2^16-1>;
 *     } CertificateExtension;
 *
 *     struct {
 *         opaque certificate_request_context<0..2^8-1>;
 *         SignatureAndHashAlgorithm
 *           supported_signature_algorithms<2..2^16-2>;
 *         DistinguishedName certificate_authorities<0..2^16-1>;
 *         CertificateExtension certificate_extensions<0..2^16-1>;
 *     } CertificateRequest;
 */
static SECStatus
tls13_SendCertificateRequest(sslSocket *ss)
{
    SECStatus rv;
    sslBuffer extensionBuf = SSL_BUFFER_EMPTY;

    SSL_TRC(3, ("%d: TLS13[%d]: begin send certificate_request",
                SSL_GETPID(), ss->fd));

    rv = ssl_ConstructExtensions(ss, &extensionBuf, ssl_hs_certificate_request);
    if (rv != SECSuccess) {
        return SECFailure; /* Code already set. */
    }
    /* We should always have at least one of these. */
    PORT_Assert(SSL_BUFFER_LEN(&extensionBuf) > 0);

    rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate_request,
                                    1 + 0 + /* empty request context */
                                        2 + /* extension length */
                                        SSL_BUFFER_LEN(&extensionBuf));
    if (rv != SECSuccess) {
        goto loser; /* err set by AppendHandshake. */
    }

    /* Context. */
    rv = ssl3_AppendHandshakeNumber(ss, 0, 1);
    if (rv != SECSuccess) {
        goto loser; /* err set by AppendHandshake. */
    }
    /* Extensions. */
    rv = ssl3_AppendBufferToHandshakeVariable(ss, &extensionBuf, 2);
    if (rv != SECSuccess) {
        goto loser; /* err set by AppendHandshake. */
    }

    sslBuffer_Clear(&extensionBuf);
    return SECSuccess;

loser:
    sslBuffer_Clear(&extensionBuf);
    return SECFailure;
}

/* [draft-ietf-tls-tls13; S 4.4.1] says:
 *
 *     Transcript-Hash(ClientHello1, HelloRetryRequest, ... MN) =
 *      Hash(message_hash ||        // Handshake type
 *           00 00 Hash.length ||   // Handshake message length
 *           Hash(ClientHello1) ||  // Hash of ClientHello1
 *           HelloRetryRequest ... MN)
 */
static SECStatus
tls13_ReinjectHandshakeTranscript(sslSocket *ss)
{
    SSL3Hashes hashes;
    SECStatus rv;

    // First compute the hash.
    rv = tls13_ComputeHash(ss, &hashes,
                           ss->ssl3.hs.messages.buf,
                           ss->ssl3.hs.messages.len);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    // Now re-init the handshake.
    ssl3_RestartHandshakeHashes(ss);

    // And reinject the message.
    rv = ssl_HashHandshakeMessage(ss, ssl_hs_message_hash,
                                  hashes.u.raw, hashes.len);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    return SECSuccess;
}

static unsigned int
ssl_ListCount(PRCList *list)
{
    unsigned int c = 0;
    PRCList *cur;
    for (cur = PR_NEXT_LINK(list); cur != list; cur = PR_NEXT_LINK(cur)) {
        ++c;
    }
    return c;
}

SECStatus
tls13_HandleHelloRetryRequest(sslSocket *ss, const PRUint8 *savedMsg,
                              PRUint32 savedLength)
{
    SECStatus rv;

    SSL_TRC(3, ("%d: TLS13[%d]: handle hello retry request",
                SSL_GETPID(), ss->fd));

    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) {
        FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_HELLO_RETRY_REQUEST,
                    unexpected_message);
        return SECFailure;
    }
    PORT_Assert(ss->ssl3.hs.ws == wait_server_hello);

    if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) {
        ss->ssl3.hs.zeroRttState = ssl_0rtt_ignored;
        /* Restore the null cipher spec for writing. */
        ssl_GetSpecWriteLock(ss);
        ssl_CipherSpecRelease(ss->ssl3.cwSpec);
        ss->ssl3.cwSpec = ssl_FindCipherSpecByEpoch(ss, CipherSpecWrite,
                                                    TrafficKeyClearText);
        PORT_Assert(ss->ssl3.cwSpec);
        ssl_ReleaseSpecWriteLock(ss);
    } else {
        PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_none);
    }
    /* Set the spec version, because we want to send CH now with 0303 */
    tls13_SetSpecRecordVersion(ss, ss->ssl3.cwSpec);

    /* Extensions must contain more than just supported_versions.  This will
     * ensure that a HelloRetryRequest isn't a no-op: we must have at least two
     * extensions, supported_versions plus one other.  That other must be one
     * that we understand and recognize as being valid for HelloRetryRequest,
     * and all the extensions we permit cause us to modify our second
     * ClientHello in some meaningful way. */
    if (ssl_ListCount(&ss->ssl3.hs.remoteExtensions) <= 1) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST,
                    decode_error);
        return SECFailure;
    }

    rv = ssl3_HandleParsedExtensions(ss, ssl_hs_hello_retry_request);
    ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions);
    if (rv != SECSuccess) {
        return SECFailure; /* Error code set below */
    }

    ss->ssl3.hs.helloRetry = PR_TRUE;
    rv = tls13_ReinjectHandshakeTranscript(ss);
    if (rv != SECSuccess) {
        return rv;
    }

    rv = ssl_HashHandshakeMessage(ss, ssl_hs_server_hello,
                                  savedMsg, savedLength);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    ssl_GetXmitBufLock(ss);
    if (ss->opt.enableTls13CompatMode && !IS_DTLS(ss) &&
        ss->ssl3.hs.zeroRttState == ssl_0rtt_none) {
        rv = ssl3_SendChangeCipherSpecsInt(ss);
        if (rv != SECSuccess) {
            goto loser;
        }
    }

    rv = ssl3_SendClientHello(ss, client_hello_retry);
    if (rv != SECSuccess) {
        goto loser;
    }

    ssl_ReleaseXmitBufLock(ss);
    return SECSuccess;

loser:
    ssl_ReleaseXmitBufLock(ss);
    return SECFailure;
}

static SECStatus
tls13_HandleCertificateRequest(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
    SECStatus rv;
    SECItem context = { siBuffer, NULL, 0 };
    SECItem extensionsData = { siBuffer, NULL, 0 };

    SSL_TRC(3, ("%d: TLS13[%d]: handle certificate_request sequence",
                SSL_GETPID(), ss->fd));

    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    /* Client */
    rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST,
                              wait_cert_request);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    PORT_Assert(ss->ssl3.clientCertChain == NULL);
    PORT_Assert(ss->ssl3.clientCertificate == NULL);
    PORT_Assert(ss->ssl3.clientPrivateKey == NULL);
    PORT_Assert(!ss->ssl3.hs.clientCertRequested);

    rv = ssl3_ConsumeHandshakeVariable(ss, &context, 1, &b, &length);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    /* We don't support post-handshake client auth, the certificate request
     * context must always be empty. */
    if (context.len > 0) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_REQUEST, illegal_parameter);
        return SECFailure;
    }

    rv = ssl3_ConsumeHandshakeVariable(ss, &extensionsData, 2, &b, &length);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    if (length) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_REQUEST, decode_error);
        return SECFailure;
    }

    /* Process all the extensions. */
    rv = ssl3_HandleExtensions(ss, &extensionsData.data, &extensionsData.len,
                               ssl_hs_certificate_request);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    if (!ss->xtnData.numSigSchemes) {
        FATAL_ERROR(ss, SSL_ERROR_MISSING_SIGNATURE_ALGORITHMS_EXTENSION,
                    missing_extension);
        return SECFailure;
    }

    rv = SECITEM_CopyItem(NULL, &ss->xtnData.certReqContext, &context);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    ss->ssl3.hs.clientCertRequested = PR_TRUE;
    TLS13_SET_HS_STATE(ss, wait_server_cert);
    return SECSuccess;
}

PRBool
tls13_ShouldRequestClientAuth(sslSocket *ss)
{
    return ss->opt.requestCertificate &&
           ss->ssl3.hs.kea_def->authKeyType != ssl_auth_psk;
}

static SECStatus
tls13_SendEncryptedServerSequence(sslSocket *ss)
{
    SECStatus rv;

    rv = tls13_ComputeHandshakeSecrets(ss);
    if (rv != SECSuccess) {
        return SECFailure; /* error code is set. */
    }

    rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake,
                             CipherSpecWrite, PR_FALSE);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
        rv = ssl3_RegisterExtensionSender(ss, &ss->xtnData,
                                          ssl_tls13_early_data_xtn,
                                          ssl_SendEmptyExtension);
        if (rv != SECSuccess) {
            return SECFailure; /* Error code set already. */
        }
    }

    rv = tls13_SendEncryptedExtensions(ss);
    if (rv != SECSuccess) {
        return SECFailure; /* error code is set. */
    }

    if (tls13_ShouldRequestClientAuth(ss)) {
        rv = tls13_SendCertificateRequest(ss);
        if (rv != SECSuccess) {
            return SECFailure; /* error code is set. */
        }
    }
    if (ss->ssl3.hs.signatureScheme != ssl_sig_none) {
        SECKEYPrivateKey *svrPrivKey;

        rv = tls13_SendCertificate(ss);
        if (rv != SECSuccess) {
            return SECFailure; /* error code is set. */
        }

        svrPrivKey = ss->sec.serverCert->serverKeyPair->privKey;
        rv = tls13_SendCertificateVerify(ss, svrPrivKey);
        if (rv != SECSuccess) {
            return SECFailure; /* err code is set. */
        }
    }

    rv = tls13_SendFinished(ss, ss->ssl3.hs.serverHsTrafficSecret);
    if (rv != SECSuccess) {
        return SECFailure; /* error code is set. */
    }

    return SECSuccess;
}

/* Called from:  ssl3_HandleClientHello */
static SECStatus
tls13_SendServerHelloSequence(sslSocket *ss)
{
    SECStatus rv;
    PRErrorCode err = 0;

    SSL_TRC(3, ("%d: TLS13[%d]: begin send server_hello sequence",
                SSL_GETPID(), ss->fd));

    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));

    rv = ssl3_RegisterExtensionSender(ss, &ss->xtnData,
                                      ssl_tls13_supported_versions_xtn,
                                      tls13_ServerSendSupportedVersionsXtn);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    rv = ssl3_SendServerHello(ss);
    if (rv != SECSuccess) {
        return rv; /* err code is set. */
    }

    if (ss->ssl3.hs.fakeSid.len) {
        PORT_Assert(!IS_DTLS(ss));
        SECITEM_FreeItem(&ss->ssl3.hs.fakeSid, PR_FALSE);
        if (!ss->ssl3.hs.helloRetry) {
            rv = ssl3_SendChangeCipherSpecsInt(ss);
            if (rv != SECSuccess) {
                return rv;
            }
        }
    }

    rv = tls13_SendEncryptedServerSequence(ss);
    if (rv != SECSuccess) {
        err = PORT_GetError();
    }
    /* Even if we get an error, since the ServerHello was successfully
     * serialized, we should give it a chance to reach the network.  This gives
     * the client a chance to perform the key exchange and decrypt the alert
     * we're about to send. */
    rv |= ssl3_FlushHandshake(ss, 0);
    if (rv != SECSuccess) {
        if (err) {
            PORT_SetError(err);
        }
        return SECFailure;
    }

    /* Compute the rest of the secrets except for the resumption
     * and exporter secret. */
    rv = tls13_ComputeApplicationSecrets(ss);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, PORT_GetError());
        return SECFailure;
    }

    rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData,
                             CipherSpecWrite, PR_FALSE);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    if (IS_DTLS(ss)) {
        /* We need this for reading ACKs. */
        ssl_CipherSpecAddRef(ss->ssl3.crSpec);
    }
    if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
        rv = tls13_SetCipherSpec(ss, TrafficKeyEarlyApplicationData,
                                 CipherSpecRead, PR_TRUE);
        if (rv != SECSuccess) {
            LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
            return SECFailure;
        }
        TLS13_SET_HS_STATE(ss, wait_end_of_early_data);
    } else {
        PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_none ||
                    ss->ssl3.hs.zeroRttState == ssl_0rtt_ignored);

        rv = tls13_SetCipherSpec(ss,
                                 TrafficKeyHandshake,
                                 CipherSpecRead, PR_FALSE);
        if (rv != SECSuccess) {
            LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
            return SECFailure;
        }
        if (tls13_ShouldRequestClientAuth(ss)) {
            TLS13_SET_HS_STATE(ss, wait_client_cert);
        } else {
            TLS13_SET_HS_STATE(ss, wait_finished);
        }
    }

    ss->ssl3.hs.serverHelloTime = ssl_TimeUsec();
    return SECSuccess;
}

SECStatus
tls13_HandleServerHelloPart2(sslSocket *ss)
{
    SECStatus rv;
    sslSessionID *sid = ss->sec.ci.sid;
    SSL3Statistics *ssl3stats = SSL_GetStatistics();

    if (ssl3_ExtensionNegotiated(ss, ssl_tls13_pre_shared_key_xtn)) {
        PORT_Assert(ss->statelessResume);
    } else {
        if (ss->ssl3.hs.currentSecret) {
            PORT_Assert(ss->statelessResume);
            PK11_FreeSymKey(ss->ssl3.hs.currentSecret);
            ss->ssl3.hs.currentSecret = NULL;
        }
        ss->statelessResume = PR_FALSE;
    }

    if (ss->statelessResume) {
        PORT_Assert(sid->version >= SSL_LIBRARY_VERSION_TLS_1_3);
        if (tls13_GetHash(ss) !=
            tls13_GetHashForCipherSuite(sid->u.ssl3.cipherSuite)) {
            FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_SERVER_HELLO,
                        illegal_parameter);
            return SECFailure;
        }
    }

    /* Now create a synthetic kea_def that we can tweak. */
    ss->ssl3.hs.kea_def_mutable = *ss->ssl3.hs.kea_def;
    ss->ssl3.hs.kea_def = &ss->ssl3.hs.kea_def_mutable;

    if (ss->statelessResume) {
        /* PSK */
        ss->ssl3.hs.kea_def_mutable.authKeyType = ssl_auth_psk;
        tls13_RestoreCipherInfo(ss, sid);
        if (sid->peerCert) {
            ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
        }

        SSL_AtomicIncrementLong(&ssl3stats->hsh_sid_cache_hits);
        SSL_AtomicIncrementLong(&ssl3stats->hsh_sid_stateless_resumes);
    } else {
        /* !PSK */
        if (ssl3_ExtensionAdvertised(ss, ssl_tls13_pre_shared_key_xtn)) {
            SSL_AtomicIncrementLong(&ssl3stats->hsh_sid_cache_misses);
        }
        if (sid->cached == in_client_cache) {
            /* If we tried to resume and failed, let's not try again. */
            ssl_UncacheSessionID(ss);
        }
    }

    if (!ss->ssl3.hs.currentSecret) {
        PORT_Assert(!ss->statelessResume);

        /* If we don't already have the Early Secret we need to make it
         * now. */
        rv = tls13_ComputeEarlySecrets(ss);
        if (rv != SECSuccess) {
            FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
            return SECFailure;
        }
    }

    /* Discard current SID and make a new one, though it may eventually
     * end up looking a lot like the old one.
     */
    ssl_FreeSID(sid);
    ss->sec.ci.sid = sid = ssl3_NewSessionID(ss, PR_FALSE);
    if (sid == NULL) {
        FATAL_ERROR(ss, PORT_GetError(), internal_error);
        return SECFailure;
    }
    if (ss->statelessResume) {
        PORT_Assert(ss->sec.peerCert);
        sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
    }
    sid->version = ss->version;

    rv = tls13_HandleServerKeyShare(ss);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    rv = tls13_ComputeHandshakeSecrets(ss);
    if (rv != SECSuccess) {
        return SECFailure; /* error code is set. */
    }

    if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) {
        /* When we send 0-RTT, we saved the null spec in case we needed it to
         * send another ClientHello in response to a HelloRetryRequest.  Now
         * that we won't be receiving a HelloRetryRequest, release the spec. */
        ssl_CipherSpecReleaseByEpoch(ss, CipherSpecWrite, TrafficKeyClearText);
    }

    rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake,
                             CipherSpecRead, PR_FALSE);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SSL_ERROR_INIT_CIPHER_SUITE_FAILURE, internal_error);
        return SECFailure;
    }
    TLS13_SET_HS_STATE(ss, wait_encrypted_extensions);

    return SECSuccess;
}

static void
tls13_SetKeyExchangeType(sslSocket *ss, const sslNamedGroupDef *group)
{
    ss->sec.keaGroup = group;
    switch (group->keaType) {
        /* Note: These overwrite on resumption.... so if you start with ECDH
         * and resume with DH, we report DH. That's fine, since no answer
         * is really right. */
        case ssl_kea_ecdh:
            ss->ssl3.hs.kea_def_mutable.exchKeyType =
                ss->statelessResume ? ssl_kea_ecdh_psk : ssl_kea_ecdh;
            ss->sec.keaType = ssl_kea_ecdh;
            break;
        case ssl_kea_dh:
            ss->ssl3.hs.kea_def_mutable.exchKeyType =
                ss->statelessResume ? ssl_kea_dh_psk : ssl_kea_dh;
            ss->sec.keaType = ssl_kea_dh;
            break;
        default:
            PORT_Assert(0);
    }
}

/*
 * Called from ssl3_HandleServerHello.
 *
 * Caller must hold Handshake and RecvBuf locks.
 */
static SECStatus
tls13_HandleServerKeyShare(sslSocket *ss)
{
    SECStatus rv;
    TLS13KeyShareEntry *entry;
    sslEphemeralKeyPair *keyPair;

    SSL_TRC(3, ("%d: TLS13[%d]: handle server_key_share handshake",
                SSL_GETPID(), ss->fd));
    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    /* This list should have one entry. */
    if (PR_CLIST_IS_EMPTY(&ss->xtnData.remoteKeyShares)) {
        FATAL_ERROR(ss, SSL_ERROR_MISSING_KEY_SHARE, missing_extension);
        return SECFailure;
    }

    entry = (TLS13KeyShareEntry *)PR_NEXT_LINK(&ss->xtnData.remoteKeyShares);
    PORT_Assert(PR_NEXT_LINK(&entry->link) == &ss->xtnData.remoteKeyShares);

    /* Now get our matching key. */
    keyPair = ssl_LookupEphemeralKeyPair(ss, entry->group);
    if (!keyPair) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_KEY_SHARE, illegal_parameter);
        return SECFailure;
    }

    PORT_Assert(ssl_NamedGroupEnabled(ss, entry->group));

    rv = tls13_HandleKeyShare(ss, entry, keyPair->keys,
                              tls13_GetHash(ss),
                              &ss->ssl3.hs.dheSecret);
    if (rv != SECSuccess)
        return SECFailure; /* Error code set by caller. */

    tls13_SetKeyExchangeType(ss, entry->group);
    ss->sec.keaKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->keys->pubKey);

    return SECSuccess;
}

/*
 *    opaque ASN1Cert<1..2^24-1>;
 *
 *    struct {
 *        ASN1Cert cert_data;
 *        Extension extensions<0..2^16-1>;
 *    } CertificateEntry;
 *
 *    struct {
 *        opaque certificate_request_context<0..2^8-1>;
 *        CertificateEntry certificate_list<0..2^24-1>;
 *    } Certificate;
 */
static SECStatus
tls13_SendCertificate(sslSocket *ss)
{
    SECStatus rv;
    CERTCertificateList *certChain;
    int certChainLen = 0;
    int i;
    SECItem context = { siBuffer, NULL, 0 };
    sslBuffer extensionBuf = SSL_BUFFER_EMPTY;

    SSL_TRC(3, ("%d: TLS1.3[%d]: send certificate handshake",
                SSL_GETPID(), ss->fd));

    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    if (ss->sec.isServer) {
        PORT_Assert(!ss->sec.localCert);
        /* A server certificate is selected in tls13_SelectServerCert(). */
        PORT_Assert(ss->sec.serverCert);

        certChain = ss->sec.serverCert->serverCertChain;
        ss->sec.localCert = CERT_DupCertificate(ss->sec.serverCert->serverCert);
    } else {
        if (ss->sec.localCert)
            CERT_DestroyCertificate(ss->sec.localCert);

        certChain = ss->ssl3.clientCertChain;
        ss->sec.localCert = CERT_DupCertificate(ss->ssl3.clientCertificate);
    }

    if (!ss->sec.isServer) {
        PORT_Assert(ss->ssl3.hs.clientCertRequested);
        context = ss->xtnData.certReqContext;
    }
    if (certChain) {
        for (i = 0; i < certChain->len; i++) {
            /* Each cert is 3 octet length, cert, and extensions */
            certChainLen += 3 + certChain->certs[i].len + 2;
        }

        /* Build the extensions. This only applies to the leaf cert, because we
         * don't yet send extensions for non-leaf certs. */
        rv = ssl_ConstructExtensions(ss, &extensionBuf, ssl_hs_certificate);
        if (rv != SECSuccess) {
            return SECFailure; /* code already set */
        }
        /* extensionBuf.len is only added once, for the leaf cert. */
        certChainLen += SSL_BUFFER_LEN(&extensionBuf);
    }

    rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate,
                                    1 + context.len + 3 + certChainLen);
    if (rv != SECSuccess) {
        return SECFailure; /* err set by AppendHandshake. */
    }

    rv = ssl3_AppendHandshakeVariable(ss, context.data,
                                      context.len, 1);
    if (rv != SECSuccess) {
        goto loser; /* err set by AppendHandshake. */
    }

    rv = ssl3_AppendHandshakeNumber(ss, certChainLen, 3);
    if (rv != SECSuccess) {
        goto loser; /* err set by AppendHandshake. */
    }
    if (certChain) {
        for (i = 0; i < certChain->len; i++) {
            rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data,
                                              certChain->certs[i].len, 3);
            if (rv != SECSuccess) {
                goto loser; /* err set by AppendHandshake. */
            }

            if (i) {
                /* Not end-entity. */
                rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
                if (rv != SECSuccess) {
                    goto loser; /* err set by AppendHandshake. */
                }
                continue;
            }

            /* End-entity, send extensions. */
            rv = ssl3_AppendBufferToHandshakeVariable(ss, &extensionBuf, 2);
            if (rv != SECSuccess) {
                goto loser; /* err set by AppendHandshake. */
            }
        }
    }

    sslBuffer_Clear(&extensionBuf);
    return SECSuccess;

loser:
    sslBuffer_Clear(&extensionBuf);
    return SECFailure;
}

static SECStatus
tls13_HandleCertificateEntry(sslSocket *ss, SECItem *data, PRBool first,
                             CERTCertificate **certp)
{
    SECStatus rv;
    SECItem certData;
    SECItem extensionsData;
    CERTCertificate *cert = NULL;

    rv = ssl3_ConsumeHandshakeVariable(ss, &certData,
                                       3, &data->data, &data->len);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    rv = ssl3_ConsumeHandshakeVariable(ss, &extensionsData,
                                       2, &data->data, &data->len);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    /* Parse all the extensions. */
    if (first && !ss->sec.isServer) {
        rv = ssl3_HandleExtensions(ss, &extensionsData.data,
                                   &extensionsData.len,
                                   ssl_hs_certificate);
        if (rv != SECSuccess) {
            return SECFailure;
        }

        /* TODO(ekr@rtfm.com): Copy out SCTs. Bug 1315727. */
    }

    cert = CERT_NewTempCertificate(ss->dbHandle, &certData, NULL,
                                   PR_FALSE, PR_TRUE);

    if (!cert) {
        PRErrorCode errCode = PORT_GetError();
        switch (errCode) {
            case PR_OUT_OF_MEMORY_ERROR:
            case SEC_ERROR_BAD_DATABASE:
            case SEC_ERROR_NO_MEMORY:
                FATAL_ERROR(ss, errCode, internal_error);
                return SECFailure;
            default:
                ssl3_SendAlertForCertError(ss, errCode);
                return SECFailure;
        }
    }

    *certp = cert;

    return SECSuccess;
}

/* Called from tls13_CompleteHandleHandshakeMessage() when it has deciphered a complete
 * tls13 Certificate message.
 * Caller must hold Handshake and RecvBuf locks.
 */
static SECStatus
tls13_HandleCertificate(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
    SECStatus rv;
    SECItem context = { siBuffer, NULL, 0 };
    SECItem certList;
    PRBool first = PR_TRUE;
    ssl3CertNode *lastCert = NULL;

    SSL_TRC(3, ("%d: TLS13[%d]: handle certificate handshake",
                SSL_GETPID(), ss->fd));
    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    if (ss->sec.isServer) {
        rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_CERTIFICATE,
                                  wait_client_cert);
    } else {
        rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_CERTIFICATE,
                                  wait_cert_request, wait_server_cert);
    }
    if (rv != SECSuccess)
        return SECFailure;

    /* We can ignore any other cleartext from the client. */
    if (ss->sec.isServer && IS_DTLS(ss)) {
        ssl_CipherSpecReleaseByEpoch(ss, CipherSpecRead, TrafficKeyClearText);
        dtls_ReceivedFirstMessageInFlight(ss);
    }
    /* Process the context string */
    rv = ssl3_ConsumeHandshakeVariable(ss, &context, 1, &b, &length);
    if (rv != SECSuccess)
        return SECFailure;

    if (context.len) {
        /* The context string MUST be empty */
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERTIFICATE, illegal_parameter);
        return SECFailure;
    }

    rv = ssl3_ConsumeHandshakeVariable(ss, &certList, 3, &b, &length);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    if (length) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERTIFICATE, illegal_parameter);
        return SECFailure;
    }

    if (!certList.len) {
        if (!ss->sec.isServer) {
            /* Servers always need to send some cert. */
            FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERTIFICATE, bad_certificate);
            return SECFailure;
        } else {
            /* This is TLS's version of a no_certificate alert. */
            /* I'm a server. I've requested a client cert. He hasn't got one. */
            rv = ssl3_HandleNoCertificate(ss);
            if (rv != SECSuccess) {
                return SECFailure;
            }

            TLS13_SET_HS_STATE(ss, wait_finished);
            return SECSuccess;
        }
    }

    /* Now clean up. */
    ssl3_CleanupPeerCerts(ss);
    ss->ssl3.peerCertArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (ss->ssl3.peerCertArena == NULL) {
        FATAL_ERROR(ss, SEC_ERROR_NO_MEMORY, internal_error);
        return SECFailure;
    }

    while (certList.len) {
        CERTCertificate *cert;

        rv = tls13_HandleCertificateEntry(ss, &certList, first,
                                          &cert);
        if (rv != SECSuccess) {
            ss->xtnData.signedCertTimestamps.len = 0;
            return SECFailure;
        }

        if (first) {
            ss->sec.peerCert = cert;

            if (ss->xtnData.signedCertTimestamps.len) {
                sslSessionID *sid = ss->sec.ci.sid;
                rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.signedCertTimestamps,
                                      &ss->xtnData.signedCertTimestamps);
                ss->xtnData.signedCertTimestamps.len = 0;
                if (rv != SECSuccess) {
                    FATAL_ERROR(ss, SEC_ERROR_NO_MEMORY, internal_error);
                    return SECFailure;
                }
            }
        } else {
            ssl3CertNode *c = PORT_ArenaNew(ss->ssl3.peerCertArena,
                                            ssl3CertNode);
            if (!c) {
                FATAL_ERROR(ss, SEC_ERROR_NO_MEMORY, internal_error);
                return SECFailure;
            }
            c->cert = cert;
            c->next = NULL;

            if (lastCert) {
                lastCert->next = c;
            } else {
                ss->ssl3.peerCertChain = c;
            }
            lastCert = c;
        }

        first = PR_FALSE;
    }
    SECKEY_UpdateCertPQG(ss->sec.peerCert);

    return ssl3_AuthCertificate(ss); /* sets ss->ssl3.hs.ws */
}

/* Add context to the hash functions as described in
   [draft-ietf-tls-tls13; Section 4.9.1] */
SECStatus
tls13_AddContextToHashes(sslSocket *ss, const SSL3Hashes *hashes,
                         SSLHashType algorithm, PRBool sending,
                         SSL3Hashes *tbsHash)
{
    SECStatus rv = SECSuccess;
    PK11Context *ctx;
    const unsigned char context_padding[] = {
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    };

    const char *client_cert_verify_string = "TLS 1.3, client CertificateVerify";
    const char *server_cert_verify_string = "TLS 1.3, server CertificateVerify";
    const char *context_string = (sending ^ ss->sec.isServer) ? client_cert_verify_string
                                                              : server_cert_verify_string;
    unsigned int hashlength;

    /* Double check that we are doing the same hash.*/
    PORT_Assert(hashes->len == tls13_GetHashSize(ss));

    ctx = PK11_CreateDigestContext(ssl3_HashTypeToOID(algorithm));
    if (!ctx) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    PORT_Assert(SECFailure);
    PORT_Assert(!SECSuccess);

    PRINT_BUF(50, (ss, "TLS 1.3 hash without context", hashes->u.raw, hashes->len));
    PRINT_BUF(50, (ss, "Context string", context_string, strlen(context_string)));
    rv |= PK11_DigestBegin(ctx);
    rv |= PK11_DigestOp(ctx, context_padding, sizeof(context_padding));
    rv |= PK11_DigestOp(ctx, (unsigned char *)context_string,
                        strlen(context_string) + 1); /* +1 includes the terminating 0 */
    rv |= PK11_DigestOp(ctx, hashes->u.raw, hashes->len);
    /* Update the hash in-place */
    rv |= PK11_DigestFinal(ctx, tbsHash->u.raw, &hashlength, sizeof(tbsHash->u.raw));
    PK11_DestroyContext(ctx, PR_TRUE);
    PRINT_BUF(50, (ss, "TLS 1.3 hash with context", tbsHash->u.raw, hashlength));

    tbsHash->len = hashlength;
    tbsHash->hashAlg = algorithm;

    if (rv) {
        ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
        goto loser;
    }
    return SECSuccess;

loser:
    return SECFailure;
}

/*
 *    Derive-Secret(Secret, Label, Messages) =
 *       HKDF-Expand-Label(Secret, Label,
 *                         Hash(Messages) + Hash(resumption_context), L))
 */
SECStatus
tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key,
                   const char *label,
                   unsigned int labelLen,
                   const SSL3Hashes *hashes,
                   PK11SymKey **dest)
{
    SECStatus rv;

    rv = tls13_HkdfExpandLabel(key, tls13_GetHash(ss),
                               hashes->u.raw, hashes->len,
                               label, labelLen,
                               tls13_GetHkdfMechanism(ss),
                               tls13_GetHashSize(ss), dest);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    return SECSuccess;
}

/* Convenience wrapper for the empty hash. */
SECStatus
tls13_DeriveSecretNullHash(sslSocket *ss, PK11SymKey *key,
                           const char *label,
                           unsigned int labelLen,
                           PK11SymKey **dest)
{
    SSL3Hashes hashes;
    SECStatus rv;
    PRUint8 buf[] = { 0 };

    rv = tls13_ComputeHash(ss, &hashes, buf, 0);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    return tls13_DeriveSecret(ss, key, label, labelLen, &hashes, dest);
}

/* Convenience wrapper that lets us supply a separate prefix and suffix. */
static SECStatus
tls13_DeriveSecretWrap(sslSocket *ss, PK11SymKey *key,
                       const char *prefix,
                       const char *suffix,
                       const char *keylogLabel,
                       PK11SymKey **dest)
{
    SECStatus rv;
    SSL3Hashes hashes;
    char buf[100];
    const char *label;

    if (prefix) {
        if ((strlen(prefix) + strlen(suffix) + 2) > sizeof(buf)) {
            PORT_Assert(0);
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
            return SECFailure;
        }
        (void)PR_snprintf(buf, sizeof(buf), "%s %s",
                          prefix, suffix);
        label = buf;
    } else {
        label = suffix;
    }

    SSL_TRC(3, ("%d: TLS13[%d]: deriving secret '%s'",
                SSL_GETPID(), ss->fd, label));
    rv = tls13_ComputeHandshakeHashes(ss, &hashes);
    if (rv != SECSuccess) {
        PORT_Assert(0); /* Should never fail */
        ssl_MapLowLevelError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    rv = tls13_DeriveSecret(ss, key, label, strlen(label),
                            &hashes, dest);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    if (keylogLabel) {
        ssl3_RecordKeyLog(ss, keylogLabel, *dest);
    }
    return SECSuccess;
}

/* Derive traffic keys for the next cipher spec in the queue. */
static SECStatus
tls13_DeriveTrafficKeys(sslSocket *ss, ssl3CipherSpec *spec,
                        TrafficKeyType type,
                        PRBool deleteSecret)
{
    size_t keySize = spec->cipherDef->key_size;
    size_t ivSize = spec->cipherDef->iv_size +
                    spec->cipherDef->explicit_nonce_size; /* This isn't always going to
                                                           * work, but it does for
                                                           * AES-GCM */
    CK_MECHANISM_TYPE bulkAlgorithm = ssl3_Alg2Mech(spec->cipherDef->calg);
    PK11SymKey **prkp = NULL;
    PK11SymKey *prk = NULL;
    PRBool clientSecret;
    SECStatus rv;
    /* These labels are just used for debugging. */
    static const char kHkdfPhaseEarlyApplicationDataKeys[] = "early application data";
    static const char kHkdfPhaseHandshakeKeys[] = "handshake data";
    static const char kHkdfPhaseApplicationDataKeys[] = "application data";

    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    clientSecret = !tls13_UseServerSecret(ss, spec->direction);
    switch (type) {
        case TrafficKeyEarlyApplicationData:
            PORT_Assert(clientSecret);
            prkp = &ss->ssl3.hs.clientEarlyTrafficSecret;
            spec->phase = kHkdfPhaseEarlyApplicationDataKeys;
            break;
        case TrafficKeyHandshake:
            prkp = clientSecret ? &ss->ssl3.hs.clientHsTrafficSecret
                                : &ss->ssl3.hs.serverHsTrafficSecret;
            spec->phase = kHkdfPhaseHandshakeKeys;
            break;
        case TrafficKeyApplicationData:
            prkp = clientSecret ? &ss->ssl3.hs.clientTrafficSecret
                                : &ss->ssl3.hs.serverTrafficSecret;
            spec->phase = kHkdfPhaseApplicationDataKeys;
            break;
        default:
            LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
            PORT_Assert(0);
            return SECFailure;
    }
    PORT_Assert(prkp != NULL);
    prk = *prkp;

    SSL_TRC(3, ("%d: TLS13[%d]: deriving %s traffic keys epoch=%d (%s)",
                SSL_GETPID(), ss->fd, SPEC_DIR(spec),
                spec->epoch, spec->phase));

    rv = tls13_HkdfExpandLabel(prk, tls13_GetHash(ss),
                               NULL, 0,
                               kHkdfPurposeKey, strlen(kHkdfPurposeKey),
                               bulkAlgorithm, keySize,
                               &spec->keyMaterial.key);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        PORT_Assert(0);
        goto loser;
    }

    rv = tls13_HkdfExpandLabelRaw(prk, tls13_GetHash(ss),
                                  NULL, 0,
                                  kHkdfPurposeIv, strlen(kHkdfPurposeIv),
                                  spec->keyMaterial.iv, ivSize);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        PORT_Assert(0);
        goto loser;
    }

    if (deleteSecret) {
        PK11_FreeSymKey(prk);
        *prkp = NULL;
    }
    return SECSuccess;

loser:
    return SECFailure;
}

void
tls13_SetSpecRecordVersion(sslSocket *ss, ssl3CipherSpec *spec)
{
    /* Set the record version to pretend to be (D)TLS 1.2. */
    if (IS_DTLS(ss)) {
        spec->recordVersion = SSL_LIBRARY_VERSION_DTLS_1_2_WIRE;
    } else {
        spec->recordVersion = SSL_LIBRARY_VERSION_TLS_1_2;
    }
    SSL_TRC(10, ("%d: TLS13[%d]: set spec=%d record version to 0x%04x",
                 SSL_GETPID(), ss->fd, spec, spec->recordVersion));
}

SSLAEADCipher
tls13_GetAead(const ssl3BulkCipherDef *cipherDef)
{
    switch (cipherDef->calg) {
        case ssl_calg_aes_gcm:
            return tls13_AESGCM;
        case ssl_calg_chacha20:
            return tls13_ChaCha20Poly1305;
        default:
            PORT_Assert(PR_FALSE);
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
            return NULL;
    }
}

static SECStatus
tls13_SetupPendingCipherSpec(sslSocket *ss, ssl3CipherSpec *spec)
{
    ssl3CipherSuite suite = ss->ssl3.hs.cipher_suite;

    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert(spec->epoch);

    /* Version isn't set when we send 0-RTT data. */
    spec->version = PR_MAX(SSL_LIBRARY_VERSION_TLS_1_3, ss->version);

    ssl_SaveCipherSpec(ss, spec);
    /* We want to keep read cipher specs around longer because
     * there are cases where we might get either epoch N or
     * epoch N+1. */
    if (IS_DTLS(ss) && spec->direction == CipherSpecRead) {
        ssl_CipherSpecAddRef(spec);
    }

    SSL_TRC(3, ("%d: TLS13[%d]: Set Pending Cipher Suite to 0x%04x",
                SSL_GETPID(), ss->fd, suite));

    spec->cipherDef = ssl_GetBulkCipherDef(ssl_LookupCipherSuiteDef(suite));
    spec->aead = tls13_GetAead(spec->cipherDef);
    if (!spec->aead) {
        return SECFailure;
    }

    if (spec->epoch == TrafficKeyEarlyApplicationData) {
        spec->earlyDataRemaining =
            ss->sec.ci.sid->u.ssl3.locked.sessionTicket.max_early_data_size;
    }

    tls13_SetSpecRecordVersion(ss, spec);

    /* The record size limit is reduced by one so that the remainder of the
     * record handling code can use the same checks for all versions. */
    if (ssl3_ExtensionNegotiated(ss, ssl_record_size_limit_xtn)) {
        spec->recordSizeLimit = ((spec->direction == CipherSpecRead)
                                     ? ss->opt.recordSizeLimit
                                     : ss->xtnData.recordSizeLimit) -
                                1;
    } else {
        spec->recordSizeLimit = MAX_FRAGMENT_LENGTH;
    }
    return SECSuccess;
}

/*
 * Called before sending alerts to set up the right key on the client.
 * We might encounter errors during the handshake where the current
 * key is ClearText or EarlyApplicationData. This
 * function switches to the Handshake key if possible.
 */
SECStatus
tls13_SetAlertCipherSpec(sslSocket *ss)
{
    SECStatus rv;

    if (ss->sec.isServer) {
        return SECSuccess;
    }
    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
        return SECSuccess;
    }
    if (TLS13_IN_HS_STATE(ss, wait_server_hello)) {
        return SECSuccess;
    }
    if ((ss->ssl3.cwSpec->epoch != TrafficKeyClearText) &&
        (ss->ssl3.cwSpec->epoch != TrafficKeyEarlyApplicationData)) {
        return SECSuccess;
    }

    rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake,
                             CipherSpecWrite, PR_FALSE);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    return SECSuccess;
}

/* Install a new cipher spec for this direction.
 *
 * During the handshake, the values for |epoch| take values from the
 * TrafficKeyType enum.  Afterwards, key update increments them.
 */
static SECStatus
tls13_SetCipherSpec(sslSocket *ss, PRUint16 epoch,
                    CipherSpecDirection direction, PRBool deleteSecret)
{
    TrafficKeyType type;
    SECStatus rv;
    ssl3CipherSpec *spec = NULL;
    ssl3CipherSpec **specp;

    /* Flush out old handshake data. */
    ssl_GetXmitBufLock(ss);
    rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
    ssl_ReleaseXmitBufLock(ss);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    /* Create the new spec. */
    spec = ssl_CreateCipherSpec(ss, direction);
    if (!spec) {
        return SECFailure;
    }
    spec->epoch = epoch;
    spec->nextSeqNum = 0;
    if (IS_DTLS(ss)) {
        dtls_InitRecvdRecords(&spec->recvdRecords);
    }

    /* This depends on spec having a valid direction and epoch. */
    rv = tls13_SetupPendingCipherSpec(ss, spec);
    if (rv != SECSuccess) {
        goto loser;
    }

    type = (TrafficKeyType)PR_MIN(TrafficKeyApplicationData, epoch);
    rv = tls13_DeriveTrafficKeys(ss, spec, type, deleteSecret);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* Now that we've set almost everything up, finally cut over. */
    specp = (direction == CipherSpecRead) ? &ss->ssl3.crSpec : &ss->ssl3.cwSpec;
    ssl_GetSpecWriteLock(ss);
    ssl_CipherSpecRelease(*specp); /* May delete old cipher. */
    *specp = spec;                 /* Overwrite. */
    ssl_ReleaseSpecWriteLock(ss);

    SSL_TRC(3, ("%d: TLS13[%d]: %s installed key for epoch=%d (%s) dir=%s",
                SSL_GETPID(), ss->fd, SSL_ROLE(ss), spec->epoch,
                spec->phase, SPEC_DIR(spec)));

    if (ss->ssl3.changedCipherSpecFunc) {
        ss->ssl3.changedCipherSpecFunc(ss->ssl3.changedCipherSpecArg,
                                       direction == CipherSpecWrite, spec);
    }
    return SECSuccess;

loser:
    ssl_CipherSpecRelease(spec);
    return SECFailure;
}

SECStatus
tls13_ComputeHandshakeHashes(sslSocket *ss, SSL3Hashes *hashes)
{
    SECStatus rv;
    PK11Context *ctx = NULL;

    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    if (ss->ssl3.hs.hashType == handshake_hash_unknown) {
        /* Backup: if we haven't done any hashing, then hash now.
         * This happens when we are doing 0-RTT on the client. */
        ctx = PK11_CreateDigestContext(ssl3_HashTypeToOID(tls13_GetHash(ss)));
        if (!ctx) {
            ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
            return SECFailure;
        }

        if (PK11_DigestBegin(ctx) != SECSuccess) {
            ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
            goto loser;
        }

        PRINT_BUF(10, (ss, "Handshake hash computed over saved messages",
                       ss->ssl3.hs.messages.buf,
                       ss->ssl3.hs.messages.len));

        if (PK11_DigestOp(ctx,
                          ss->ssl3.hs.messages.buf,
                          ss->ssl3.hs.messages.len) != SECSuccess) {
            ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
            goto loser;
        }
    } else {
        ctx = PK11_CloneContext(ss->ssl3.hs.sha);
        if (!ctx) {
            ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
            return SECFailure;
        }
    }

    rv = PK11_DigestFinal(ctx, hashes->u.raw,
                          &hashes->len,
                          sizeof(hashes->u.raw));
    if (rv != SECSuccess) {
        ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
        goto loser;
    }

    PRINT_BUF(10, (ss, "Handshake hash", hashes->u.raw, hashes->len));
    PORT_Assert(hashes->len == tls13_GetHashSize(ss));
    PK11_DestroyContext(ctx, PR_TRUE);

    return SECSuccess;

loser:
    PK11_DestroyContext(ctx, PR_TRUE);
    return SECFailure;
}

TLS13KeyShareEntry *
tls13_CopyKeyShareEntry(TLS13KeyShareEntry *o)
{
    TLS13KeyShareEntry *n;

    PORT_Assert(o);
    n = PORT_ZNew(TLS13KeyShareEntry);
    if (!n) {
        return NULL;
    }

    if (SECSuccess != SECITEM_CopyItem(NULL, &n->key_exchange, &o->key_exchange)) {
        PORT_Free(n);
        return NULL;
    }
    n->group = o->group;
    return n;
}

void
tls13_DestroyKeyShareEntry(TLS13KeyShareEntry *offer)
{
    if (!offer) {
        return;
    }
    SECITEM_ZfreeItem(&offer->key_exchange, PR_FALSE);
    PORT_ZFree(offer, sizeof(*offer));
}

void
tls13_DestroyKeyShares(PRCList *list)
{
    PRCList *cur_p;

    /* The list must be initialized. */
    PORT_Assert(PR_LIST_HEAD(list));

    while (!PR_CLIST_IS_EMPTY(list)) {
        cur_p = PR_LIST_TAIL(list);
        PR_REMOVE_LINK(cur_p);
        tls13_DestroyKeyShareEntry((TLS13KeyShareEntry *)cur_p);
    }
}

void
tls13_DestroyEarlyData(PRCList *list)
{
    PRCList *cur_p;

    while (!PR_CLIST_IS_EMPTY(list)) {
        TLS13EarlyData *msg;

        cur_p = PR_LIST_TAIL(list);
        msg = (TLS13EarlyData *)cur_p;

        PR_REMOVE_LINK(cur_p);
        SECITEM_ZfreeItem(&msg->data, PR_FALSE);
        PORT_ZFree(msg, sizeof(*msg));
    }
}

/* draft-ietf-tls-tls13 Section 5.2.2 specifies the following
 * nonce algorithm:
 *
 * The length of the per-record nonce (iv_length) is set to max(8 bytes,
 * N_MIN) for the AEAD algorithm (see [RFC5116] Section 4).  An AEAD
 * algorithm where N_MAX is less than 8 bytes MUST NOT be used with TLS.
 * The per-record nonce for the AEAD construction is formed as follows:
 *
 * 1.  The 64-bit record sequence number is padded to the left with
 *     zeroes to iv_length.
 *
 * 2.  The padded sequence number is XORed with the static
 *     client_write_iv or server_write_iv, depending on the role.
 *
 * The resulting quantity (of length iv_length) is used as the per-
 * record nonce.
 *
 * Existing suites have the same nonce size: N_MIN = N_MAX = 12 bytes
 *
 * See RFC 5288 and https://tools.ietf.org/html/draft-ietf-tls-chacha20-poly1305-04#section-2
 */
static void
tls13_WriteNonce(ssl3KeyMaterial *keys,
                 const unsigned char *seqNumBuf, unsigned int seqNumLen,
                 unsigned char *nonce, unsigned int nonceLen)
{
    size_t i;

    PORT_Assert(nonceLen == 12);
    memcpy(nonce, keys->iv, 12);

    /* XOR the last 8 bytes of the IV with the sequence number. */
    PORT_Assert(seqNumLen == 8);
    for (i = 0; i < 8; ++i) {
        nonce[4 + i] ^= seqNumBuf[i];
    }
    PRINT_BUF(50, (NULL, "Nonce", nonce, nonceLen));
}

/* Implement the SSLAEADCipher interface defined in sslimpl.h.
 *
 * That interface takes the additional data (see below) and reinterprets that as
 * a sequence number. In TLS 1.3 there is no additional data so this value is
 * just the encoded sequence number.
 */
static SECStatus
tls13_AEAD(ssl3KeyMaterial *keys, PRBool doDecrypt,
           unsigned char *out, int *outlen, int maxout,
           const unsigned char *in, int inlen,
           CK_MECHANISM_TYPE mechanism,
           unsigned char *aeadParams, unsigned int aeadParamLength)
{
    SECStatus rv;
    unsigned int uOutLen = 0;
    SECItem param = {
        siBuffer, aeadParams, aeadParamLength
    };

    if (doDecrypt) {
        rv = PK11_Decrypt(keys->key, mechanism, &param,
                          out, &uOutLen, maxout, in, inlen);
    } else {
        rv = PK11_Encrypt(keys->key, mechanism, &param,
                          out, &uOutLen, maxout, in, inlen);
    }
    *outlen = (int)uOutLen;

    return rv;
}

static SECStatus
tls13_AESGCM(ssl3KeyMaterial *keys,
             PRBool doDecrypt,
             unsigned char *out,
             int *outlen,
             int maxout,
             const unsigned char *in,
             int inlen,
             const unsigned char *additionalData,
             int additionalDataLen)
{
    CK_GCM_PARAMS gcmParams;
    unsigned char nonce[12];

    PORT_Assert(additionalDataLen >= 8);
    memset(&gcmParams, 0, sizeof(gcmParams));
    gcmParams.pIv = nonce;
    gcmParams.ulIvLen = sizeof(nonce);
    gcmParams.pAAD = (PRUint8 *)(additionalData + 8);
    gcmParams.ulAADLen = additionalDataLen - 8;
    gcmParams.ulTagBits = 128; /* GCM measures tag length in bits. */

    tls13_WriteNonce(keys, additionalData, 8,
                     nonce, sizeof(nonce));
    return tls13_AEAD(keys, doDecrypt, out, outlen, maxout, in, inlen,
                      CKM_AES_GCM,
                      (unsigned char *)&gcmParams, sizeof(gcmParams));
}

static SECStatus
tls13_ChaCha20Poly1305(ssl3KeyMaterial *keys, PRBool doDecrypt,
                       unsigned char *out, int *outlen, int maxout,
                       const unsigned char *in, int inlen,
                       const unsigned char *additionalData,
                       int additionalDataLen)
{
    CK_NSS_AEAD_PARAMS aeadParams;
    unsigned char nonce[12];

    PORT_Assert(additionalDataLen > 8);
    memset(&aeadParams, 0, sizeof(aeadParams));
    aeadParams.pNonce = nonce;
    aeadParams.ulNonceLen = sizeof(nonce);
    aeadParams.pAAD = (PRUint8 *)(additionalData + 8);
    aeadParams.ulAADLen = additionalDataLen - 8;
    aeadParams.ulTagLen = 16; /* The Poly1305 tag is 16 octets. */

    tls13_WriteNonce(keys, additionalData, 8,
                     nonce, sizeof(nonce));
    return tls13_AEAD(keys, doDecrypt, out, outlen, maxout, in, inlen,
                      CKM_NSS_CHACHA20_POLY1305,
                      (unsigned char *)&aeadParams, sizeof(aeadParams));
}

static SECStatus
tls13_HandleEncryptedExtensions(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
    SECStatus rv;
    PRUint32 innerLength;
    SECItem oldAlpn = { siBuffer, NULL, 0 };

    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    SSL_TRC(3, ("%d: TLS13[%d]: handle encrypted extensions",
                SSL_GETPID(), ss->fd));

    rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_ENCRYPTED_EXTENSIONS,
                              wait_encrypted_extensions);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    rv = ssl3_ConsumeHandshakeNumber(ss, &innerLength, 2, &b, &length);
    if (rv != SECSuccess) {
        return SECFailure; /* Alert already sent. */
    }
    if (innerLength != length) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_ENCRYPTED_EXTENSIONS,
                    illegal_parameter);
        return SECFailure;
    }

    /* If we are doing 0-RTT, then we already have an ALPN value. Stash
     * it for comparison. */
    if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent &&
        ss->xtnData.nextProtoState == SSL_NEXT_PROTO_EARLY_VALUE) {
        oldAlpn = ss->xtnData.nextProto;
        ss->xtnData.nextProto.data = NULL;
        ss->xtnData.nextProtoState = SSL_NEXT_PROTO_NO_SUPPORT;
    }

    rv = ssl3_ParseExtensions(ss, &b, &length);
    if (rv != SECSuccess) {
        return SECFailure; /* Error code set below */
    }

    /* If we sent ESNI, check the nonce. */
    if (ss->xtnData.esniPrivateKey) {
        PORT_Assert(ssl3_ExtensionAdvertised(ss, ssl_tls13_encrypted_sni_xtn));
        rv = tls13_ClientCheckEsniXtn(ss);
        if (rv != SECSuccess) {
            return SECFailure;
        }
    }

    /* Handle the rest of the extensions. */
    rv = ssl3_HandleParsedExtensions(ss, ssl_hs_encrypted_extensions);
    if (rv != SECSuccess) {
        return SECFailure; /* Error code set below */
    }

    /* We can only get here if we offered 0-RTT. */
    if (ssl3_ExtensionNegotiated(ss, ssl_tls13_early_data_xtn)) {
        PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_sent);
        if (!ss->statelessResume) {
            /* Illegal to accept 0-RTT without also accepting PSK. */
            FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_ENCRYPTED_EXTENSIONS,
                        illegal_parameter);
        }
        ss->ssl3.hs.zeroRttState = ssl_0rtt_accepted;

        /* Check that the server negotiated the same ALPN (if any). */
        if (SECITEM_CompareItem(&oldAlpn, &ss->xtnData.nextProto)) {
            SECITEM_FreeItem(&oldAlpn, PR_FALSE);
            FATAL_ERROR(ss, SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID,
                        illegal_parameter);
            return SECFailure;
        }
        /* Check that the server negotiated the same cipher suite. */
        if (ss->ssl3.hs.cipher_suite != ss->ssl3.hs.zeroRttSuite) {
            FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_ENCRYPTED_EXTENSIONS,
                        illegal_parameter);
            return SECFailure;
        }
    } else if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) {
        /* Though we sent 0-RTT, the early_data extension wasn't present so the
         * state is unmodified; the server must have rejected 0-RTT. */
        ss->ssl3.hs.zeroRttState = ssl_0rtt_ignored;
        ss->ssl3.hs.zeroRttIgnore = ssl_0rtt_ignore_trial;
    } else {
        PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_none ||
                    (ss->ssl3.hs.helloRetry &&
                     ss->ssl3.hs.zeroRttState == ssl_0rtt_ignored));
    }

    SECITEM_FreeItem(&oldAlpn, PR_FALSE);
    if (ss->ssl3.hs.kea_def->authKeyType == ssl_auth_psk) {
        TLS13_SET_HS_STATE(ss, wait_finished);
    } else {
        TLS13_SET_HS_STATE(ss, wait_cert_request);
    }

    return SECSuccess;
}

static SECStatus
tls13_SendEncryptedExtensions(sslSocket *ss)
{
    sslBuffer extensions = SSL_BUFFER_EMPTY;
    SECStatus rv;

    SSL_TRC(3, ("%d: TLS13[%d]: send encrypted extensions handshake",
                SSL_GETPID(), ss->fd));

    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));

    rv = ssl_ConstructExtensions(ss, &extensions, ssl_hs_encrypted_extensions);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_encrypted_extensions,
                                    SSL_BUFFER_LEN(&extensions) + 2);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        goto loser;
    }
    rv = ssl3_AppendBufferToHandshakeVariable(ss, &extensions, 2);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        goto loser;
    }
    sslBuffer_Clear(&extensions);
    return SECSuccess;

loser:
    sslBuffer_Clear(&extensions);
    return SECFailure;
}

SECStatus
tls13_SendCertificateVerify(sslSocket *ss, SECKEYPrivateKey *privKey)
{
    SECStatus rv = SECFailure;
    SECItem buf = { siBuffer, NULL, 0 };
    unsigned int len;
    SSLHashType hashAlg;
    SSL3Hashes hash;
    SSL3Hashes tbsHash; /* The hash "to be signed". */

    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    SSL_TRC(3, ("%d: TLS13[%d]: send certificate_verify handshake",
                SSL_GETPID(), ss->fd));

    PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_single);
    rv = tls13_ComputeHandshakeHashes(ss, &hash);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    /* We should have picked a signature scheme when we received a
     * CertificateRequest, or when we picked a server certificate. */
    PORT_Assert(ss->ssl3.hs.signatureScheme != ssl_sig_none);
    if (ss->ssl3.hs.signatureScheme == ssl_sig_none) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    hashAlg = ssl_SignatureSchemeToHashType(ss->ssl3.hs.signatureScheme);
    rv = tls13_AddContextToHashes(ss, &hash, hashAlg,
                                  PR_TRUE, &tbsHash);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    rv = ssl3_SignHashes(ss, &tbsHash, privKey, &buf);
    if (rv == SECSuccess && !ss->sec.isServer) {
        /* Remember the info about the slot that did the signing.
         * Later, when doing an SSL restart handshake, verify this.
         * These calls are mere accessors, and can't fail.
         */
        PK11SlotInfo *slot;
        sslSessionID *sid = ss->sec.ci.sid;

        slot = PK11_GetSlotFromPrivateKey(privKey);
        sid->u.ssl3.clAuthSeries = PK11_GetSlotSeries(slot);
        sid->u.ssl3.clAuthSlotID = PK11_GetSlotID(slot);
        sid->u.ssl3.clAuthModuleID = PK11_GetModuleID(slot);
        sid->u.ssl3.clAuthValid = PR_TRUE;
        PK11_FreeSlot(slot);
    }
    if (rv != SECSuccess) {
        goto done; /* err code was set by ssl3_SignHashes */
    }

    len = buf.len + 2 + 2;

    rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate_verify, len);
    if (rv != SECSuccess) {
        goto done; /* error code set by AppendHandshake */
    }

    rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.signatureScheme, 2);
    if (rv != SECSuccess) {
        goto done; /* err set by AppendHandshakeNumber */
    }

    rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2);
    if (rv != SECSuccess) {
        goto done; /* error code set by AppendHandshake */
    }

done:
    /* For parity with the allocation functions, which don't use
     * SECITEM_AllocItem(). */
    if (buf.data)
        PORT_Free(buf.data);
    return rv;
}

/* Called from tls13_CompleteHandleHandshakeMessage() when it has deciphered a complete
 * tls13 CertificateVerify message
 * Caller must hold Handshake and RecvBuf locks.
 */
SECStatus
tls13_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
    SECItem signed_hash = { siBuffer, NULL, 0 };
    SECStatus rv;
    SSLSignatureScheme sigScheme;
    SSLHashType hashAlg;
    SSL3Hashes tbsHash;
    SSL3Hashes hashes;

    SSL_TRC(3, ("%d: TLS13[%d]: handle certificate_verify handshake",
                SSL_GETPID(), ss->fd));
    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY,
                              wait_cert_verify);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    rv = tls13_ComputeHandshakeHashes(ss, &hashes);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    rv = ssl_HashHandshakeMessage(ss, ssl_hs_certificate_verify, b, length);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    rv = ssl_ConsumeSignatureScheme(ss, &b, &length, &sigScheme);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_VERIFY, illegal_parameter);
        return SECFailure;
    }

    rv = ssl_CheckSignatureSchemeConsistency(ss, sigScheme, ss->sec.peerCert);
    if (rv != SECSuccess) {
        /* Error set already */
        FATAL_ERROR(ss, PORT_GetError(), illegal_parameter);
        return SECFailure;
    }
    hashAlg = ssl_SignatureSchemeToHashType(sigScheme);

    rv = tls13_AddContextToHashes(ss, &hashes, hashAlg, PR_FALSE, &tbsHash);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SSL_ERROR_DIGEST_FAILURE, internal_error);
        return SECFailure;
    }

    rv = ssl3_ConsumeHandshakeVariable(ss, &signed_hash, 2, &b, &length);
    if (rv != SECSuccess) {
        PORT_SetError(SSL_ERROR_RX_MALFORMED_CERT_VERIFY);
        return SECFailure;
    }

    if (length != 0) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_VERIFY, decode_error);
        return SECFailure;
    }

    rv = ssl3_VerifySignedHashes(ss, sigScheme, &tbsHash, &signed_hash);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, PORT_GetError(), decrypt_error);
        return SECFailure;
    }

    /* Set the auth type. */
    if (!ss->sec.isServer) {
        ss->sec.authType = ssl_SignatureSchemeToAuthType(sigScheme);
    }

    /* Request a client certificate now if one was requested. */
    if (ss->ssl3.hs.clientCertRequested) {
        PORT_Assert(!ss->sec.isServer);
        rv = ssl3_CompleteHandleCertificateRequest(
            ss, ss->xtnData.sigSchemes, ss->xtnData.numSigSchemes,
            &ss->xtnData.certReqAuthorities);
        if (rv != SECSuccess) {
            FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
            return rv;
        }
    }

    TLS13_SET_HS_STATE(ss, wait_finished);

    return SECSuccess;
}

static SECStatus
tls13_ComputePskBinderHash(sslSocket *ss, unsigned int prefixLength,
                           SSL3Hashes *hashes)
{
    SECStatus rv;

    PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_unknown);
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert(prefixLength <= ss->ssl3.hs.messages.len);

    PRINT_BUF(10, (NULL, "Handshake hash computed over ClientHello prefix",
                   ss->ssl3.hs.messages.buf, prefixLength));
    rv = PK11_HashBuf(ssl3_HashTypeToOID(tls13_GetHash(ss)),
                      hashes->u.raw, ss->ssl3.hs.messages.buf, prefixLength);
    if (rv != SECSuccess) {
        ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
        return SECFailure;
    }

    hashes->len = tls13_GetHashSize(ss);
    PRINT_BUF(10, (NULL, "PSK Binder hash", hashes->u.raw, hashes->len));

    return SECSuccess;
}

/* Compute and inject the PSK Binder for sending.
 *
 * When sending a ClientHello, we construct all the extensions with a dummy
 * value for the binder.  To construct the binder, we commit the entire message
 * up to the point where the binders start.  Then we calculate the hash using
 * the saved message (in ss->ssl3.hs.messages).  This is written over the dummy
 * binder, after which we write the remainder of the binder extension. */
SECStatus
tls13_WriteExtensionsWithBinder(sslSocket *ss, sslBuffer *extensions)
{
    SSL3Hashes hashes;
    SECStatus rv;
    unsigned int size = tls13_GetHashSize(ss);
    unsigned int prefixLen = extensions->len - size - 3;
    unsigned int finishedLen;

    PORT_Assert(extensions->len >= size + 3);

    rv = ssl3_AppendHandshakeNumber(ss, extensions->len, 2);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    /* Only write the extension up to the point before the binders.  Assume that
     * the pre_shared_key extension is at the end of the buffer.  Don't write
     * the binder, or the lengths that precede it (a 2 octet length for the list
     * of all binders, plus a 1 octet length for the binder length). */
    rv = ssl3_AppendHandshake(ss, extensions->buf, prefixLen);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    /* Calculate the binder based on what has been written out. */
    rv = tls13_ComputePskBinderHash(ss, ss->ssl3.hs.messages.len, &hashes);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    /* Write the binder into the extensions buffer, over the zeros we reserved
     * previously.  This avoids an allocation and means that we don't need a
     * separate write for the extra bits that precede the binder. */
    rv = tls13_ComputeFinished(ss, ss->ssl3.hs.pskBinderKey, &hashes, PR_TRUE,
                               extensions->buf + extensions->len - size,
                               &finishedLen, size);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    PORT_Assert(finishedLen == size);

    /* Write out the remainder of the extension. */
    rv = ssl3_AppendHandshake(ss, extensions->buf + prefixLen,
                              extensions->len - prefixLen);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    return SECSuccess;
}

static SECStatus
tls13_ComputeFinished(sslSocket *ss, PK11SymKey *baseKey,
                      const SSL3Hashes *hashes,
                      PRBool sending, PRUint8 *output, unsigned int *outputLen,
                      unsigned int maxOutputLen)
{
    SECStatus rv;
    PK11Context *hmacCtx = NULL;
    CK_MECHANISM_TYPE macAlg = tls13_GetHmacMechanism(ss);
    SECItem param = { siBuffer, NULL, 0 };
    unsigned int outputLenUint;
    const char *label = kHkdfLabelFinishedSecret;
    PK11SymKey *secret = NULL;

    PORT_Assert(baseKey);
    SSL_TRC(3, ("%d: TLS13[%d]: %s calculate finished",
                SSL_GETPID(), ss->fd, SSL_ROLE(ss)));
    PRINT_BUF(50, (ss, "Handshake hash", hashes->u.raw, hashes->len));

    /* Now derive the appropriate finished secret from the base secret. */
    rv = tls13_HkdfExpandLabel(baseKey,
                               tls13_GetHash(ss),
                               NULL, 0,
                               label, strlen(label),
                               tls13_GetHmacMechanism(ss),
                               tls13_GetHashSize(ss), &secret);
    if (rv != SECSuccess) {
        goto abort;
    }

    PORT_Assert(hashes->len == tls13_GetHashSize(ss));
    hmacCtx = PK11_CreateContextBySymKey(macAlg, CKA_SIGN,
                                         secret, &param);
    if (!hmacCtx) {
        goto abort;
    }

    rv = PK11_DigestBegin(hmacCtx);
    if (rv != SECSuccess)
        goto abort;

    rv = PK11_DigestOp(hmacCtx, hashes->u.raw, hashes->len);
    if (rv != SECSuccess)
        goto abort;

    PORT_Assert(maxOutputLen >= tls13_GetHashSize(ss));
    rv = PK11_DigestFinal(hmacCtx, output, &outputLenUint, maxOutputLen);
    if (rv != SECSuccess)
        goto abort;
    *outputLen = outputLenUint;

    PK11_FreeSymKey(secret);
    PK11_DestroyContext(hmacCtx, PR_TRUE);
    PRINT_BUF(50, (ss, "finished value", output, outputLenUint));
    return SECSuccess;

abort:
    if (secret) {
        PK11_FreeSymKey(secret);
    }

    if (hmacCtx) {
        PK11_DestroyContext(hmacCtx, PR_TRUE);
    }

    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
    return SECFailure;
}

static SECStatus
tls13_SendFinished(sslSocket *ss, PK11SymKey *baseKey)
{
    SECStatus rv;
    PRUint8 finishedBuf[TLS13_MAX_FINISHED_SIZE];
    unsigned int finishedLen;
    SSL3Hashes hashes;

    SSL_TRC(3, ("%d: TLS13[%d]: send finished handshake", SSL_GETPID(), ss->fd));

    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    rv = tls13_ComputeHandshakeHashes(ss, &hashes);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    ssl_GetSpecReadLock(ss);
    rv = tls13_ComputeFinished(ss, baseKey, &hashes, PR_TRUE,
                               finishedBuf, &finishedLen, sizeof(finishedBuf));
    ssl_ReleaseSpecReadLock(ss);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_finished, finishedLen);
    if (rv != SECSuccess) {
        return SECFailure; /* Error code already set. */
    }

    rv = ssl3_AppendHandshake(ss, finishedBuf, finishedLen);
    if (rv != SECSuccess) {
        return SECFailure; /* Error code already set. */
    }

    /* TODO(ekr@rtfm.com): Record key log */
    return SECSuccess;
}

static SECStatus
tls13_VerifyFinished(sslSocket *ss, SSLHandshakeType message,
                     PK11SymKey *secret,
                     PRUint8 *b, PRUint32 length,
                     const SSL3Hashes *hashes)
{
    SECStatus rv;
    PRUint8 finishedBuf[TLS13_MAX_FINISHED_SIZE];
    unsigned int finishedLen;

    if (!hashes) {
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        return SECFailure;
    }

    rv = tls13_ComputeFinished(ss, secret, hashes, PR_FALSE,
                               finishedBuf, &finishedLen, sizeof(finishedBuf));
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        return SECFailure;
    }

    if (length != finishedLen) {
#ifndef UNSAFE_FUZZER_MODE
        FATAL_ERROR(ss, message == ssl_hs_finished ? SSL_ERROR_RX_MALFORMED_FINISHED : SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
        return SECFailure;
#endif
    }

    if (NSS_SecureMemcmp(b, finishedBuf, finishedLen) != 0) {
#ifndef UNSAFE_FUZZER_MODE
        FATAL_ERROR(ss, SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE,
                    decrypt_error);
        return SECFailure;
#endif
    }

    return SECSuccess;
}

static SECStatus
tls13_CommonHandleFinished(sslSocket *ss, PK11SymKey *key,
                           PRUint8 *b, PRUint32 length)
{
    SECStatus rv;
    SSL3Hashes hashes;

    rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_FINISHED,
                              wait_finished);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    ss->ssl3.hs.endOfFlight = PR_TRUE;

    rv = tls13_ComputeHandshakeHashes(ss, &hashes);
    if (rv != SECSuccess) {
        LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    rv = ssl_HashHandshakeMessage(ss, ssl_hs_finished, b, length);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    return tls13_VerifyFinished(ss, ssl_hs_finished,
                                key, b, length, &hashes);
}

static SECStatus
tls13_ClientHandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
    SECStatus rv;

    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    SSL_TRC(3, ("%d: TLS13[%d]: client handle finished handshake",
                SSL_GETPID(), ss->fd));

    rv = tls13_CommonHandleFinished(ss, ss->ssl3.hs.serverHsTrafficSecret,
                                    b, length);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    return tls13_SendClientSecondRound(ss);
}

static SECStatus
tls13_ServerHandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
    SECStatus rv;

    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    SSL_TRC(3, ("%d: TLS13[%d]: server handle finished handshake",
                SSL_GETPID(), ss->fd));

    rv = tls13_CommonHandleFinished(ss, ss->ssl3.hs.clientHsTrafficSecret,
                                    b, length);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    if (!tls13_ShouldRequestClientAuth(ss) &&
        (ss->ssl3.hs.zeroRttState != ssl_0rtt_done)) {
        dtls_ReceivedFirstMessageInFlight(ss);
    }

    rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData,
                             CipherSpecRead, PR_FALSE);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        return SECFailure;
    }

    if (IS_DTLS(ss)) {
        ssl_CipherSpecReleaseByEpoch(ss, CipherSpecRead, TrafficKeyClearText);
        /* We need to keep the handshake cipher spec so we can
         * read re-transmitted client Finished. */
        rv = dtls_StartTimer(ss, ss->ssl3.hs.hdTimer,
                             DTLS_RETRANSMIT_FINISHED_MS,
                             dtls13_HolddownTimerCb);
        if (rv != SECSuccess) {
            return SECFailure;
        }
    }

    rv = tls13_ComputeFinalSecrets(ss);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    ssl_GetXmitBufLock(ss);
    if (ss->opt.enableSessionTickets) {
        rv = tls13_SendNewSessionTicket(ss, NULL, 0);
        if (rv != SECSuccess) {
            goto loser;
        }
        rv = ssl3_FlushHandshake(ss, 0);
        if (rv != SECSuccess) {
            goto loser;
        }
    }
    ssl_ReleaseXmitBufLock(ss);

    return tls13_FinishHandshake(ss);

loser:
    ssl_ReleaseXmitBufLock(ss);
    return SECFailure;
}

static SECStatus
tls13_FinishHandshake(sslSocket *ss)
{
    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
    PORT_Assert(ss->ssl3.hs.restartTarget == NULL);

    /* The first handshake is now completed. */
    ss->handshake = NULL;

    /* Don't need this. */
    PK11_FreeSymKey(ss->ssl3.hs.clientHsTrafficSecret);
    ss->ssl3.hs.clientHsTrafficSecret = NULL;
    PK11_FreeSymKey(ss->ssl3.hs.serverHsTrafficSecret);
    ss->ssl3.hs.serverHsTrafficSecret = NULL;

    TLS13_SET_HS_STATE(ss, idle_handshake);

    ssl_FinishHandshake(ss);

    return SECSuccess;
}

/* Do the parts of sending the client's second round that require
 * the XmitBuf lock. */
static SECStatus
tls13_SendClientSecondFlight(sslSocket *ss, PRBool sendClientCert,
                             SSL3AlertDescription *sendAlert)
{
    SECStatus rv;

    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));

    *sendAlert = internal_error;

    if (ss->ssl3.sendEmptyCert) {
        ss->ssl3.sendEmptyCert = PR_FALSE;
        rv = ssl3_SendEmptyCertificate(ss);
        /* Don't send verify */
        if (rv != SECSuccess) {
            return SECFailure; /* error code is set. */
        }
    } else if (sendClientCert) {
        rv = tls13_SendCertificate(ss);
        if (rv != SECSuccess) {
            return SECFailure; /* error code is set. */
        }
    }
    if (ss->ssl3.hs.clientCertRequested) {
        SECITEM_FreeItem(&ss->xtnData.certReqContext, PR_FALSE);
        if (ss->xtnData.certReqAuthorities.arena) {
            PORT_FreeArena(ss->xtnData.certReqAuthorities.arena, PR_FALSE);
            ss->xtnData.certReqAuthorities.arena = NULL;
        }
        PORT_Memset(&ss->xtnData.certReqAuthorities, 0,
                    sizeof(ss->xtnData.certReqAuthorities));
        ss->ssl3.hs.clientCertRequested = PR_FALSE;
    }

    if (sendClientCert) {
        rv = tls13_SendCertificateVerify(ss, ss->ssl3.clientPrivateKey);
        SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
        ss->ssl3.clientPrivateKey = NULL;
        if (rv != SECSuccess) {
            return SECFailure; /* err is set. */
        }
    }

    rv = tls13_SendFinished(ss, ss->ssl3.hs.clientHsTrafficSecret);
    if (rv != SECSuccess) {
        return SECFailure; /* err code was set. */
    }
    rv = ssl3_FlushHandshake(ss, 0);
    if (rv != SECSuccess) {
        /* No point in sending an alert here because we're not going to
         * be able to send it if we couldn't flush the handshake. */
        *sendAlert = no_alert;
        return SECFailure;
    }

    return SECSuccess;
}

static SECStatus
tls13_SendClientSecondRound(sslSocket *ss)
{
    SECStatus rv;
    PRBool sendClientCert;
    SSL3AlertDescription sendAlert = no_alert;

    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));

    sendClientCert = !ss->ssl3.sendEmptyCert &&
                     ss->ssl3.clientCertChain != NULL &&
                     ss->ssl3.clientPrivateKey != NULL;

    /* Defer client authentication sending if we are still waiting for server
     * authentication.  This avoids unnecessary disclosure of client credentials
     * to an unauthenticated server.
     */
    if (ss->ssl3.hs.restartTarget) {
        PR_NOT_REACHED("unexpected ss->ssl3.hs.restartTarget");
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    if (ss->ssl3.hs.authCertificatePending) {
        SSL_TRC(3, ("%d: TLS13[%d]: deferring ssl3_SendClientSecondRound because"
                    " certificate authentication is still pending.",
                    SSL_GETPID(), ss->fd));
        ss->ssl3.hs.restartTarget = tls13_SendClientSecondRound;
        return SECWouldBlock;
    }

    rv = tls13_ComputeApplicationSecrets(ss);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        return SECFailure;
    }

    if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
        ssl_GetXmitBufLock(ss); /*******************************/
        rv = tls13_SendEndOfEarlyData(ss);
        ssl_ReleaseXmitBufLock(ss); /*******************************/
        if (rv != SECSuccess) {
            return SECFailure; /* Error code already set. */
        }
    } else if (ss->opt.enableTls13CompatMode && !IS_DTLS(ss) &&
               ss->ssl3.hs.zeroRttState == ssl_0rtt_none &&
               !ss->ssl3.hs.helloRetry) {
        ssl_GetXmitBufLock(ss); /*******************************/
        rv = ssl3_SendChangeCipherSpecsInt(ss);
        ssl_ReleaseXmitBufLock(ss); /*******************************/
        if (rv != SECSuccess) {
            return rv;
        }
    }

    rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake,
                             CipherSpecWrite, PR_FALSE);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SSL_ERROR_INIT_CIPHER_SUITE_FAILURE, internal_error);
        return SECFailure;
    }

    rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData,
                             CipherSpecRead, PR_FALSE);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        return SECFailure;
    }

    ssl_GetXmitBufLock(ss); /*******************************/
    rv = tls13_SendClientSecondFlight(ss, sendClientCert, &sendAlert);
    ssl_ReleaseXmitBufLock(ss); /*******************************/
    if (rv != SECSuccess) {
        if (sendAlert != no_alert) {
            FATAL_ERROR(ss, PORT_GetError(), sendAlert);
        } else {
            LOG_ERROR(ss, PORT_GetError());
        }
        return SECFailure;
    }
    rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData,
                             CipherSpecWrite, PR_FALSE);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    rv = tls13_ComputeFinalSecrets(ss);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    /* The handshake is now finished */
    return tls13_FinishHandshake(ss);
}

/*
 *  enum { (65535) } TicketExtensionType;
 *
 *  struct {
 *      TicketExtensionType extension_type;
 *      opaque extension_data<0..2^16-1>;
 *  } TicketExtension;
 *
 *   struct {
 *       uint32 ticket_lifetime;
 *       uint32 ticket_age_add;
 *       opaque ticket_nonce<1..255>;
 *       opaque ticket<1..2^16-1>;
 *       TicketExtension extensions<0..2^16-2>;
 *   } NewSessionTicket;
 */

static SECStatus
tls13_SendNewSessionTicket(sslSocket *ss, const PRUint8 *appToken,
                           unsigned int appTokenLen)
{
    PRUint16 message_length;
    PK11SymKey *secret;
    SECItem ticket_data = { 0, NULL, 0 };
    SECStatus rv;
    NewSessionTicket ticket = { 0 };
    PRUint32 max_early_data_size_len = 0;
    PRUint8 ticketNonce[sizeof(ss->ssl3.hs.ticketNonce)];
    sslBuffer ticketNonceBuf = SSL_BUFFER(ticketNonce);

    SSL_TRC(3, ("%d: TLS13[%d]: send new session ticket message %d",
                SSL_GETPID(), ss->fd, ss->ssl3.hs.ticketNonce));

    ticket.flags = 0;
    if (ss->opt.enable0RttData) {
        ticket.flags |= ticket_allow_early_data;
        max_early_data_size_len = 8; /* type + len + value. */
    }
    ticket.ticket_lifetime_hint = ssl_ticket_lifetime;

    /* The ticket age obfuscator. */
    rv = PK11_GenerateRandom((PRUint8 *)&ticket.ticket_age_add,
                             sizeof(ticket.ticket_age_add));
    if (rv != SECSuccess)
        goto loser;

    rv = sslBuffer_AppendNumber(&ticketNonceBuf, ss->ssl3.hs.ticketNonce,
                                sizeof(ticketNonce));
    if (rv != SECSuccess) {
        goto loser;
    }
    ++ss->ssl3.hs.ticketNonce;
    rv = tls13_HkdfExpandLabel(ss->ssl3.hs.resumptionMasterSecret,
                               tls13_GetHash(ss),
                               ticketNonce, sizeof(ticketNonce),
                               kHkdfLabelResumption,
                               strlen(kHkdfLabelResumption),
                               tls13_GetHkdfMechanism(ss),
                               tls13_GetHashSize(ss), &secret);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = ssl3_EncodeSessionTicket(ss, &ticket, appToken, appTokenLen,
                                  secret, &ticket_data);
    PK11_FreeSymKey(secret);
    if (rv != SECSuccess)
        goto loser;

    message_length =
        4 +                           /* lifetime */
        4 +                           /* ticket_age_add */
        1 + sizeof(ticketNonce) +     /* ticket_nonce */
        2 + max_early_data_size_len + /* max_early_data_size_len */
        2 +                           /* ticket length */
        ticket_data.len;

    rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_new_session_ticket,
                                    message_length);
    if (rv != SECSuccess)
        goto loser;

    /* This is a fixed value. */
    rv = ssl3_AppendHandshakeNumber(ss, ssl_ticket_lifetime, 4);
    if (rv != SECSuccess)
        goto loser;

    rv = ssl3_AppendHandshakeNumber(ss, ticket.ticket_age_add, 4);
    if (rv != SECSuccess)
        goto loser;

    /* The ticket nonce. */
    rv = ssl3_AppendHandshakeVariable(ss, ticketNonce, sizeof(ticketNonce), 1);
    if (rv != SECSuccess)
        goto loser;

    /* Encode the ticket. */
    rv = ssl3_AppendHandshakeVariable(
        ss, ticket_data.data, ticket_data.len, 2);
    if (rv != SECSuccess)
        goto loser;

    /* Extensions. */
    rv = ssl3_AppendHandshakeNumber(ss, max_early_data_size_len, 2);
    if (rv != SECSuccess)
        goto loser;

    if (max_early_data_size_len) {
        rv = ssl3_AppendHandshakeNumber(
            ss, ssl_tls13_early_data_xtn, 2);
        if (rv != SECSuccess)
            goto loser;

        /* Length */
        rv = ssl3_AppendHandshakeNumber(ss, 4, 2);
        if (rv != SECSuccess)
            goto loser;

        rv = ssl3_AppendHandshakeNumber(ss, ss->opt.maxEarlyDataSize, 4);
        if (rv != SECSuccess)
            goto loser;
    }

    SECITEM_FreeItem(&ticket_data, PR_FALSE);
    return SECSuccess;

loser:
    if (ticket_data.data) {
        SECITEM_FreeItem(&ticket_data, PR_FALSE);
    }
    return SECFailure;
}

SECStatus
SSLExp_SendSessionTicket(PRFileDesc *fd, const PRUint8 *token,
                         unsigned int tokenLen)
{
    sslSocket *ss;
    SECStatus rv;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        return SECFailure;
    }

    if (IS_DTLS(ss)) {
        PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION);
        return SECFailure;
    }

    if (!ss->sec.isServer || !ss->firstHsDone ||
        ss->version < SSL_LIBRARY_VERSION_TLS_1_3 ||
        tokenLen > 0xffff) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    ssl_GetSSL3HandshakeLock(ss);
    ssl_GetXmitBufLock(ss);
    rv = tls13_SendNewSessionTicket(ss, token, tokenLen);
    if (rv == SECSuccess) {
        rv = ssl3_FlushHandshake(ss, 0);
    }
    ssl_ReleaseXmitBufLock(ss);
    ssl_ReleaseSSL3HandshakeLock(ss);

    return rv;
}

static SECStatus
tls13_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
    SECStatus rv;
    PRUint32 utmp;
    NewSessionTicket ticket = { 0 };
    SECItem data;
    SECItem ticket_nonce;
    SECItem ticket_data;

    SSL_TRC(3, ("%d: TLS13[%d]: handle new session ticket message",
                SSL_GETPID(), ss->fd));

    rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET,
                              idle_handshake);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    if (!ss->firstHsDone || ss->sec.isServer) {
        FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET,
                    unexpected_message);
        return SECFailure;
    }

    ticket.received_timestamp = ssl_TimeUsec();
    rv = ssl3_ConsumeHandshakeNumber(ss, &ticket.ticket_lifetime_hint, 4, &b,
                                     &length);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET,
                    decode_error);
        return SECFailure;
    }
    ticket.ticket.type = siBuffer;

    rv = ssl3_ConsumeHandshake(ss, &utmp, sizeof(utmp),
                               &b, &length);
    if (rv != SECSuccess) {
        PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
        return SECFailure;
    }
    ticket.ticket_age_add = PR_ntohl(utmp);

    /* The nonce. */
    rv = ssl3_ConsumeHandshakeVariable(ss, &ticket_nonce, 1, &b, &length);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET,
                    decode_error);
        return SECFailure;
    }

    /* Get the ticket value. */
    rv = ssl3_ConsumeHandshakeVariable(ss, &ticket_data, 2, &b, &length);
    if (rv != SECSuccess || !ticket_data.len) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET,
                    decode_error);
        return SECFailure;
    }

    /* Parse extensions. */
    rv = ssl3_ConsumeHandshakeVariable(ss, &data, 2, &b, &length);
    if (rv != SECSuccess || length) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET,
                    decode_error);
        return SECFailure;
    }

    rv = ssl3_HandleExtensions(ss, &data.data,
                               &data.len, ssl_hs_new_session_ticket);
    if (rv != SECSuccess) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET,
                    decode_error);
        return SECFailure;
    }
    if (ss->xtnData.max_early_data_size) {
        ticket.flags |= ticket_allow_early_data;
        ticket.max_early_data_size = ss->xtnData.max_early_data_size;
    }

    if (!ss->opt.noCache) {
        PK11SymKey *secret;

        PORT_Assert(ss->sec.ci.sid);
        rv = SECITEM_CopyItem(NULL, &ticket.ticket, &ticket_data);
        if (rv != SECSuccess) {
            FATAL_ERROR(ss, SEC_ERROR_NO_MEMORY, internal_error);
            return SECFailure;
        }
        PRINT_BUF(50, (ss, "Caching session ticket",
                       ticket.ticket.data,
                       ticket.ticket.len));

        /* Replace a previous session ticket when
         * we receive a second NewSessionTicket message. */
        if (ss->sec.ci.sid->cached == in_client_cache ||
            ss->sec.ci.sid->cached == in_external_cache) {
            /* Create a new session ID. */
            sslSessionID *sid = ssl3_NewSessionID(ss, PR_FALSE);
            if (!sid) {
                return SECFailure;
            }

            /* Copy over the peerCert. */
            PORT_Assert(ss->sec.ci.sid->peerCert);
            sid->peerCert = CERT_DupCertificate(ss->sec.ci.sid->peerCert);
            if (!sid->peerCert) {
                ssl_FreeSID(sid);
                return SECFailure;
            }

            /* Destroy the old SID. */
            ssl_UncacheSessionID(ss);
            ssl_FreeSID(ss->sec.ci.sid);
            ss->sec.ci.sid = sid;
        }

        ssl3_SetSIDSessionTicket(ss->sec.ci.sid, &ticket);
        PORT_Assert(!ticket.ticket.data);

        rv = tls13_HkdfExpandLabel(ss->ssl3.hs.resumptionMasterSecret,
                                   tls13_GetHash(ss),
                                   ticket_nonce.data, ticket_nonce.len,
                                   kHkdfLabelResumption,
                                   strlen(kHkdfLabelResumption),
                                   tls13_GetHkdfMechanism(ss),
                                   tls13_GetHashSize(ss), &secret);
        if (rv != SECSuccess) {
            return SECFailure;
        }

        rv = ssl3_FillInCachedSID(ss, ss->sec.ci.sid, secret);
        PK11_FreeSymKey(secret);
        if (rv != SECSuccess) {
            return SECFailure;
        }

        /* Cache the session. */
        ssl_CacheSessionID(ss);
    }

    return SECSuccess;
}

#define _M(a) (1 << PR_MIN(a, 31))
#define _M1(a) (_M(ssl_hs_##a))
#define _M2(a, b) (_M1(a) | _M1(b))
#define _M3(a, b, c) (_M1(a) | _M2(b, c))

static const struct {
    PRUint16 ex_value;
    PRUint32 messages;
} KnownExtensions[] = {
    { ssl_server_name_xtn, _M2(client_hello, encrypted_extensions) },
    { ssl_supported_groups_xtn, _M2(client_hello, encrypted_extensions) },
    { ssl_signature_algorithms_xtn, _M2(client_hello, certificate_request) },
    { ssl_signature_algorithms_cert_xtn, _M2(client_hello,
                                             certificate_request) },
    { ssl_use_srtp_xtn, _M2(client_hello, encrypted_extensions) },
    { ssl_app_layer_protocol_xtn, _M2(client_hello, encrypted_extensions) },
    { ssl_padding_xtn, _M1(client_hello) },
    { ssl_tls13_key_share_xtn, _M3(client_hello, server_hello,
                                   hello_retry_request) },
    { ssl_tls13_pre_shared_key_xtn, _M2(client_hello, server_hello) },
    { ssl_tls13_psk_key_exchange_modes_xtn, _M1(client_hello) },
    { ssl_tls13_early_data_xtn, _M3(client_hello, encrypted_extensions,
                                    new_session_ticket) },
    { ssl_signed_cert_timestamp_xtn, _M3(client_hello, certificate_request,
                                         certificate) },
    { ssl_cert_status_xtn, _M3(client_hello, certificate_request,
                               certificate) },
    { ssl_tls13_cookie_xtn, _M2(client_hello, hello_retry_request) },
    { ssl_tls13_certificate_authorities_xtn, _M1(certificate_request) },
    { ssl_tls13_supported_versions_xtn, _M3(client_hello, server_hello,
                                            hello_retry_request) },
    { ssl_record_size_limit_xtn, _M2(client_hello, encrypted_extensions) },
    { ssl_tls13_encrypted_sni_xtn, _M2(client_hello, encrypted_extensions) }
};

tls13ExtensionStatus
tls13_ExtensionStatus(PRUint16 extension, SSLHandshakeType message)
{
    unsigned int i;

    PORT_Assert((message == ssl_hs_client_hello) ||
                (message == ssl_hs_server_hello) ||
                (message == ssl_hs_hello_retry_request) ||
                (message == ssl_hs_encrypted_extensions) ||
                (message == ssl_hs_new_session_ticket) ||
                (message == ssl_hs_certificate) ||
                (message == ssl_hs_certificate_request));

    for (i = 0; i < PR_ARRAY_SIZE(KnownExtensions); i++) {
        /* Hacky check for message numbers > 30. */
        PORT_Assert(!(KnownExtensions[i].messages & (1U << 31)));
        if (KnownExtensions[i].ex_value == extension) {
            break;
        }
    }
    if (i >= PR_ARRAY_SIZE(KnownExtensions)) {
        return tls13_extension_unknown;
    }

    /* Return "disallowed" if the message mask bit isn't set. */
    if (!(_M(message) & KnownExtensions[i].messages)) {
        return tls13_extension_disallowed;
    }

    return tls13_extension_allowed;
}

#undef _M
#undef _M1
#undef _M2
#undef _M3

/* We cheat a bit on additional data because the AEAD interface
 * which doesn't have room for the record number. The AAD we
 * format is serialized record number followed by the true AD
 * (i.e., the record header) plus the serialized record number. */
static SECStatus
tls13_FormatAdditionalData(
    sslSocket *ss,
    const PRUint8 *header, unsigned int headerLen,
    DTLSEpoch epoch, sslSequenceNumber seqNum,
    PRUint8 *aad, unsigned int *aadLength, unsigned int maxLength)
{
    SECStatus rv;
    sslBuffer buf = SSL_BUFFER_FIXED(aad, maxLength);

    if (IS_DTLS(ss)) {
        rv = sslBuffer_AppendNumber(&buf, epoch, 2);
        if (rv != SECSuccess) {
            return SECFailure;
        }
    }
    rv = sslBuffer_AppendNumber(&buf, seqNum, IS_DTLS(ss) ? 6 : 8);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    rv = sslBuffer_Append(&buf, header, headerLen);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    *aadLength = buf.len;

    return SECSuccess;
}

PRInt32
tls13_LimitEarlyData(sslSocket *ss, SSLContentType type, PRInt32 toSend)
{
    PRInt32 reduced;

    PORT_Assert(type == ssl_ct_application_data);
    PORT_Assert(ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3);
    PORT_Assert(!ss->firstHsDone);
    if (ss->ssl3.cwSpec->epoch != TrafficKeyEarlyApplicationData) {
        return toSend;
    }

    if (IS_DTLS(ss) && toSend > ss->ssl3.cwSpec->earlyDataRemaining) {
        /* Don't split application data records in DTLS. */
        return 0;
    }

    reduced = PR_MIN(toSend, ss->ssl3.cwSpec->earlyDataRemaining);
    ss->ssl3.cwSpec->earlyDataRemaining -= reduced;
    return reduced;
}

SECStatus
tls13_ProtectRecord(sslSocket *ss,
                    ssl3CipherSpec *cwSpec,
                    SSLContentType type,
                    const PRUint8 *pIn,
                    PRUint32 contentLen,
                    sslBuffer *wrBuf)
{
    const ssl3BulkCipherDef *cipher_def = cwSpec->cipherDef;
    const int tagLen = cipher_def->tag_size;
    SECStatus rv;

    PORT_Assert(cwSpec->direction == CipherSpecWrite);
    SSL_TRC(3, ("%d: TLS13[%d]: spec=%d epoch=%d (%s) protect 0x%0llx len=%u",
                SSL_GETPID(), ss->fd, cwSpec, cwSpec->epoch, cwSpec->phase,
                cwSpec->nextSeqNum, contentLen));

    if (contentLen + 1 + tagLen > SSL_BUFFER_SPACE(wrBuf)) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    /* Copy the data into the wrBuf. We're going to encrypt in-place
     * in the AEAD branch anyway */
    PORT_Memcpy(SSL_BUFFER_NEXT(wrBuf), pIn, contentLen);

    if (cipher_def->calg == ssl_calg_null) {
        /* Shortcut for plaintext */
        rv = sslBuffer_Skip(wrBuf, contentLen, NULL);
        PORT_Assert(rv == SECSuccess);
    } else {
        PRUint8 hdr[13];
        sslBuffer buf = SSL_BUFFER_FIXED(hdr, sizeof(hdr));
        PRBool needsLength;
        PRUint8 aad[21];
        unsigned int aadLen;
        int len;

        PORT_Assert(cipher_def->type == type_aead);

        /* Add the content type at the end. */
        *(SSL_BUFFER_NEXT(wrBuf) + contentLen) = type;

        /* Create the header (ugly that we have to do it twice). */
        rv = ssl_InsertRecordHeader(ss, cwSpec, ssl_ct_application_data,
                                    &buf, &needsLength);
        if (rv != SECSuccess) {
            return SECFailure;
        }
        if (needsLength) {
            rv = sslBuffer_AppendNumber(&buf, contentLen + 1 +
                                                  cwSpec->cipherDef->tag_size,
                                        2);
            if (rv != SECSuccess) {
                return SECFailure;
            }
        }
        rv = tls13_FormatAdditionalData(ss, SSL_BUFFER_BASE(&buf), SSL_BUFFER_LEN(&buf),
                                        cwSpec->epoch, cwSpec->nextSeqNum,
                                        aad, &aadLen, sizeof(aad));
        if (rv != SECSuccess) {
            return SECFailure;
        }
        rv = cwSpec->aead(&cwSpec->keyMaterial,
                          PR_FALSE,                /* do encrypt */
                          SSL_BUFFER_NEXT(wrBuf),  /* output  */
                          &len,                    /* out len */
                          SSL_BUFFER_SPACE(wrBuf), /* max out */
                          SSL_BUFFER_NEXT(wrBuf),  /* input */
                          contentLen + 1,          /* input len */
                          aad, aadLen);
        if (rv != SECSuccess) {
            PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
            return SECFailure;
        }
        rv = sslBuffer_Skip(wrBuf, len, NULL);
        PORT_Assert(rv == SECSuccess);
    }

    return SECSuccess;
}

/* Unprotect a TLS 1.3 record and leave the result in plaintext.
 *
 * Called by ssl3_HandleRecord. Caller must hold the spec read lock.
 * Therefore, we MUST not call SSL3_SendAlert().
 *
 * If SECFailure is returned, we:
 * 1. Set |*alert| to the alert to be sent.
 * 2. Call PORT_SetError() witn an appropriate code.
 */
SECStatus
tls13_UnprotectRecord(sslSocket *ss,
                      ssl3CipherSpec *spec,
                      SSL3Ciphertext *cText,
                      sslBuffer *plaintext,
                      SSLContentType *innerType,
                      SSL3AlertDescription *alert)
{
    const ssl3BulkCipherDef *cipher_def = spec->cipherDef;
    PRUint8 aad[21];
    unsigned int aadLen;
    SECStatus rv;

    *alert = bad_record_mac; /* Default alert for most issues. */

    PORT_Assert(spec->direction == CipherSpecRead);
    SSL_TRC(3, ("%d: TLS13[%d]: spec=%d epoch=%d (%s) unprotect 0x%0llx len=%u",
                SSL_GETPID(), ss->fd, spec, spec->epoch, spec->phase,
                cText->seqNum, cText->buf->len));

    /* Verify that the content type is right, even though we overwrite it.
     * Also allow the DTLS short header in TLS 1.3. */
    if (!(cText->hdr[0] == ssl_ct_application_data ||
          (IS_DTLS(ss) &&
           ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
           (cText->hdr[0] & 0xe0) == 0x20))) {
        SSL_TRC(3,
                ("%d: TLS13[%d]: record has invalid exterior type=%2.2x",
                 SSL_GETPID(), ss->fd, cText->hdr[0]));
        PORT_SetError(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE);
        *alert = unexpected_message;
        return SECFailure;
    }

    /* We can perform this test in variable time because the record's total
     * length and the ciphersuite are both public knowledge. */
    if (cText->buf->len < cipher_def->tag_size) {
        SSL_TRC(3,
                ("%d: TLS13[%d]: record too short to contain valid AEAD data",
                 SSL_GETPID(), ss->fd));
        PORT_SetError(SSL_ERROR_BAD_MAC_READ);
        return SECFailure;
    }

    /* Check the version number in the record. Stream only. */
    if (!IS_DTLS(ss)) {
        SSL3ProtocolVersion version =
            ((SSL3ProtocolVersion)cText->hdr[1] << 8) |
            (SSL3ProtocolVersion)cText->hdr[2];
        if (version != spec->recordVersion) {
            /* Do we need a better error here? */
            SSL_TRC(3, ("%d: TLS13[%d]: record has bogus version",
                        SSL_GETPID(), ss->fd));
            return SECFailure;
        }
    }

    /* Decrypt */
    PORT_Assert(cipher_def->type == type_aead);
    rv = tls13_FormatAdditionalData(ss, cText->hdr, cText->hdrLen,
                                    spec->epoch, cText->seqNum,
                                    aad, &aadLen, sizeof(aad));
    if (rv != SECSuccess) {
        return SECFailure;
    }
    rv = spec->aead(&spec->keyMaterial,
                    PR_TRUE,                /* do decrypt */
                    plaintext->buf,         /* out */
                    (int *)&plaintext->len, /* outlen */
                    plaintext->space,       /* maxout */
                    cText->buf->buf,        /* in */
                    cText->buf->len,        /* inlen */
                    aad, aadLen);
    if (rv != SECSuccess) {
        SSL_TRC(3,
                ("%d: TLS13[%d]: record has bogus MAC",
                 SSL_GETPID(), ss->fd));
        PORT_SetError(SSL_ERROR_BAD_MAC_READ);
        return SECFailure;
    }

    /* There is a similar test in ssl3_HandleRecord, but this test is needed to
     * account for padding.  It's safe to do this here (including the alert),
     * because it only confirms that the record exceeded the size limit, which
     * is apparent from the size of the ciphertext. */
    if (plaintext->len > spec->recordSizeLimit + 1) {
        SSL3_SendAlert(ss, alert_fatal, record_overflow);
        PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
        return SECFailure;
    }

    /* The record is right-padded with 0s, followed by the true
     * content type, so read from the right until we receive a
     * nonzero byte. */
    while (plaintext->len > 0 && !(plaintext->buf[plaintext->len - 1])) {
        --plaintext->len;
    }

    /* Bogus padding. */
    if (plaintext->len < 1) {
        SSL_TRC(3, ("%d: TLS13[%d]: empty record", SSL_GETPID(), ss->fd));
        /* It's safe to report this specifically because it happened
         * after the MAC has been verified. */
        PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
        return SECFailure;
    }

    /* Record the type. */
    *innerType = (SSLContentType)plaintext->buf[plaintext->len - 1];
    --plaintext->len;

    /* Check that we haven't received too much 0-RTT data. */
    if (spec->epoch == TrafficKeyEarlyApplicationData &&
        *innerType == ssl_ct_application_data) {
        if (plaintext->len > spec->earlyDataRemaining) {
            *alert = unexpected_message;
            PORT_SetError(SSL_ERROR_TOO_MUCH_EARLY_DATA);
            return SECFailure;
        }
        spec->earlyDataRemaining -= plaintext->len;
    }

    SSL_TRC(10,
            ("%d: TLS13[%d]: %s received record of length=%d, type=%d",
             SSL_GETPID(), ss->fd, SSL_ROLE(ss), plaintext->len, *innerType));

    return SECSuccess;
}

/* 0-RTT is only permitted if:
 *
 * 1. We are doing TLS 1.3
 * 2. This isn't a second ClientHello (in response to HelloRetryRequest)
 * 3. The 0-RTT option is set.
 * 4. We have a valid ticket.
 * 5. The server is willing to accept 0-RTT.
 * 6. We have not changed our ALPN settings to disallow the ALPN tag
 *    in the ticket.
 *
 * Called from tls13_ClientSendEarlyDataXtn().
 */
PRBool
tls13_ClientAllow0Rtt(const sslSocket *ss, const sslSessionID *sid)
{
    /* We checked that the cipher suite was still allowed back in
     * ssl3_SendClientHello. */
    if (sid->version < SSL_LIBRARY_VERSION_TLS_1_3)
        return PR_FALSE;
    if (ss->ssl3.hs.helloRetry)
        return PR_FALSE;
    if (!ss->opt.enable0RttData)
        return PR_FALSE;
    if (!ss->statelessResume)
        return PR_FALSE;
    if ((sid->u.ssl3.locked.sessionTicket.flags & ticket_allow_early_data) == 0)
        return PR_FALSE;
    return ssl_AlpnTagAllowed(ss, &sid->u.ssl3.alpnSelection);
}

SECStatus
tls13_MaybeDo0RTTHandshake(sslSocket *ss)
{
    SECStatus rv;

    /* Don't do anything if there is no early_data xtn, which means we're
     * not doing early data. */
    if (!ssl3_ExtensionAdvertised(ss, ssl_tls13_early_data_xtn)) {
        return SECSuccess;
    }

    ss->ssl3.hs.zeroRttState = ssl_0rtt_sent;
    ss->ssl3.hs.zeroRttSuite = ss->ssl3.hs.cipher_suite;

    SSL_TRC(3, ("%d: TLS13[%d]: in 0-RTT mode", SSL_GETPID(), ss->fd));

    /* Set the ALPN data as if it was negotiated. We check in the ServerHello
     * handler that the server negotiates the same value. */
    if (ss->sec.ci.sid->u.ssl3.alpnSelection.len) {
        ss->xtnData.nextProtoState = SSL_NEXT_PROTO_EARLY_VALUE;
        rv = SECITEM_CopyItem(NULL, &ss->xtnData.nextProto,
                              &ss->sec.ci.sid->u.ssl3.alpnSelection);
        if (rv != SECSuccess) {
            return SECFailure;
        }
    }

    if (ss->opt.enableTls13CompatMode && !IS_DTLS(ss)) {
        /* Pretend that this is a proper ChangeCipherSpec even though it is sent
         * before receiving the ServerHello. */
        ssl_GetSpecWriteLock(ss);
        tls13_SetSpecRecordVersion(ss, ss->ssl3.cwSpec);
        ssl_ReleaseSpecWriteLock(ss);
        ssl_GetXmitBufLock(ss);
        rv = ssl3_SendChangeCipherSpecsInt(ss);
        ssl_ReleaseXmitBufLock(ss);
        if (rv != SECSuccess) {
            return SECFailure;
        }
    }

    /* Cipher suite already set in tls13_SetupClientHello. */
    ss->ssl3.hs.preliminaryInfo = 0;

    rv = tls13_DeriveEarlySecrets(ss);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    /* Save cwSpec in case we get a HelloRetryRequest and have to send another
     * ClientHello. */
    ssl_CipherSpecAddRef(ss->ssl3.cwSpec);

    rv = tls13_SetCipherSpec(ss, TrafficKeyEarlyApplicationData,
                             CipherSpecWrite, PR_TRUE);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    return SECSuccess;
}

PRInt32
tls13_Read0RttData(sslSocket *ss, void *buf, PRInt32 len)
{
    TLS13EarlyData *msg;

    PORT_Assert(!PR_CLIST_IS_EMPTY(&ss->ssl3.hs.bufferedEarlyData));
    msg = (TLS13EarlyData *)PR_NEXT_LINK(&ss->ssl3.hs.bufferedEarlyData);

    PR_REMOVE_LINK(&msg->link);
    if (msg->data.len > len) {
        PORT_SetError(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
        return SECFailure;
    }
    len = msg->data.len;

    PORT_Memcpy(buf, msg->data.data, msg->data.len);
    SECITEM_ZfreeItem(&msg->data, PR_FALSE);
    PORT_ZFree(msg, sizeof(*msg));

    return len;
}

static SECStatus
tls13_SendEndOfEarlyData(sslSocket *ss)
{
    SECStatus rv;

    SSL_TRC(3, ("%d: TLS13[%d]: send EndOfEarlyData", SSL_GETPID(), ss->fd));
    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));

    rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_end_of_early_data, 0);
    if (rv != SECSuccess) {
        return rv; /* err set by AppendHandshake. */
    }

    ss->ssl3.hs.zeroRttState = ssl_0rtt_done;
    return SECSuccess;
}

static SECStatus
tls13_HandleEndOfEarlyData(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
    SECStatus rv;

    PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);

    rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_END_OF_EARLY_DATA,
                              wait_end_of_early_data);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    /* We shouldn't be getting any more early data, and if we do,
     * it is because of reordering and we drop it. */
    if (IS_DTLS(ss)) {
        ssl_CipherSpecReleaseByEpoch(ss, CipherSpecRead,
                                     TrafficKeyEarlyApplicationData);
        dtls_ReceivedFirstMessageInFlight(ss);
    }

    PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted);

    if (length) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_END_OF_EARLY_DATA, decode_error);
        return SECFailure;
    }

    rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake,
                             CipherSpecRead, PR_FALSE);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    ss->ssl3.hs.zeroRttState = ssl_0rtt_done;
    if (tls13_ShouldRequestClientAuth(ss)) {
        TLS13_SET_HS_STATE(ss, wait_client_cert);
    } else {
        TLS13_SET_HS_STATE(ss, wait_finished);
    }
    return SECSuccess;
}

SECStatus
tls13_HandleEarlyApplicationData(sslSocket *ss, sslBuffer *origBuf)
{
    TLS13EarlyData *ed;
    SECItem it = { siBuffer, NULL, 0 };

    PORT_Assert(ss->sec.isServer);
    PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted);
    if (ss->ssl3.hs.zeroRttState != ssl_0rtt_accepted) {
        /* Belt and suspenders. */
        FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
        return SECFailure;
    }

    PRINT_BUF(3, (NULL, "Received early application data",
                  origBuf->buf, origBuf->len));
    ed = PORT_ZNew(TLS13EarlyData);
    if (!ed) {
        FATAL_ERROR(ss, SEC_ERROR_NO_MEMORY, internal_error);
        return SECFailure;
    }
    it.data = origBuf->buf;
    it.len = origBuf->len;
    if (SECITEM_CopyItem(NULL, &ed->data, &it) != SECSuccess) {
        FATAL_ERROR(ss, SEC_ERROR_NO_MEMORY, internal_error);
        return SECFailure;
    }
    PR_APPEND_LINK(&ed->link, &ss->ssl3.hs.bufferedEarlyData);

    origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */

    return SECSuccess;
}

PRUint16
tls13_EncodeDraftVersion(SSL3ProtocolVersion version, SSLProtocolVariant variant)
{
#ifdef DTLS_1_3_DRAFT_VERSION
    if (version == SSL_LIBRARY_VERSION_TLS_1_3 &&
        variant == ssl_variant_datagram) {
        return 0x7f00 | DTLS_1_3_DRAFT_VERSION;
    }
#endif
    return (PRUint16)version;
}

SECStatus
tls13_ClientReadSupportedVersion(sslSocket *ss)
{
    PRUint32 temp;
    TLSExtension *versionExtension;
    SECItem it;
    SECStatus rv;

    /* Update the version based on the extension, as necessary. */
    versionExtension = ssl3_FindExtension(ss, ssl_tls13_supported_versions_xtn);
    if (!versionExtension) {
        return SECSuccess;
    }

    /* Struct copy so we don't damage the extension. */
    it = versionExtension->data;

    rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 2, &it.data, &it.len);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    if (it.len) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_SERVER_HELLO, illegal_parameter);
        return SECFailure;
    }

    if (temp != tls13_EncodeDraftVersion(SSL_LIBRARY_VERSION_TLS_1_3,
                                         ss->protocolVariant)) {
        /* You cannot negotiate < TLS 1.3 with supported_versions. */
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_SERVER_HELLO, illegal_parameter);
        return SECFailure;
    }

    ss->version = SSL_LIBRARY_VERSION_TLS_1_3;
    return SECSuccess;
}

/* Pick the highest version we support that is also advertised. */
SECStatus
tls13_NegotiateVersion(sslSocket *ss, const TLSExtension *supportedVersions)
{
    PRUint16 version;
    /* Make a copy so we're nondestructive. */
    SECItem data = supportedVersions->data;
    SECItem versions;
    SECStatus rv;

    rv = ssl3_ConsumeHandshakeVariable(ss, &versions, 1,
                                       &data.data, &data.len);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    if (data.len || !versions.len || (versions.len & 1)) {
        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
        return SECFailure;
    }
    for (version = ss->vrange.max; version >= ss->vrange.min; --version) {
        PRUint16 wire = tls13_EncodeDraftVersion(version, ss->protocolVariant);
        unsigned long offset;

        for (offset = 0; offset < versions.len; offset += 2) {
            PRUint16 supported =
                (versions.data[offset] << 8) | versions.data[offset + 1];
            if (supported == wire) {
                ss->version = version;
                return SECSuccess;
            }
        }
    }

    FATAL_ERROR(ss, SSL_ERROR_UNSUPPORTED_VERSION, protocol_version);
    return SECFailure;
}

/* This is TLS 1.3 or might negotiate to it. */
PRBool
tls13_MaybeTls13(sslSocket *ss)
{
    if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
        return PR_TRUE;
    }

    if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) {
        return PR_FALSE;
    }

    if (!(ss->ssl3.hs.preliminaryInfo & ssl_preinfo_version)) {
        return PR_TRUE;
    }

    return PR_FALSE;
}
