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 }