tor-browser

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

tls13hashstate.c (12377B)


      1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
      2 /*
      3 * This file is PRIVATE to SSL.
      4 *
      5 * This Source Code Form is subject to the terms of the Mozilla Public
      6 * License, v. 2.0. If a copy of the MPL was not distributed with this
      7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      8 
      9 #include "pk11func.h"
     10 #include "ssl.h"
     11 #include "sslt.h"
     12 #include "sslimpl.h"
     13 #include "selfencrypt.h"
     14 #include "tls13con.h"
     15 #include "tls13ech.h"
     16 #include "tls13err.h"
     17 #include "tls13hashstate.h"
     18 
     19 /*
     20 * The cookie is structured as a self-encrypted structure with the
     21 * inner value being.
     22 *
     23 * struct {
     24 *     uint8 indicator = 0xff;            // To disambiguate from tickets.
     25 *     uint16 cipherSuite;                // Selected cipher suite.
     26 *     uint16 keyShare;                   // Requested key share group (0=none)
     27 *     PRUint8 echConfigId;               // ECH config_id
     28 *     HpkeKdfId kdfId;                   // ECH KDF (uint16)
     29 *     HpkeAeadId aeadId;                 // ECH AEAD (uint16)
     30 *     opaque echHpkeCtx<0..65535>;       // ECH serialized HPKE context
     31 *     opaque applicationToken<0..65535>; // Application token
     32 *     opaque ch_hash[rest_of_buffer];    // H(ClientHello)
     33 * } CookieInner;
     34 *
     35 * An empty echConfigId means that ECH was not offered in the first ClientHello.
     36 * An empty echHrrPsk means that ECH was not accepted in CH1.
     37 */
     38 SECStatus
     39 tls13_MakeHrrCookie(sslSocket *ss, const sslNamedGroupDef *selectedGroup,
     40                    const PRUint8 *appToken, unsigned int appTokenLen,
     41                    PRUint8 *buf, unsigned int *len, unsigned int maxlen)
     42 {
     43    SECStatus rv;
     44    SSL3Hashes hashes;
     45    PRUint8 cookie[1024];
     46    sslBuffer cookieBuf = SSL_BUFFER(cookie);
     47    static const PRUint8 indicator = 0xff;
     48    SECItem *echHpkeCtx = NULL;
     49 
     50    /* Encode header. */
     51    rv = sslBuffer_Append(&cookieBuf, &indicator, 1);
     52    if (rv != SECSuccess) {
     53        return SECFailure;
     54    }
     55    rv = sslBuffer_AppendNumber(&cookieBuf, ss->ssl3.hs.cipher_suite, 2);
     56    if (rv != SECSuccess) {
     57        return SECFailure;
     58    }
     59    rv = sslBuffer_AppendNumber(&cookieBuf,
     60                                selectedGroup ? selectedGroup->name : 0, 2);
     61    if (rv != SECSuccess) {
     62        return SECFailure;
     63    }
     64 
     65    if (ss->xtnData.ech) {
     66        /* Record that we received ECH. See sslEchCookieData */
     67        rv = sslBuffer_AppendNumber(&cookieBuf, PR_TRUE, 1);
     68        if (rv != SECSuccess) {
     69            return SECFailure;
     70        }
     71 
     72        rv = sslBuffer_AppendNumber(&cookieBuf, ss->xtnData.ech->configId,
     73                                    1);
     74        if (rv != SECSuccess) {
     75            return SECFailure;
     76        }
     77 
     78        rv = sslBuffer_AppendNumber(&cookieBuf, ss->xtnData.ech->kdfId, 2);
     79        if (rv != SECSuccess) {
     80            return SECFailure;
     81        }
     82        rv = sslBuffer_AppendNumber(&cookieBuf, ss->xtnData.ech->aeadId, 2);
     83        if (rv != SECSuccess) {
     84            return SECFailure;
     85        }
     86        /* We need to send a ECH HRR Extension containing a signal for the client,
     87         * we must store the signal in the cookie so we can reconstruct the transcript
     88         * later. To avoid leaking whether ECH was accepted in the length of the cookie
     89         * we include the empty signal in the cookie regardless.
     90         */
     91        PR_ASSERT(SSL_BUFFER_LEN(&ss->ssl3.hs.greaseEchBuf) == TLS13_ECH_SIGNAL_LEN);
     92        rv = sslBuffer_AppendBuffer(&cookieBuf, &ss->ssl3.hs.greaseEchBuf);
     93        if (rv != SECSuccess) {
     94            return SECFailure;
     95        }
     96 
     97        /* There might be no HPKE Context, e.g. when we lack a matching ECHConfig. */
     98        if (ss->ssl3.hs.echHpkeCtx) {
     99            rv = PK11_HPKE_ExportContext(ss->ssl3.hs.echHpkeCtx, NULL, &echHpkeCtx);
    100            if (rv != SECSuccess) {
    101                return SECFailure;
    102            }
    103            rv = sslBuffer_AppendVariable(&cookieBuf, echHpkeCtx->data, echHpkeCtx->len, 2);
    104            SECITEM_ZfreeItem(echHpkeCtx, PR_TRUE);
    105        } else {
    106            /* Zero length HPKE context. */
    107            rv = sslBuffer_AppendNumber(&cookieBuf, 0, 2);
    108        }
    109        if (rv != SECSuccess) {
    110            return SECFailure;
    111        }
    112    } else {
    113        rv = sslBuffer_AppendNumber(&cookieBuf, PR_FALSE, 1);
    114        if (rv != SECSuccess) {
    115            return SECFailure;
    116        }
    117    }
    118 
    119    /* Application token. */
    120    rv = sslBuffer_AppendVariable(&cookieBuf, appToken, appTokenLen, 2);
    121    if (rv != SECSuccess) {
    122        return SECFailure;
    123    }
    124 
    125    /* Compute and encode hashes. */
    126    rv = tls13_ComputeHandshakeHashes(ss, &hashes);
    127    if (rv != SECSuccess) {
    128        return SECFailure;
    129    }
    130    rv = sslBuffer_Append(&cookieBuf, hashes.u.raw, hashes.len);
    131    if (rv != SECSuccess) {
    132        return SECFailure;
    133    }
    134 
    135    /* Encrypt right into the buffer. */
    136    rv = ssl_SelfEncryptProtect(ss, cookieBuf.buf, cookieBuf.len,
    137                                buf, len, maxlen);
    138    if (rv != SECSuccess) {
    139        return SECFailure;
    140    }
    141 
    142    return SECSuccess;
    143 }
    144 
    145 /* Given a cookie and cookieLen, decrypt and parse, returning
    146 * any values that were requested via the "previous_" params. If
    147 * recoverState is true, the transcript state and application
    148 * token are restored. Note that previousEchKdfId, previousEchAeadId,
    149 * previousEchConfigId, and previousEchHpkeCtx are not modified if ECH was not
    150 * previously negotiated (i.e., previousEchOffered is PR_FALSE). */
    151 SECStatus
    152 tls13_HandleHrrCookie(sslSocket *ss,
    153                      unsigned char *cookie, unsigned int cookieLen,
    154                      ssl3CipherSuite *previousCipherSuite,
    155                      const sslNamedGroupDef **previousGroup,
    156                      PRBool *previousOfferedEch,
    157                      sslEchCookieData *echData,
    158                      PRBool recoverState)
    159 {
    160    SECStatus rv;
    161    unsigned char plaintext[1024];
    162    unsigned int plaintextLen = 0;
    163    sslBuffer messageBuf = SSL_BUFFER_EMPTY;
    164    sslReadBuffer echHpkeBuf = { 0 };
    165    PRBool receivedEch;
    166    PRUint64 sentinel;
    167    PRUint64 cipherSuite;
    168    sslEchCookieData parsedEchData = { 0 };
    169    sslReadBuffer greaseReadBuf = { 0 };
    170    PRUint64 group;
    171    PRUint64 tmp64;
    172    const sslNamedGroupDef *selectedGroup;
    173    PRUint64 appTokenLen;
    174 
    175    rv = ssl_SelfEncryptUnprotect(ss, cookie, cookieLen,
    176                                  plaintext, &plaintextLen, sizeof(plaintext));
    177    if (rv != SECSuccess) {
    178        SSL_TRC(100, ("Error decrypting cookie."));
    179        return SECFailure;
    180    }
    181 
    182    sslReader reader = SSL_READER(plaintext, plaintextLen);
    183 
    184    /* Should start with the sentinel value. */
    185    rv = sslRead_ReadNumber(&reader, 1, &sentinel);
    186    if ((rv != SECSuccess) || (sentinel != TLS13_COOKIE_SENTINEL)) {
    187        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
    188        return SECFailure;
    189    }
    190    /* The cipher suite should be the same or there are some shenanigans. */
    191    rv = sslRead_ReadNumber(&reader, 2, &cipherSuite);
    192    if (rv != SECSuccess) {
    193        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
    194        return SECFailure;
    195    }
    196 
    197    /* The named group, if any. */
    198    rv = sslRead_ReadNumber(&reader, 2, &group);
    199    if (rv != SECSuccess) {
    200        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
    201        return SECFailure;
    202    }
    203    selectedGroup = ssl_LookupNamedGroup(group);
    204 
    205    /* Was ECH received. */
    206    rv = sslRead_ReadNumber(&reader, 1, &tmp64);
    207    if (rv != SECSuccess) {
    208        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
    209        return SECFailure;
    210    }
    211    receivedEch = tmp64 == PR_TRUE;
    212    *previousOfferedEch = receivedEch;
    213    if (receivedEch) {
    214        /* ECH config ID */
    215        rv = sslRead_ReadNumber(&reader, 1, &tmp64);
    216        if (rv != SECSuccess) {
    217            FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
    218            return SECFailure;
    219        }
    220        parsedEchData.configId = (PRUint8)tmp64;
    221 
    222        /* ECH Ciphersuite */
    223        rv = sslRead_ReadNumber(&reader, 2, &tmp64);
    224        if (rv != SECSuccess) {
    225            FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
    226            return SECFailure;
    227        }
    228        parsedEchData.kdfId = (HpkeKdfId)tmp64;
    229 
    230        rv = sslRead_ReadNumber(&reader, 2, &tmp64);
    231        if (rv != SECSuccess) {
    232            FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
    233            return SECFailure;
    234        }
    235        parsedEchData.aeadId = (HpkeAeadId)tmp64;
    236 
    237        /* ECH accept_confirmation signal. */
    238        rv = sslRead_Read(&reader, TLS13_ECH_SIGNAL_LEN, &greaseReadBuf);
    239        if (rv != SECSuccess) {
    240            FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
    241            return SECFailure;
    242        }
    243        PORT_Memcpy(parsedEchData.signal, greaseReadBuf.buf, TLS13_ECH_SIGNAL_LEN);
    244 
    245        /* ECH HPKE context may be empty. */
    246        rv = sslRead_ReadVariable(&reader, 2, &echHpkeBuf);
    247        if (rv != SECSuccess) {
    248            FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
    249            return SECFailure;
    250        }
    251        if (echData && echHpkeBuf.len) {
    252            const SECItem hpkeItem = { siBuffer, CONST_CAST(unsigned char, echHpkeBuf.buf),
    253                                       echHpkeBuf.len };
    254            parsedEchData.hpkeCtx = PK11_HPKE_ImportContext(&hpkeItem, NULL);
    255            if (!parsedEchData.hpkeCtx) {
    256                FATAL_ERROR(ss, PORT_GetError(), illegal_parameter);
    257                return SECFailure;
    258            }
    259        }
    260    }
    261 
    262    /* Application token. */
    263    rv = sslRead_ReadNumber(&reader, 2, &appTokenLen);
    264    if (rv != SECSuccess) {
    265        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
    266        return SECFailure;
    267    }
    268    sslReadBuffer appTokenReader = { 0 };
    269    rv = sslRead_Read(&reader, appTokenLen, &appTokenReader);
    270    if (rv != SECSuccess) {
    271        FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
    272        return SECFailure;
    273    }
    274    PORT_Assert(appTokenReader.len == appTokenLen);
    275 
    276    if (recoverState) {
    277        PORT_Assert(ss->xtnData.applicationToken.len == 0);
    278        if (SECITEM_AllocItem(NULL, &ss->xtnData.applicationToken,
    279                              appTokenLen) == NULL) {
    280            FATAL_ERROR(ss, PORT_GetError(), internal_error);
    281            return SECFailure;
    282        }
    283        PORT_Memcpy(ss->xtnData.applicationToken.data, appTokenReader.buf, appTokenLen);
    284        ss->xtnData.applicationToken.len = appTokenLen;
    285 
    286        /* The remainder is the hash. */
    287        unsigned int hashLen = SSL_READER_REMAINING(&reader);
    288        if (hashLen != tls13_GetHashSize(ss)) {
    289            FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter);
    290            return SECFailure;
    291        }
    292 
    293        /* Now reinject the message. */
    294        SSL_ASSERT_HASHES_EMPTY(ss);
    295        rv = ssl_HashHandshakeMessageInt(ss, ssl_hs_message_hash, 0,
    296                                         SSL_READER_CURRENT(&reader), hashLen,
    297                                         ssl3_UpdateHandshakeHashes);
    298        if (rv != SECSuccess) {
    299            return SECFailure;
    300        }
    301 
    302        /* And finally reinject the HRR. */
    303        rv = tls13_ConstructHelloRetryRequest(ss, cipherSuite,
    304                                              selectedGroup,
    305                                              cookie, cookieLen,
    306                                              parsedEchData.signal,
    307                                              &messageBuf);
    308        if (rv != SECSuccess) {
    309            return SECFailure;
    310        }
    311 
    312        rv = ssl_HashHandshakeMessageInt(ss, ssl_hs_server_hello, 0,
    313                                         SSL_BUFFER_BASE(&messageBuf),
    314                                         SSL_BUFFER_LEN(&messageBuf),
    315                                         ssl3_UpdateHandshakeHashes);
    316        sslBuffer_Clear(&messageBuf);
    317        if (rv != SECSuccess) {
    318            return SECFailure;
    319        }
    320    }
    321 
    322    if (previousCipherSuite) {
    323        *previousCipherSuite = cipherSuite;
    324    }
    325    if (previousGroup) {
    326        *previousGroup = selectedGroup;
    327    }
    328    if (echData) {
    329        PORT_Memcpy(echData, &parsedEchData, sizeof(parsedEchData));
    330    }
    331    return SECSuccess;
    332 }