Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
sPymbed
Date:
Wed Nov 20 13:27:48 2019 +0000
Revision:
17:ff9d1e86ad5f
Parent:
15:117db924cf7c
removed: wolfcrypt

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sPymbed 17:ff9d1e86ad5f 1 /* tls13.c
sPymbed 17:ff9d1e86ad5f 2 *
sPymbed 17:ff9d1e86ad5f 3 * Copyright (C) 2006-2017 wolfSSL Inc.
sPymbed 17:ff9d1e86ad5f 4 *
sPymbed 17:ff9d1e86ad5f 5 * This file is part of wolfSSL.
sPymbed 17:ff9d1e86ad5f 6 *
sPymbed 17:ff9d1e86ad5f 7 * wolfSSL is free software; you can redistribute it and/or modify
sPymbed 17:ff9d1e86ad5f 8 * it under the terms of the GNU General Public License as published by
sPymbed 17:ff9d1e86ad5f 9 * the Free Software Foundation; either version 2 of the License, or
sPymbed 17:ff9d1e86ad5f 10 * (at your option) any later version.
sPymbed 17:ff9d1e86ad5f 11 *
sPymbed 17:ff9d1e86ad5f 12 * wolfSSL is distributed in the hope that it will be useful,
sPymbed 17:ff9d1e86ad5f 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
sPymbed 17:ff9d1e86ad5f 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
sPymbed 17:ff9d1e86ad5f 15 * GNU General Public License for more details.
sPymbed 17:ff9d1e86ad5f 16 *
sPymbed 17:ff9d1e86ad5f 17 * You should have received a copy of the GNU General Public License
sPymbed 17:ff9d1e86ad5f 18 * along with this program; if not, write to the Free Software
sPymbed 17:ff9d1e86ad5f 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
sPymbed 17:ff9d1e86ad5f 20 */
sPymbed 17:ff9d1e86ad5f 21
sPymbed 17:ff9d1e86ad5f 22
sPymbed 17:ff9d1e86ad5f 23 /*
sPymbed 17:ff9d1e86ad5f 24 * BUILD_GCM
sPymbed 17:ff9d1e86ad5f 25 * Enables AES-GCM ciphersuites.
sPymbed 17:ff9d1e86ad5f 26 * HAVE_AESCCM
sPymbed 17:ff9d1e86ad5f 27 * Enables AES-CCM ciphersuites.
sPymbed 17:ff9d1e86ad5f 28 * HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 29 * Enables session tickets - required for TLS 1.3 resumption.
sPymbed 17:ff9d1e86ad5f 30 * NO_PSK
sPymbed 17:ff9d1e86ad5f 31 * Do not enable Pre-Shared Keys.
sPymbed 17:ff9d1e86ad5f 32 * TLS13_SUPPORTS_EXPORTERS
sPymbed 17:ff9d1e86ad5f 33 * Gaurd to compile out any code for exporter keys.
sPymbed 17:ff9d1e86ad5f 34 * Feature not supported yet.
sPymbed 17:ff9d1e86ad5f 35 * WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 36 * Enables the use of asynchornous cryptographic operations.
sPymbed 17:ff9d1e86ad5f 37 * This is available for ciphers and certificates.
sPymbed 17:ff9d1e86ad5f 38 * HAVE_CHACHA && HAVE_POLY1305
sPymbed 17:ff9d1e86ad5f 39 * Enables use of CHACHA20-POLY1305 ciphersuites.
sPymbed 17:ff9d1e86ad5f 40 * WOLFSSL_DEBUG_TLS
sPymbed 17:ff9d1e86ad5f 41 * Writes out details of TLS 1.3 protocol including hanshake message buffers
sPymbed 17:ff9d1e86ad5f 42 * and key generation input and output.
sPymbed 17:ff9d1e86ad5f 43 * WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 44 * Allow 0-RTT Handshake using Early Data extensions and handshake message
sPymbed 17:ff9d1e86ad5f 45 * WOLFSSL_NO_SERVER_GROUPS_EXT
sPymbed 17:ff9d1e86ad5f 46 * Do not send the server's groups in an extension when the server's top
sPymbed 17:ff9d1e86ad5f 47 * preference is not in client's list.
sPymbed 17:ff9d1e86ad5f 48 * WOLFSSL_POST_HANDSHAKE_AUTH
sPymbed 17:ff9d1e86ad5f 49 * Allow TLS v1.3 code to perform post-handshake authentication of the
sPymbed 17:ff9d1e86ad5f 50 * client.
sPymbed 17:ff9d1e86ad5f 51 * WOLFSSL_SEND_HRR_COOKIE
sPymbed 17:ff9d1e86ad5f 52 * Send a cookie in hello_retry_request message to enable stateless tracking
sPymbed 17:ff9d1e86ad5f 53 * of ClientHello replies.
sPymbed 17:ff9d1e86ad5f 54 * WOLFSSL_TLS13
sPymbed 17:ff9d1e86ad5f 55 * Enable TLS 1.3 protocol implementation.
sPymbed 17:ff9d1e86ad5f 56 * WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 57 * Conform with Draft 18 of the TLS v1.3 specification.
sPymbed 17:ff9d1e86ad5f 58 * WOLFSSL_TLS13_DRAFT_22
sPymbed 17:ff9d1e86ad5f 59 * Conform with Draft 22 of the TLS v1.3 specification.
sPymbed 17:ff9d1e86ad5f 60 * WOLFSSL_TLS13_DRAFT_23
sPymbed 17:ff9d1e86ad5f 61 * Conform with Draft 23 of the TLS v1.3 specification.
sPymbed 17:ff9d1e86ad5f 62 * WOLFSSL_TLS13_MIDDLEBOX_COMPAT
sPymbed 17:ff9d1e86ad5f 63 * Enable middlebox compatability in the TLS 1.3 handshake.
sPymbed 17:ff9d1e86ad5f 64 * This includes sending ChangeCipherSpec before encrypted messages and
sPymbed 17:ff9d1e86ad5f 65 * including a session id.
sPymbed 17:ff9d1e86ad5f 66 * WOLFSSL_TLS13_SHA512
sPymbed 17:ff9d1e86ad5f 67 * Allow generation of SHA-512 digests in handshake - no ciphersuite
sPymbed 17:ff9d1e86ad5f 68 * requires SHA-512 at this time.
sPymbed 17:ff9d1e86ad5f 69 * WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
sPymbed 17:ff9d1e86ad5f 70 * Allow a NewSessionTicket message to be sent by server before Client's
sPymbed 17:ff9d1e86ad5f 71 * Finished message.
sPymbed 17:ff9d1e86ad5f 72 * See TLS v1.3 specification, Section 4.6.1, Paragraph 4 (Note).
sPymbed 17:ff9d1e86ad5f 73 */
sPymbed 17:ff9d1e86ad5f 74
sPymbed 17:ff9d1e86ad5f 75 #ifdef HAVE_CONFIG_H
sPymbed 17:ff9d1e86ad5f 76 #include <config.h>
sPymbed 17:ff9d1e86ad5f 77 #endif
sPymbed 17:ff9d1e86ad5f 78
sPymbed 17:ff9d1e86ad5f 79 #include <wolfcrypt/settings.h>
sPymbed 17:ff9d1e86ad5f 80
sPymbed 17:ff9d1e86ad5f 81 #ifdef WOLFSSL_TLS13
sPymbed 17:ff9d1e86ad5f 82 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 83 #include <wolfcrypt/wc_port.h>
sPymbed 17:ff9d1e86ad5f 84 #endif
sPymbed 17:ff9d1e86ad5f 85
sPymbed 17:ff9d1e86ad5f 86 #ifndef WOLFCRYPT_ONLY
sPymbed 17:ff9d1e86ad5f 87
sPymbed 17:ff9d1e86ad5f 88 #ifdef HAVE_ERRNO_H
sPymbed 17:ff9d1e86ad5f 89 #include <errno.h>
sPymbed 17:ff9d1e86ad5f 90 #endif
sPymbed 17:ff9d1e86ad5f 91
sPymbed 17:ff9d1e86ad5f 92 #include <wolfssl/internal.h>
sPymbed 17:ff9d1e86ad5f 93 #include <wolfssl/error-ssl.h>
sPymbed 17:ff9d1e86ad5f 94 #include <wolfcrypt/asn.h>
sPymbed 17:ff9d1e86ad5f 95 #include <wolfcrypt/dh.h>
sPymbed 17:ff9d1e86ad5f 96 #ifdef NO_INLINE
sPymbed 17:ff9d1e86ad5f 97 #include <wolfcrypt/misc.h>
sPymbed 17:ff9d1e86ad5f 98 #else
sPymbed 17:ff9d1e86ad5f 99 #define WOLFSSL_MISC_INCLUDED
sPymbed 17:ff9d1e86ad5f 100 #include <wolfcrypt/src/misc.c>
sPymbed 17:ff9d1e86ad5f 101 #endif
sPymbed 17:ff9d1e86ad5f 102
sPymbed 17:ff9d1e86ad5f 103 #ifdef HAVE_NTRU
sPymbed 17:ff9d1e86ad5f 104 #include "libntruencrypt/ntru_crypto.h"
sPymbed 17:ff9d1e86ad5f 105 #endif
sPymbed 17:ff9d1e86ad5f 106
sPymbed 17:ff9d1e86ad5f 107 #if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_DEBUG) || \
sPymbed 17:ff9d1e86ad5f 108 defined(CHACHA_AEAD_TEST) || defined(WOLFSSL_SESSION_EXPORT_DEBUG)
sPymbed 17:ff9d1e86ad5f 109 #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
sPymbed 17:ff9d1e86ad5f 110 #if MQX_USE_IO_OLD
sPymbed 17:ff9d1e86ad5f 111 #include <fio.h>
sPymbed 17:ff9d1e86ad5f 112 #else
sPymbed 17:ff9d1e86ad5f 113 #include <nio.h>
sPymbed 17:ff9d1e86ad5f 114 #endif
sPymbed 17:ff9d1e86ad5f 115 #else
sPymbed 17:ff9d1e86ad5f 116 #include <stdio.h>
sPymbed 17:ff9d1e86ad5f 117 #endif
sPymbed 17:ff9d1e86ad5f 118 #endif
sPymbed 17:ff9d1e86ad5f 119
sPymbed 17:ff9d1e86ad5f 120 #ifdef __sun
sPymbed 17:ff9d1e86ad5f 121 #include <sys/filio.h>
sPymbed 17:ff9d1e86ad5f 122 #endif
sPymbed 17:ff9d1e86ad5f 123
sPymbed 17:ff9d1e86ad5f 124 #ifndef TRUE
sPymbed 17:ff9d1e86ad5f 125 #define TRUE 1
sPymbed 17:ff9d1e86ad5f 126 #endif
sPymbed 17:ff9d1e86ad5f 127 #ifndef FALSE
sPymbed 17:ff9d1e86ad5f 128 #define FALSE 0
sPymbed 17:ff9d1e86ad5f 129 #endif
sPymbed 17:ff9d1e86ad5f 130
sPymbed 17:ff9d1e86ad5f 131 #ifndef HAVE_HKDF
sPymbed 17:ff9d1e86ad5f 132 #error The build option HAVE_HKDF is required for TLS 1.3
sPymbed 17:ff9d1e86ad5f 133 #endif
sPymbed 17:ff9d1e86ad5f 134
sPymbed 17:ff9d1e86ad5f 135
sPymbed 17:ff9d1e86ad5f 136 /* Set ret to error value and jump to label.
sPymbed 17:ff9d1e86ad5f 137 *
sPymbed 17:ff9d1e86ad5f 138 * err The error value to set.
sPymbed 17:ff9d1e86ad5f 139 * eLabel The label to jump to.
sPymbed 17:ff9d1e86ad5f 140 */
sPymbed 17:ff9d1e86ad5f 141 #define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
sPymbed 17:ff9d1e86ad5f 142
sPymbed 17:ff9d1e86ad5f 143
sPymbed 17:ff9d1e86ad5f 144 /* Extract data using HMAC, salt and input.
sPymbed 17:ff9d1e86ad5f 145 * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
sPymbed 17:ff9d1e86ad5f 146 *
sPymbed 17:ff9d1e86ad5f 147 * prk The generated pseudorandom key.
sPymbed 17:ff9d1e86ad5f 148 * salt The salt.
sPymbed 17:ff9d1e86ad5f 149 * saltLen The length of the salt.
sPymbed 17:ff9d1e86ad5f 150 * ikm The input keying material.
sPymbed 17:ff9d1e86ad5f 151 * ikmLen The length of the input keying material.
sPymbed 17:ff9d1e86ad5f 152 * mac The type of digest to use.
sPymbed 17:ff9d1e86ad5f 153 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 154 */
sPymbed 17:ff9d1e86ad5f 155 static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
sPymbed 17:ff9d1e86ad5f 156 byte* ikm, int ikmLen, int mac)
sPymbed 17:ff9d1e86ad5f 157 {
sPymbed 17:ff9d1e86ad5f 158 int ret;
sPymbed 17:ff9d1e86ad5f 159 int hash = 0;
sPymbed 17:ff9d1e86ad5f 160 int len = 0;
sPymbed 17:ff9d1e86ad5f 161
sPymbed 17:ff9d1e86ad5f 162 switch (mac) {
sPymbed 17:ff9d1e86ad5f 163 #ifndef NO_SHA256
sPymbed 17:ff9d1e86ad5f 164 case sha256_mac:
sPymbed 17:ff9d1e86ad5f 165 hash = WC_SHA256;
sPymbed 17:ff9d1e86ad5f 166 len = WC_SHA256_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 167 break;
sPymbed 17:ff9d1e86ad5f 168 #endif
sPymbed 17:ff9d1e86ad5f 169
sPymbed 17:ff9d1e86ad5f 170 #ifdef WOLFSSL_SHA384
sPymbed 17:ff9d1e86ad5f 171 case sha384_mac:
sPymbed 17:ff9d1e86ad5f 172 hash = WC_SHA384;
sPymbed 17:ff9d1e86ad5f 173 len = WC_SHA384_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 174 break;
sPymbed 17:ff9d1e86ad5f 175 #endif
sPymbed 17:ff9d1e86ad5f 176
sPymbed 17:ff9d1e86ad5f 177 #ifdef WOLFSSL_TLS13_SHA512
sPymbed 17:ff9d1e86ad5f 178 case sha512_mac:
sPymbed 17:ff9d1e86ad5f 179 hash = WC_SHA512;
sPymbed 17:ff9d1e86ad5f 180 len = WC_SHA512_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 181 break;
sPymbed 17:ff9d1e86ad5f 182 #endif
sPymbed 17:ff9d1e86ad5f 183 }
sPymbed 17:ff9d1e86ad5f 184
sPymbed 17:ff9d1e86ad5f 185 /* When length is 0 then use zeroed data of digest length. */
sPymbed 17:ff9d1e86ad5f 186 if (ikmLen == 0) {
sPymbed 17:ff9d1e86ad5f 187 ikmLen = len;
sPymbed 17:ff9d1e86ad5f 188 XMEMSET(ikm, 0, len);
sPymbed 17:ff9d1e86ad5f 189 }
sPymbed 17:ff9d1e86ad5f 190
sPymbed 17:ff9d1e86ad5f 191 #ifdef WOLFSSL_DEBUG_TLS
sPymbed 17:ff9d1e86ad5f 192 WOLFSSL_MSG(" Salt");
sPymbed 17:ff9d1e86ad5f 193 WOLFSSL_BUFFER(salt, saltLen);
sPymbed 17:ff9d1e86ad5f 194 WOLFSSL_MSG(" IKM");
sPymbed 17:ff9d1e86ad5f 195 WOLFSSL_BUFFER(ikm, ikmLen);
sPymbed 17:ff9d1e86ad5f 196 #endif
sPymbed 17:ff9d1e86ad5f 197
sPymbed 17:ff9d1e86ad5f 198 ret = wc_HKDF_Extract(hash, salt, saltLen, ikm, ikmLen, prk);
sPymbed 17:ff9d1e86ad5f 199
sPymbed 17:ff9d1e86ad5f 200 #ifdef WOLFSSL_DEBUG_TLS
sPymbed 17:ff9d1e86ad5f 201 WOLFSSL_MSG(" PRK");
sPymbed 17:ff9d1e86ad5f 202 WOLFSSL_BUFFER(prk, len);
sPymbed 17:ff9d1e86ad5f 203 #endif
sPymbed 17:ff9d1e86ad5f 204
sPymbed 17:ff9d1e86ad5f 205 return ret;
sPymbed 17:ff9d1e86ad5f 206 }
sPymbed 17:ff9d1e86ad5f 207
sPymbed 17:ff9d1e86ad5f 208 /* Expand data using HMAC, salt and label and info.
sPymbed 17:ff9d1e86ad5f 209 * TLS v1.3 defines this function.
sPymbed 17:ff9d1e86ad5f 210 *
sPymbed 17:ff9d1e86ad5f 211 * okm The generated pseudorandom key - output key material.
sPymbed 17:ff9d1e86ad5f 212 * okmLen The length of generated pseudorandom key - output key material.
sPymbed 17:ff9d1e86ad5f 213 * prk The salt - pseudo-random key.
sPymbed 17:ff9d1e86ad5f 214 * prkLen The length of the salt - pseudo-random key.
sPymbed 17:ff9d1e86ad5f 215 * protocol The TLS protocol label.
sPymbed 17:ff9d1e86ad5f 216 * protocolLen The length of the TLS protocol label.
sPymbed 17:ff9d1e86ad5f 217 * info The information to expand.
sPymbed 17:ff9d1e86ad5f 218 * infoLen The length of the information.
sPymbed 17:ff9d1e86ad5f 219 * digest The type of digest to use.
sPymbed 17:ff9d1e86ad5f 220 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 221 */
sPymbed 17:ff9d1e86ad5f 222 static int HKDF_Expand_Label(byte* okm, word32 okmLen,
sPymbed 17:ff9d1e86ad5f 223 const byte* prk, word32 prkLen,
sPymbed 17:ff9d1e86ad5f 224 const byte* protocol, word32 protocolLen,
sPymbed 17:ff9d1e86ad5f 225 const byte* label, word32 labelLen,
sPymbed 17:ff9d1e86ad5f 226 const byte* info, word32 infoLen,
sPymbed 17:ff9d1e86ad5f 227 int digest)
sPymbed 17:ff9d1e86ad5f 228 {
sPymbed 17:ff9d1e86ad5f 229 int ret = 0;
sPymbed 17:ff9d1e86ad5f 230 int idx = 0;
sPymbed 17:ff9d1e86ad5f 231 byte data[MAX_HKDF_LABEL_SZ];
sPymbed 17:ff9d1e86ad5f 232
sPymbed 17:ff9d1e86ad5f 233 /* Output length. */
sPymbed 17:ff9d1e86ad5f 234 data[idx++] = (byte)(okmLen >> 8);
sPymbed 17:ff9d1e86ad5f 235 data[idx++] = (byte)okmLen;
sPymbed 17:ff9d1e86ad5f 236 /* Length of protocol | label. */
sPymbed 17:ff9d1e86ad5f 237 data[idx++] = (byte)(protocolLen + labelLen);
sPymbed 17:ff9d1e86ad5f 238 /* Protocol */
sPymbed 17:ff9d1e86ad5f 239 XMEMCPY(&data[idx], protocol, protocolLen);
sPymbed 17:ff9d1e86ad5f 240 idx += protocolLen;
sPymbed 17:ff9d1e86ad5f 241 /* Label */
sPymbed 17:ff9d1e86ad5f 242 XMEMCPY(&data[idx], label, labelLen);
sPymbed 17:ff9d1e86ad5f 243 idx += labelLen;
sPymbed 17:ff9d1e86ad5f 244 /* Length of hash of messages */
sPymbed 17:ff9d1e86ad5f 245 data[idx++] = (byte)infoLen;
sPymbed 17:ff9d1e86ad5f 246 /* Hash of messages */
sPymbed 17:ff9d1e86ad5f 247 XMEMCPY(&data[idx], info, infoLen);
sPymbed 17:ff9d1e86ad5f 248 idx += infoLen;
sPymbed 17:ff9d1e86ad5f 249
sPymbed 17:ff9d1e86ad5f 250 #ifdef WOLFSSL_DEBUG_TLS
sPymbed 17:ff9d1e86ad5f 251 WOLFSSL_MSG(" PRK");
sPymbed 17:ff9d1e86ad5f 252 WOLFSSL_BUFFER(prk, prkLen);
sPymbed 17:ff9d1e86ad5f 253 WOLFSSL_MSG(" Info");
sPymbed 17:ff9d1e86ad5f 254 WOLFSSL_BUFFER(data, idx);
sPymbed 17:ff9d1e86ad5f 255 #endif
sPymbed 17:ff9d1e86ad5f 256
sPymbed 17:ff9d1e86ad5f 257 ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
sPymbed 17:ff9d1e86ad5f 258
sPymbed 17:ff9d1e86ad5f 259 #ifdef WOLFSSL_DEBUG_TLS
sPymbed 17:ff9d1e86ad5f 260 WOLFSSL_MSG(" OKM");
sPymbed 17:ff9d1e86ad5f 261 WOLFSSL_BUFFER(okm, okmLen);
sPymbed 17:ff9d1e86ad5f 262 #endif
sPymbed 17:ff9d1e86ad5f 263
sPymbed 17:ff9d1e86ad5f 264 ForceZero(data, idx);
sPymbed 17:ff9d1e86ad5f 265
sPymbed 17:ff9d1e86ad5f 266 return ret;
sPymbed 17:ff9d1e86ad5f 267 }
sPymbed 17:ff9d1e86ad5f 268
sPymbed 17:ff9d1e86ad5f 269 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 270 /* Size of the TLS v1.3 label use when deriving keys. */
sPymbed 17:ff9d1e86ad5f 271 #define TLS13_PROTOCOL_LABEL_SZ 9
sPymbed 17:ff9d1e86ad5f 272 /* The protocol label for TLS v1.3. */
sPymbed 17:ff9d1e86ad5f 273 static const byte tls13ProtocolLabel[TLS13_PROTOCOL_LABEL_SZ + 1] = "TLS 1.3, ";
sPymbed 17:ff9d1e86ad5f 274 #else
sPymbed 17:ff9d1e86ad5f 275 /* Size of the TLS v1.3 label use when deriving keys. */
sPymbed 17:ff9d1e86ad5f 276 #define TLS13_PROTOCOL_LABEL_SZ 6
sPymbed 17:ff9d1e86ad5f 277 /* The protocol label for TLS v1.3. */
sPymbed 17:ff9d1e86ad5f 278 static const byte tls13ProtocolLabel[TLS13_PROTOCOL_LABEL_SZ + 1] = "tls13 ";
sPymbed 17:ff9d1e86ad5f 279 #endif
sPymbed 17:ff9d1e86ad5f 280
sPymbed 17:ff9d1e86ad5f 281 #if !defined(WOLFSSL_TLS13_DRAFT_18) || defined(HAVE_SESSION_TICKET) || \
sPymbed 17:ff9d1e86ad5f 282 !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 283 /* Derive a key from a message.
sPymbed 17:ff9d1e86ad5f 284 *
sPymbed 17:ff9d1e86ad5f 285 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 286 * output The buffer to hold the derived key.
sPymbed 17:ff9d1e86ad5f 287 * outputLen The length of the derived key.
sPymbed 17:ff9d1e86ad5f 288 * secret The secret used to derive the key (HMAC secret).
sPymbed 17:ff9d1e86ad5f 289 * label The label used to distinguish the context.
sPymbed 17:ff9d1e86ad5f 290 * labelLen The length of the label.
sPymbed 17:ff9d1e86ad5f 291 * msg The message data to derive key from.
sPymbed 17:ff9d1e86ad5f 292 * msgLen The length of the message data to derive key from.
sPymbed 17:ff9d1e86ad5f 293 * hashAlgo The hash algorithm to use in the HMAC.
sPymbed 17:ff9d1e86ad5f 294 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 295 */
sPymbed 17:ff9d1e86ad5f 296 static int DeriveKeyMsg(WOLFSSL* ssl, byte* output, int outputLen,
sPymbed 17:ff9d1e86ad5f 297 const byte* secret, const byte* label, word32 labelLen,
sPymbed 17:ff9d1e86ad5f 298 byte* msg, int msgLen, int hashAlgo)
sPymbed 17:ff9d1e86ad5f 299 {
sPymbed 17:ff9d1e86ad5f 300 byte hash[WC_MAX_DIGEST_SIZE];
sPymbed 17:ff9d1e86ad5f 301 Digest digest;
sPymbed 17:ff9d1e86ad5f 302 word32 hashSz = 0;
sPymbed 17:ff9d1e86ad5f 303 const byte* protocol;
sPymbed 17:ff9d1e86ad5f 304 word32 protocolLen;
sPymbed 17:ff9d1e86ad5f 305 int digestAlg = -1;
sPymbed 17:ff9d1e86ad5f 306 int ret = BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 307
sPymbed 17:ff9d1e86ad5f 308 switch (hashAlgo) {
sPymbed 17:ff9d1e86ad5f 309 #ifndef NO_WOLFSSL_SHA256
sPymbed 17:ff9d1e86ad5f 310 case sha256_mac:
sPymbed 17:ff9d1e86ad5f 311 ret = wc_InitSha256_ex(&digest.sha256, ssl->heap, INVALID_DEVID);
sPymbed 17:ff9d1e86ad5f 312 if (ret == 0) {
sPymbed 17:ff9d1e86ad5f 313 ret = wc_Sha256Update(&digest.sha256, msg, msgLen);
sPymbed 17:ff9d1e86ad5f 314 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 315 ret = wc_Sha256Final(&digest.sha256, hash);
sPymbed 17:ff9d1e86ad5f 316 wc_Sha256Free(&digest.sha256);
sPymbed 17:ff9d1e86ad5f 317 }
sPymbed 17:ff9d1e86ad5f 318 hashSz = WC_SHA256_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 319 digestAlg = WC_SHA256;
sPymbed 17:ff9d1e86ad5f 320 break;
sPymbed 17:ff9d1e86ad5f 321 #endif
sPymbed 17:ff9d1e86ad5f 322 #ifdef WOLFSSL_SHA384
sPymbed 17:ff9d1e86ad5f 323 case sha384_mac:
sPymbed 17:ff9d1e86ad5f 324 ret = wc_InitSha384_ex(&digest.sha384, ssl->heap, INVALID_DEVID);
sPymbed 17:ff9d1e86ad5f 325 if (ret == 0) {
sPymbed 17:ff9d1e86ad5f 326 ret = wc_Sha384Update(&digest.sha384, msg, msgLen);
sPymbed 17:ff9d1e86ad5f 327 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 328 ret = wc_Sha384Final(&digest.sha384, hash);
sPymbed 17:ff9d1e86ad5f 329 wc_Sha384Free(&digest.sha384);
sPymbed 17:ff9d1e86ad5f 330 }
sPymbed 17:ff9d1e86ad5f 331 hashSz = WC_SHA384_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 332 digestAlg = WC_SHA384;
sPymbed 17:ff9d1e86ad5f 333 break;
sPymbed 17:ff9d1e86ad5f 334 #endif
sPymbed 17:ff9d1e86ad5f 335 #ifdef WOLFSSL_TLS13_SHA512
sPymbed 17:ff9d1e86ad5f 336 case sha512_mac:
sPymbed 17:ff9d1e86ad5f 337 ret = wc_InitSha512_ex(&digest.sha512, ssl->heap, INVALID_DEVID);
sPymbed 17:ff9d1e86ad5f 338 if (ret == 0) {
sPymbed 17:ff9d1e86ad5f 339 ret = wc_Sha512Update(&digest.sha512, msg, msgLen);
sPymbed 17:ff9d1e86ad5f 340 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 341 ret = wc_Sha512Final(&digest.sha512, hash);
sPymbed 17:ff9d1e86ad5f 342 wc_Sha512Free(&digest.sha512);
sPymbed 17:ff9d1e86ad5f 343 }
sPymbed 17:ff9d1e86ad5f 344 hashSz = WC_SHA512_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 345 digestAlg = WC_SHA512;
sPymbed 17:ff9d1e86ad5f 346 break;
sPymbed 17:ff9d1e86ad5f 347 #endif
sPymbed 17:ff9d1e86ad5f 348 default:
sPymbed 17:ff9d1e86ad5f 349 digestAlg = -1;
sPymbed 17:ff9d1e86ad5f 350 break;
sPymbed 17:ff9d1e86ad5f 351 }
sPymbed 17:ff9d1e86ad5f 352
sPymbed 17:ff9d1e86ad5f 353 if (digestAlg < 0)
sPymbed 17:ff9d1e86ad5f 354 return HASH_TYPE_E;
sPymbed 17:ff9d1e86ad5f 355
sPymbed 17:ff9d1e86ad5f 356 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 357 return ret;
sPymbed 17:ff9d1e86ad5f 358
sPymbed 17:ff9d1e86ad5f 359 switch (ssl->version.minor) {
sPymbed 17:ff9d1e86ad5f 360 case TLSv1_3_MINOR:
sPymbed 17:ff9d1e86ad5f 361 protocol = tls13ProtocolLabel;
sPymbed 17:ff9d1e86ad5f 362 protocolLen = TLS13_PROTOCOL_LABEL_SZ;
sPymbed 17:ff9d1e86ad5f 363 break;
sPymbed 17:ff9d1e86ad5f 364
sPymbed 17:ff9d1e86ad5f 365 default:
sPymbed 17:ff9d1e86ad5f 366 return VERSION_ERROR;
sPymbed 17:ff9d1e86ad5f 367 }
sPymbed 17:ff9d1e86ad5f 368 if (outputLen == -1)
sPymbed 17:ff9d1e86ad5f 369 outputLen = hashSz;
sPymbed 17:ff9d1e86ad5f 370
sPymbed 17:ff9d1e86ad5f 371 return HKDF_Expand_Label(output, outputLen, secret, hashSz,
sPymbed 17:ff9d1e86ad5f 372 protocol, protocolLen, label, labelLen,
sPymbed 17:ff9d1e86ad5f 373 hash, hashSz, digestAlg);
sPymbed 17:ff9d1e86ad5f 374 }
sPymbed 17:ff9d1e86ad5f 375 #endif
sPymbed 17:ff9d1e86ad5f 376
sPymbed 17:ff9d1e86ad5f 377 /* Derive a key.
sPymbed 17:ff9d1e86ad5f 378 *
sPymbed 17:ff9d1e86ad5f 379 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 380 * output The buffer to hold the derived key.
sPymbed 17:ff9d1e86ad5f 381 * outputLen The length of the derived key.
sPymbed 17:ff9d1e86ad5f 382 * secret The secret used to derive the key (HMAC secret).
sPymbed 17:ff9d1e86ad5f 383 * label The label used to distinguish the context.
sPymbed 17:ff9d1e86ad5f 384 * labelLen The length of the label.
sPymbed 17:ff9d1e86ad5f 385 * hashAlgo The hash algorithm to use in the HMAC.
sPymbed 17:ff9d1e86ad5f 386 * includeMsgs Whether to include a hash of the handshake messages so far.
sPymbed 17:ff9d1e86ad5f 387 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 388 */
sPymbed 17:ff9d1e86ad5f 389 static int DeriveKey(WOLFSSL* ssl, byte* output, int outputLen,
sPymbed 17:ff9d1e86ad5f 390 const byte* secret, const byte* label, word32 labelLen,
sPymbed 17:ff9d1e86ad5f 391 int hashAlgo, int includeMsgs)
sPymbed 17:ff9d1e86ad5f 392 {
sPymbed 17:ff9d1e86ad5f 393 int ret = 0;
sPymbed 17:ff9d1e86ad5f 394 byte hash[WC_MAX_DIGEST_SIZE];
sPymbed 17:ff9d1e86ad5f 395 word32 hashSz = 0;
sPymbed 17:ff9d1e86ad5f 396 word32 hashOutSz = 0;
sPymbed 17:ff9d1e86ad5f 397 const byte* protocol;
sPymbed 17:ff9d1e86ad5f 398 word32 protocolLen;
sPymbed 17:ff9d1e86ad5f 399 int digestAlg = 0;
sPymbed 17:ff9d1e86ad5f 400
sPymbed 17:ff9d1e86ad5f 401 switch (hashAlgo) {
sPymbed 17:ff9d1e86ad5f 402 #ifndef NO_SHA256
sPymbed 17:ff9d1e86ad5f 403 case sha256_mac:
sPymbed 17:ff9d1e86ad5f 404 hashSz = WC_SHA256_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 405 digestAlg = WC_SHA256;
sPymbed 17:ff9d1e86ad5f 406 if (includeMsgs)
sPymbed 17:ff9d1e86ad5f 407 ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash);
sPymbed 17:ff9d1e86ad5f 408 break;
sPymbed 17:ff9d1e86ad5f 409 #endif
sPymbed 17:ff9d1e86ad5f 410
sPymbed 17:ff9d1e86ad5f 411 #ifdef WOLFSSL_SHA384
sPymbed 17:ff9d1e86ad5f 412 case sha384_mac:
sPymbed 17:ff9d1e86ad5f 413 hashSz = WC_SHA384_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 414 digestAlg = WC_SHA384;
sPymbed 17:ff9d1e86ad5f 415 if (includeMsgs)
sPymbed 17:ff9d1e86ad5f 416 ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash);
sPymbed 17:ff9d1e86ad5f 417 break;
sPymbed 17:ff9d1e86ad5f 418 #endif
sPymbed 17:ff9d1e86ad5f 419
sPymbed 17:ff9d1e86ad5f 420 #ifdef WOLFSSL_TLS13_SHA512
sPymbed 17:ff9d1e86ad5f 421 case sha512_mac:
sPymbed 17:ff9d1e86ad5f 422 hashSz = WC_SHA512_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 423 digestAlg = WC_SHA512;
sPymbed 17:ff9d1e86ad5f 424 if (includeMsgs)
sPymbed 17:ff9d1e86ad5f 425 ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512, hash);
sPymbed 17:ff9d1e86ad5f 426 break;
sPymbed 17:ff9d1e86ad5f 427 #endif
sPymbed 17:ff9d1e86ad5f 428 }
sPymbed 17:ff9d1e86ad5f 429 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 430 return ret;
sPymbed 17:ff9d1e86ad5f 431
sPymbed 17:ff9d1e86ad5f 432 /* Only one protocol version defined at this time. */
sPymbed 17:ff9d1e86ad5f 433 protocol = tls13ProtocolLabel;
sPymbed 17:ff9d1e86ad5f 434 protocolLen = TLS13_PROTOCOL_LABEL_SZ;
sPymbed 17:ff9d1e86ad5f 435
sPymbed 17:ff9d1e86ad5f 436 if (outputLen == -1)
sPymbed 17:ff9d1e86ad5f 437 outputLen = hashSz;
sPymbed 17:ff9d1e86ad5f 438 if (includeMsgs)
sPymbed 17:ff9d1e86ad5f 439 hashOutSz = hashSz;
sPymbed 17:ff9d1e86ad5f 440
sPymbed 17:ff9d1e86ad5f 441 return HKDF_Expand_Label(output, outputLen, secret, hashSz,
sPymbed 17:ff9d1e86ad5f 442 protocol, protocolLen, label, labelLen,
sPymbed 17:ff9d1e86ad5f 443 hash, hashOutSz, digestAlg);
sPymbed 17:ff9d1e86ad5f 444 }
sPymbed 17:ff9d1e86ad5f 445
sPymbed 17:ff9d1e86ad5f 446
sPymbed 17:ff9d1e86ad5f 447 #ifndef NO_PSK
sPymbed 17:ff9d1e86ad5f 448 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 449 /* The length of the binder key label. */
sPymbed 17:ff9d1e86ad5f 450 #define BINDER_KEY_LABEL_SZ 23
sPymbed 17:ff9d1e86ad5f 451 /* The binder key label. */
sPymbed 17:ff9d1e86ad5f 452 static const byte binderKeyLabel[BINDER_KEY_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 453 "external psk binder key";
sPymbed 17:ff9d1e86ad5f 454 #else
sPymbed 17:ff9d1e86ad5f 455 /* The length of the binder key label. */
sPymbed 17:ff9d1e86ad5f 456 #define BINDER_KEY_LABEL_SZ 10
sPymbed 17:ff9d1e86ad5f 457 /* The binder key label. */
sPymbed 17:ff9d1e86ad5f 458 static const byte binderKeyLabel[BINDER_KEY_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 459 "ext binder";
sPymbed 17:ff9d1e86ad5f 460 #endif
sPymbed 17:ff9d1e86ad5f 461 /* Derive the binder key.
sPymbed 17:ff9d1e86ad5f 462 *
sPymbed 17:ff9d1e86ad5f 463 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 464 * key The derived key.
sPymbed 17:ff9d1e86ad5f 465 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 466 */
sPymbed 17:ff9d1e86ad5f 467 static int DeriveBinderKey(WOLFSSL* ssl, byte* key)
sPymbed 17:ff9d1e86ad5f 468 {
sPymbed 17:ff9d1e86ad5f 469 WOLFSSL_MSG("Derive Binder Key");
sPymbed 17:ff9d1e86ad5f 470 return DeriveKeyMsg(ssl, key, -1, ssl->arrays->secret,
sPymbed 17:ff9d1e86ad5f 471 binderKeyLabel, BINDER_KEY_LABEL_SZ,
sPymbed 17:ff9d1e86ad5f 472 NULL, 0, ssl->specs.mac_algorithm);
sPymbed 17:ff9d1e86ad5f 473 }
sPymbed 17:ff9d1e86ad5f 474 #endif /* !NO_PSK */
sPymbed 17:ff9d1e86ad5f 475
sPymbed 17:ff9d1e86ad5f 476 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 477 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 478 /* The length of the binder key resume label. */
sPymbed 17:ff9d1e86ad5f 479 #define BINDER_KEY_RESUME_LABEL_SZ 25
sPymbed 17:ff9d1e86ad5f 480 /* The binder key resume label. */
sPymbed 17:ff9d1e86ad5f 481 static const byte binderKeyResumeLabel[BINDER_KEY_RESUME_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 482 "resumption psk binder key";
sPymbed 17:ff9d1e86ad5f 483 #else
sPymbed 17:ff9d1e86ad5f 484 /* The length of the binder key resume label. */
sPymbed 17:ff9d1e86ad5f 485 #define BINDER_KEY_RESUME_LABEL_SZ 10
sPymbed 17:ff9d1e86ad5f 486 /* The binder key resume label. */
sPymbed 17:ff9d1e86ad5f 487 static const byte binderKeyResumeLabel[BINDER_KEY_RESUME_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 488 "res binder";
sPymbed 17:ff9d1e86ad5f 489 #endif
sPymbed 17:ff9d1e86ad5f 490 /* Derive the binder resumption key.
sPymbed 17:ff9d1e86ad5f 491 *
sPymbed 17:ff9d1e86ad5f 492 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 493 * key The derived key.
sPymbed 17:ff9d1e86ad5f 494 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 495 */
sPymbed 17:ff9d1e86ad5f 496 static int DeriveBinderKeyResume(WOLFSSL* ssl, byte* key)
sPymbed 17:ff9d1e86ad5f 497 {
sPymbed 17:ff9d1e86ad5f 498 WOLFSSL_MSG("Derive Binder Key - Resumption");
sPymbed 17:ff9d1e86ad5f 499 return DeriveKeyMsg(ssl, key, -1, ssl->arrays->secret,
sPymbed 17:ff9d1e86ad5f 500 binderKeyResumeLabel, BINDER_KEY_RESUME_LABEL_SZ,
sPymbed 17:ff9d1e86ad5f 501 NULL, 0, ssl->specs.mac_algorithm);
sPymbed 17:ff9d1e86ad5f 502 }
sPymbed 17:ff9d1e86ad5f 503 #endif /* HAVE_SESSION_TICKET */
sPymbed 17:ff9d1e86ad5f 504
sPymbed 17:ff9d1e86ad5f 505 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 506 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 507 /* The length of the early traffic label. */
sPymbed 17:ff9d1e86ad5f 508 #define EARLY_TRAFFIC_LABEL_SZ 27
sPymbed 17:ff9d1e86ad5f 509 /* The early traffic label. */
sPymbed 17:ff9d1e86ad5f 510 static const byte earlyTrafficLabel[EARLY_TRAFFIC_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 511 "client early traffic secret";
sPymbed 17:ff9d1e86ad5f 512 #else
sPymbed 17:ff9d1e86ad5f 513 /* The length of the early traffic label. */
sPymbed 17:ff9d1e86ad5f 514 #define EARLY_TRAFFIC_LABEL_SZ 11
sPymbed 17:ff9d1e86ad5f 515 /* The early traffic label. */
sPymbed 17:ff9d1e86ad5f 516 static const byte earlyTrafficLabel[EARLY_TRAFFIC_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 517 "c e traffic";
sPymbed 17:ff9d1e86ad5f 518 #endif
sPymbed 17:ff9d1e86ad5f 519 /* Derive the early traffic key.
sPymbed 17:ff9d1e86ad5f 520 *
sPymbed 17:ff9d1e86ad5f 521 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 522 * key The derived key.
sPymbed 17:ff9d1e86ad5f 523 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 524 */
sPymbed 17:ff9d1e86ad5f 525 static int DeriveEarlyTrafficSecret(WOLFSSL* ssl, byte* key)
sPymbed 17:ff9d1e86ad5f 526 {
sPymbed 17:ff9d1e86ad5f 527 WOLFSSL_MSG("Derive Early Traffic Secret");
sPymbed 17:ff9d1e86ad5f 528 return DeriveKey(ssl, key, -1, ssl->arrays->secret,
sPymbed 17:ff9d1e86ad5f 529 earlyTrafficLabel, EARLY_TRAFFIC_LABEL_SZ,
sPymbed 17:ff9d1e86ad5f 530 ssl->specs.mac_algorithm, 1);
sPymbed 17:ff9d1e86ad5f 531 }
sPymbed 17:ff9d1e86ad5f 532
sPymbed 17:ff9d1e86ad5f 533 #ifdef TLS13_SUPPORTS_EXPORTERS
sPymbed 17:ff9d1e86ad5f 534 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 535 /* The length of the early exporter label. */
sPymbed 17:ff9d1e86ad5f 536 #define EARLY_EXPORTER_LABEL_SZ 28
sPymbed 17:ff9d1e86ad5f 537 /* The early exporter label. */
sPymbed 17:ff9d1e86ad5f 538 static const byte earlyExporterLabel[EARLY_EXPORTER_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 539 "early exporter master secret";
sPymbed 17:ff9d1e86ad5f 540 #else
sPymbed 17:ff9d1e86ad5f 541 /* The length of the early exporter label. */
sPymbed 17:ff9d1e86ad5f 542 #define EARLY_EXPORTER_LABEL_SZ 12
sPymbed 17:ff9d1e86ad5f 543 /* The early exporter label. */
sPymbed 17:ff9d1e86ad5f 544 static const byte earlyExporterLabel[EARLY_EXPORTER_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 545 "e exp master";
sPymbed 17:ff9d1e86ad5f 546 #endif
sPymbed 17:ff9d1e86ad5f 547 /* Derive the early exporter key.
sPymbed 17:ff9d1e86ad5f 548 *
sPymbed 17:ff9d1e86ad5f 549 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 550 * key The derived key.
sPymbed 17:ff9d1e86ad5f 551 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 552 */
sPymbed 17:ff9d1e86ad5f 553 static int DeriveEarlyExporterSecret(WOLFSSL* ssl, byte* key)
sPymbed 17:ff9d1e86ad5f 554 {
sPymbed 17:ff9d1e86ad5f 555 WOLFSSL_MSG("Derive Early Exporter Secret");
sPymbed 17:ff9d1e86ad5f 556 return DeriveKey(ssl, key, -1, ssl->arrays->secret,
sPymbed 17:ff9d1e86ad5f 557 earlyExporterLabel, EARLY_EXPORTER_LABEL_SZ,
sPymbed 17:ff9d1e86ad5f 558 ssl->specs.mac_algorithm, 1);
sPymbed 17:ff9d1e86ad5f 559 }
sPymbed 17:ff9d1e86ad5f 560 #endif
sPymbed 17:ff9d1e86ad5f 561 #endif
sPymbed 17:ff9d1e86ad5f 562
sPymbed 17:ff9d1e86ad5f 563 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 564 /* The length of the client hanshake label. */
sPymbed 17:ff9d1e86ad5f 565 #define CLIENT_HANDSHAKE_LABEL_SZ 31
sPymbed 17:ff9d1e86ad5f 566 /* The client hanshake label. */
sPymbed 17:ff9d1e86ad5f 567 static const byte clientHandshakeLabel[CLIENT_HANDSHAKE_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 568 "client handshake traffic secret";
sPymbed 17:ff9d1e86ad5f 569 #else
sPymbed 17:ff9d1e86ad5f 570 /* The length of the client hanshake label. */
sPymbed 17:ff9d1e86ad5f 571 #define CLIENT_HANDSHAKE_LABEL_SZ 12
sPymbed 17:ff9d1e86ad5f 572 /* The client hanshake label. */
sPymbed 17:ff9d1e86ad5f 573 static const byte clientHandshakeLabel[CLIENT_HANDSHAKE_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 574 "c hs traffic";
sPymbed 17:ff9d1e86ad5f 575 #endif
sPymbed 17:ff9d1e86ad5f 576 /* Derive the client handshake key.
sPymbed 17:ff9d1e86ad5f 577 *
sPymbed 17:ff9d1e86ad5f 578 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 579 * key The derived key.
sPymbed 17:ff9d1e86ad5f 580 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 581 */
sPymbed 17:ff9d1e86ad5f 582 static int DeriveClientHandshakeSecret(WOLFSSL* ssl, byte* key)
sPymbed 17:ff9d1e86ad5f 583 {
sPymbed 17:ff9d1e86ad5f 584 WOLFSSL_MSG("Derive Client Handshake Secret");
sPymbed 17:ff9d1e86ad5f 585 return DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret,
sPymbed 17:ff9d1e86ad5f 586 clientHandshakeLabel, CLIENT_HANDSHAKE_LABEL_SZ,
sPymbed 17:ff9d1e86ad5f 587 ssl->specs.mac_algorithm, 1);
sPymbed 17:ff9d1e86ad5f 588 }
sPymbed 17:ff9d1e86ad5f 589
sPymbed 17:ff9d1e86ad5f 590 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 591 /* The length of the server handshake label. */
sPymbed 17:ff9d1e86ad5f 592 #define SERVER_HANDSHAKE_LABEL_SZ 31
sPymbed 17:ff9d1e86ad5f 593 /* The server handshake label. */
sPymbed 17:ff9d1e86ad5f 594 static const byte serverHandshakeLabel[SERVER_HANDSHAKE_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 595 "server handshake traffic secret";
sPymbed 17:ff9d1e86ad5f 596 #else
sPymbed 17:ff9d1e86ad5f 597 /* The length of the server handshake label. */
sPymbed 17:ff9d1e86ad5f 598 #define SERVER_HANDSHAKE_LABEL_SZ 12
sPymbed 17:ff9d1e86ad5f 599 /* The server handshake label. */
sPymbed 17:ff9d1e86ad5f 600 static const byte serverHandshakeLabel[SERVER_HANDSHAKE_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 601 "s hs traffic";
sPymbed 17:ff9d1e86ad5f 602 #endif
sPymbed 17:ff9d1e86ad5f 603 /* Derive the server handshake key.
sPymbed 17:ff9d1e86ad5f 604 *
sPymbed 17:ff9d1e86ad5f 605 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 606 * key The derived key.
sPymbed 17:ff9d1e86ad5f 607 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 608 */
sPymbed 17:ff9d1e86ad5f 609 static int DeriveServerHandshakeSecret(WOLFSSL* ssl, byte* key)
sPymbed 17:ff9d1e86ad5f 610 {
sPymbed 17:ff9d1e86ad5f 611 WOLFSSL_MSG("Derive Server Handshake Secret");
sPymbed 17:ff9d1e86ad5f 612 return DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret,
sPymbed 17:ff9d1e86ad5f 613 serverHandshakeLabel, SERVER_HANDSHAKE_LABEL_SZ,
sPymbed 17:ff9d1e86ad5f 614 ssl->specs.mac_algorithm, 1);
sPymbed 17:ff9d1e86ad5f 615 }
sPymbed 17:ff9d1e86ad5f 616
sPymbed 17:ff9d1e86ad5f 617 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 618 /* The length of the client application traffic label. */
sPymbed 17:ff9d1e86ad5f 619 #define CLIENT_APP_LABEL_SZ 33
sPymbed 17:ff9d1e86ad5f 620 /* The client application traffic label. */
sPymbed 17:ff9d1e86ad5f 621 static const byte clientAppLabel[CLIENT_APP_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 622 "client application traffic secret";
sPymbed 17:ff9d1e86ad5f 623 #else
sPymbed 17:ff9d1e86ad5f 624 /* The length of the client application traffic label. */
sPymbed 17:ff9d1e86ad5f 625 #define CLIENT_APP_LABEL_SZ 12
sPymbed 17:ff9d1e86ad5f 626 /* The client application traffic label. */
sPymbed 17:ff9d1e86ad5f 627 static const byte clientAppLabel[CLIENT_APP_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 628 "c ap traffic";
sPymbed 17:ff9d1e86ad5f 629 #endif
sPymbed 17:ff9d1e86ad5f 630 /* Derive the client application traffic key.
sPymbed 17:ff9d1e86ad5f 631 *
sPymbed 17:ff9d1e86ad5f 632 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 633 * key The derived key.
sPymbed 17:ff9d1e86ad5f 634 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 635 */
sPymbed 17:ff9d1e86ad5f 636 static int DeriveClientTrafficSecret(WOLFSSL* ssl, byte* key)
sPymbed 17:ff9d1e86ad5f 637 {
sPymbed 17:ff9d1e86ad5f 638 WOLFSSL_MSG("Derive Client Traffic Secret");
sPymbed 17:ff9d1e86ad5f 639 return DeriveKey(ssl, key, -1, ssl->arrays->masterSecret,
sPymbed 17:ff9d1e86ad5f 640 clientAppLabel, CLIENT_APP_LABEL_SZ,
sPymbed 17:ff9d1e86ad5f 641 ssl->specs.mac_algorithm, 1);
sPymbed 17:ff9d1e86ad5f 642 }
sPymbed 17:ff9d1e86ad5f 643
sPymbed 17:ff9d1e86ad5f 644 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 645 /* The length of the server application traffic label. */
sPymbed 17:ff9d1e86ad5f 646 #define SERVER_APP_LABEL_SZ 33
sPymbed 17:ff9d1e86ad5f 647 /* The server application traffic label. */
sPymbed 17:ff9d1e86ad5f 648 static const byte serverAppLabel[SERVER_APP_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 649 "server application traffic secret";
sPymbed 17:ff9d1e86ad5f 650 #else
sPymbed 17:ff9d1e86ad5f 651 /* The length of the server application traffic label. */
sPymbed 17:ff9d1e86ad5f 652 #define SERVER_APP_LABEL_SZ 12
sPymbed 17:ff9d1e86ad5f 653 /* The server application traffic label. */
sPymbed 17:ff9d1e86ad5f 654 static const byte serverAppLabel[SERVER_APP_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 655 "s ap traffic";
sPymbed 17:ff9d1e86ad5f 656 #endif
sPymbed 17:ff9d1e86ad5f 657 /* Derive the server application traffic key.
sPymbed 17:ff9d1e86ad5f 658 *
sPymbed 17:ff9d1e86ad5f 659 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 660 * key The derived key.
sPymbed 17:ff9d1e86ad5f 661 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 662 */
sPymbed 17:ff9d1e86ad5f 663 static int DeriveServerTrafficSecret(WOLFSSL* ssl, byte* key)
sPymbed 17:ff9d1e86ad5f 664 {
sPymbed 17:ff9d1e86ad5f 665 WOLFSSL_MSG("Derive Server Traffic Secret");
sPymbed 17:ff9d1e86ad5f 666 return DeriveKey(ssl, key, -1, ssl->arrays->masterSecret,
sPymbed 17:ff9d1e86ad5f 667 serverAppLabel, SERVER_APP_LABEL_SZ,
sPymbed 17:ff9d1e86ad5f 668 ssl->specs.mac_algorithm, 1);
sPymbed 17:ff9d1e86ad5f 669 }
sPymbed 17:ff9d1e86ad5f 670
sPymbed 17:ff9d1e86ad5f 671 #ifdef TLS13_SUPPORTS_EXPORTERS
sPymbed 17:ff9d1e86ad5f 672 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 673 /* The length of the exporter master secret label. */
sPymbed 17:ff9d1e86ad5f 674 #define EXPORTER_MASTER_LABEL_SZ 22
sPymbed 17:ff9d1e86ad5f 675 /* The exporter master secret label. */
sPymbed 17:ff9d1e86ad5f 676 static const byte exporterMasterLabel[EXPORTER_MASTER_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 677 "exporter master secret";
sPymbed 17:ff9d1e86ad5f 678 #else
sPymbed 17:ff9d1e86ad5f 679 /* The length of the exporter master secret label. */
sPymbed 17:ff9d1e86ad5f 680 #define EXPORTER_MASTER_LABEL_SZ 10
sPymbed 17:ff9d1e86ad5f 681 /* The exporter master secret label. */
sPymbed 17:ff9d1e86ad5f 682 static const byte exporterMasterLabel[EXPORTER_MASTER_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 683 "exp master";
sPymbed 17:ff9d1e86ad5f 684 #endif
sPymbed 17:ff9d1e86ad5f 685 /* Derive the exporter secret.
sPymbed 17:ff9d1e86ad5f 686 *
sPymbed 17:ff9d1e86ad5f 687 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 688 * key The derived key.
sPymbed 17:ff9d1e86ad5f 689 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 690 */
sPymbed 17:ff9d1e86ad5f 691 static int DeriveExporterSecret(WOLFSSL* ssl, byte* key)
sPymbed 17:ff9d1e86ad5f 692 {
sPymbed 17:ff9d1e86ad5f 693 WOLFSSL_MSG("Derive Exporter Secret");
sPymbed 17:ff9d1e86ad5f 694 return DeriveKey(ssl, key, -1, ssl->arrays->masterSecret,
sPymbed 17:ff9d1e86ad5f 695 exporterMasterLabel, EXPORTER_MASTER_LABEL_SZ,
sPymbed 17:ff9d1e86ad5f 696 ssl->specs.mac_algorithm, 1);
sPymbed 17:ff9d1e86ad5f 697 }
sPymbed 17:ff9d1e86ad5f 698 #endif
sPymbed 17:ff9d1e86ad5f 699
sPymbed 17:ff9d1e86ad5f 700 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 701 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 702 /* The length of the resumption master secret label. */
sPymbed 17:ff9d1e86ad5f 703 #define RESUME_MASTER_LABEL_SZ 24
sPymbed 17:ff9d1e86ad5f 704 /* The resumption master secret label. */
sPymbed 17:ff9d1e86ad5f 705 static const byte resumeMasterLabel[RESUME_MASTER_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 706 "resumption master secret";
sPymbed 17:ff9d1e86ad5f 707 #else
sPymbed 17:ff9d1e86ad5f 708 /* The length of the resumption master secret label. */
sPymbed 17:ff9d1e86ad5f 709 #define RESUME_MASTER_LABEL_SZ 10
sPymbed 17:ff9d1e86ad5f 710 /* The resumption master secret label. */
sPymbed 17:ff9d1e86ad5f 711 static const byte resumeMasterLabel[RESUME_MASTER_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 712 "res master";
sPymbed 17:ff9d1e86ad5f 713 #endif
sPymbed 17:ff9d1e86ad5f 714 /* Derive the resumption secret.
sPymbed 17:ff9d1e86ad5f 715 *
sPymbed 17:ff9d1e86ad5f 716 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 717 * key The derived key.
sPymbed 17:ff9d1e86ad5f 718 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 719 */
sPymbed 17:ff9d1e86ad5f 720 static int DeriveResumptionSecret(WOLFSSL* ssl, byte* key)
sPymbed 17:ff9d1e86ad5f 721 {
sPymbed 17:ff9d1e86ad5f 722 WOLFSSL_MSG("Derive Resumption Secret");
sPymbed 17:ff9d1e86ad5f 723 return DeriveKey(ssl, key, -1, ssl->arrays->masterSecret,
sPymbed 17:ff9d1e86ad5f 724 resumeMasterLabel, RESUME_MASTER_LABEL_SZ,
sPymbed 17:ff9d1e86ad5f 725 ssl->specs.mac_algorithm, 1);
sPymbed 17:ff9d1e86ad5f 726 }
sPymbed 17:ff9d1e86ad5f 727 #endif
sPymbed 17:ff9d1e86ad5f 728
sPymbed 17:ff9d1e86ad5f 729 /* Length of the finished label. */
sPymbed 17:ff9d1e86ad5f 730 #define FINISHED_LABEL_SZ 8
sPymbed 17:ff9d1e86ad5f 731 /* Finished label for generating finished key. */
sPymbed 17:ff9d1e86ad5f 732 static const byte finishedLabel[FINISHED_LABEL_SZ+1] = "finished";
sPymbed 17:ff9d1e86ad5f 733 /* Derive the finished secret.
sPymbed 17:ff9d1e86ad5f 734 *
sPymbed 17:ff9d1e86ad5f 735 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 736 * key The key to use with the HMAC.
sPymbed 17:ff9d1e86ad5f 737 * secret The derived secret.
sPymbed 17:ff9d1e86ad5f 738 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 739 */
sPymbed 17:ff9d1e86ad5f 740 static int DeriveFinishedSecret(WOLFSSL* ssl, byte* key, byte* secret)
sPymbed 17:ff9d1e86ad5f 741 {
sPymbed 17:ff9d1e86ad5f 742 WOLFSSL_MSG("Derive Finished Secret");
sPymbed 17:ff9d1e86ad5f 743 return DeriveKey(ssl, secret, -1, key, finishedLabel, FINISHED_LABEL_SZ,
sPymbed 17:ff9d1e86ad5f 744 ssl->specs.mac_algorithm, 0);
sPymbed 17:ff9d1e86ad5f 745 }
sPymbed 17:ff9d1e86ad5f 746
sPymbed 17:ff9d1e86ad5f 747 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 748 /* The length of the application traffic label. */
sPymbed 17:ff9d1e86ad5f 749 #define APP_TRAFFIC_LABEL_SZ 26
sPymbed 17:ff9d1e86ad5f 750 /* The application traffic label. */
sPymbed 17:ff9d1e86ad5f 751 static const byte appTrafficLabel[APP_TRAFFIC_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 752 "application traffic secret";
sPymbed 17:ff9d1e86ad5f 753 #else
sPymbed 17:ff9d1e86ad5f 754 /* The length of the application traffic label. */
sPymbed 17:ff9d1e86ad5f 755 #define APP_TRAFFIC_LABEL_SZ 11
sPymbed 17:ff9d1e86ad5f 756 /* The application traffic label. */
sPymbed 17:ff9d1e86ad5f 757 static const byte appTrafficLabel[APP_TRAFFIC_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 758 "traffic upd";
sPymbed 17:ff9d1e86ad5f 759 #endif
sPymbed 17:ff9d1e86ad5f 760 /* Update the traffic secret.
sPymbed 17:ff9d1e86ad5f 761 *
sPymbed 17:ff9d1e86ad5f 762 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 763 * secret The previous secret and derived secret.
sPymbed 17:ff9d1e86ad5f 764 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 765 */
sPymbed 17:ff9d1e86ad5f 766 static int DeriveTrafficSecret(WOLFSSL* ssl, byte* secret)
sPymbed 17:ff9d1e86ad5f 767 {
sPymbed 17:ff9d1e86ad5f 768 WOLFSSL_MSG("Derive New Application Traffic Secret");
sPymbed 17:ff9d1e86ad5f 769 return DeriveKey(ssl, secret, -1, secret,
sPymbed 17:ff9d1e86ad5f 770 appTrafficLabel, APP_TRAFFIC_LABEL_SZ,
sPymbed 17:ff9d1e86ad5f 771 ssl->specs.mac_algorithm, 0);
sPymbed 17:ff9d1e86ad5f 772 }
sPymbed 17:ff9d1e86ad5f 773
sPymbed 17:ff9d1e86ad5f 774 /* Derive the early secret using HKDF Extract.
sPymbed 17:ff9d1e86ad5f 775 *
sPymbed 17:ff9d1e86ad5f 776 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 777 */
sPymbed 17:ff9d1e86ad5f 778 static int DeriveEarlySecret(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 779 {
sPymbed 17:ff9d1e86ad5f 780 WOLFSSL_MSG("Derive Early Secret");
sPymbed 17:ff9d1e86ad5f 781 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 782 return Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0,
sPymbed 17:ff9d1e86ad5f 783 ssl->arrays->psk_key, ssl->arrays->psk_keySz,
sPymbed 17:ff9d1e86ad5f 784 ssl->specs.mac_algorithm);
sPymbed 17:ff9d1e86ad5f 785 #else
sPymbed 17:ff9d1e86ad5f 786 return Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0,
sPymbed 17:ff9d1e86ad5f 787 ssl->arrays->masterSecret, 0, ssl->specs.mac_algorithm);
sPymbed 17:ff9d1e86ad5f 788 #endif
sPymbed 17:ff9d1e86ad5f 789 }
sPymbed 17:ff9d1e86ad5f 790
sPymbed 17:ff9d1e86ad5f 791 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 792 /* The length of the derived label. */
sPymbed 17:ff9d1e86ad5f 793 #define DERIVED_LABEL_SZ 7
sPymbed 17:ff9d1e86ad5f 794 /* The derived label. */
sPymbed 17:ff9d1e86ad5f 795 static const byte derivedLabel[DERIVED_LABEL_SZ + 1] =
sPymbed 17:ff9d1e86ad5f 796 "derived";
sPymbed 17:ff9d1e86ad5f 797 #endif
sPymbed 17:ff9d1e86ad5f 798 /* Derive the handshake secret using HKDF Extract.
sPymbed 17:ff9d1e86ad5f 799 *
sPymbed 17:ff9d1e86ad5f 800 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 801 */
sPymbed 17:ff9d1e86ad5f 802 static int DeriveHandshakeSecret(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 803 {
sPymbed 17:ff9d1e86ad5f 804 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 805 WOLFSSL_MSG("Derive Handshake Secret");
sPymbed 17:ff9d1e86ad5f 806 return Tls13_HKDF_Extract(ssl->arrays->preMasterSecret,
sPymbed 17:ff9d1e86ad5f 807 ssl->arrays->secret, ssl->specs.hash_size,
sPymbed 17:ff9d1e86ad5f 808 ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
sPymbed 17:ff9d1e86ad5f 809 ssl->specs.mac_algorithm);
sPymbed 17:ff9d1e86ad5f 810 #else
sPymbed 17:ff9d1e86ad5f 811 byte key[WC_MAX_DIGEST_SIZE];
sPymbed 17:ff9d1e86ad5f 812 int ret;
sPymbed 17:ff9d1e86ad5f 813
sPymbed 17:ff9d1e86ad5f 814 WOLFSSL_MSG("Derive Handshake Secret");
sPymbed 17:ff9d1e86ad5f 815
sPymbed 17:ff9d1e86ad5f 816 ret = DeriveKeyMsg(ssl, key, -1, ssl->arrays->secret,
sPymbed 17:ff9d1e86ad5f 817 derivedLabel, DERIVED_LABEL_SZ,
sPymbed 17:ff9d1e86ad5f 818 NULL, 0, ssl->specs.mac_algorithm);
sPymbed 17:ff9d1e86ad5f 819 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 820 return ret;
sPymbed 17:ff9d1e86ad5f 821
sPymbed 17:ff9d1e86ad5f 822 return Tls13_HKDF_Extract(ssl->arrays->preMasterSecret,
sPymbed 17:ff9d1e86ad5f 823 key, ssl->specs.hash_size,
sPymbed 17:ff9d1e86ad5f 824 ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
sPymbed 17:ff9d1e86ad5f 825 ssl->specs.mac_algorithm);
sPymbed 17:ff9d1e86ad5f 826 #endif
sPymbed 17:ff9d1e86ad5f 827 }
sPymbed 17:ff9d1e86ad5f 828
sPymbed 17:ff9d1e86ad5f 829 /* Derive the master secret using HKDF Extract.
sPymbed 17:ff9d1e86ad5f 830 *
sPymbed 17:ff9d1e86ad5f 831 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 832 */
sPymbed 17:ff9d1e86ad5f 833 static int DeriveMasterSecret(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 834 {
sPymbed 17:ff9d1e86ad5f 835 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 836 WOLFSSL_MSG("Derive Master Secret");
sPymbed 17:ff9d1e86ad5f 837 return Tls13_HKDF_Extract(ssl->arrays->masterSecret,
sPymbed 17:ff9d1e86ad5f 838 ssl->arrays->preMasterSecret, ssl->specs.hash_size,
sPymbed 17:ff9d1e86ad5f 839 ssl->arrays->masterSecret, 0, ssl->specs.mac_algorithm);
sPymbed 17:ff9d1e86ad5f 840 #else
sPymbed 17:ff9d1e86ad5f 841 byte key[WC_MAX_DIGEST_SIZE];
sPymbed 17:ff9d1e86ad5f 842 int ret;
sPymbed 17:ff9d1e86ad5f 843
sPymbed 17:ff9d1e86ad5f 844 WOLFSSL_MSG("Derive Master Secret");
sPymbed 17:ff9d1e86ad5f 845
sPymbed 17:ff9d1e86ad5f 846 ret = DeriveKeyMsg(ssl, key, -1, ssl->arrays->preMasterSecret,
sPymbed 17:ff9d1e86ad5f 847 derivedLabel, DERIVED_LABEL_SZ,
sPymbed 17:ff9d1e86ad5f 848 NULL, 0, ssl->specs.mac_algorithm);
sPymbed 17:ff9d1e86ad5f 849 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 850 return ret;
sPymbed 17:ff9d1e86ad5f 851
sPymbed 17:ff9d1e86ad5f 852 return Tls13_HKDF_Extract(ssl->arrays->masterSecret,
sPymbed 17:ff9d1e86ad5f 853 key, ssl->specs.hash_size,
sPymbed 17:ff9d1e86ad5f 854 ssl->arrays->masterSecret, 0, ssl->specs.mac_algorithm);
sPymbed 17:ff9d1e86ad5f 855 #endif
sPymbed 17:ff9d1e86ad5f 856 }
sPymbed 17:ff9d1e86ad5f 857
sPymbed 17:ff9d1e86ad5f 858 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 859 #if defined(HAVE_SESSION_TICKET)
sPymbed 17:ff9d1e86ad5f 860 /* Length of the resumption label. */
sPymbed 17:ff9d1e86ad5f 861 #define RESUMPTION_LABEL_SZ 10
sPymbed 17:ff9d1e86ad5f 862 /* Resumption label for generating PSK assocated with the ticket. */
sPymbed 17:ff9d1e86ad5f 863 static const byte resumptionLabel[RESUMPTION_LABEL_SZ+1] = "resumption";
sPymbed 17:ff9d1e86ad5f 864 /* Derive the PSK assocated with the ticket.
sPymbed 17:ff9d1e86ad5f 865 *
sPymbed 17:ff9d1e86ad5f 866 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 867 * nonce The nonce to derive with.
sPymbed 17:ff9d1e86ad5f 868 * nonceLen The length of the nonce to derive with.
sPymbed 17:ff9d1e86ad5f 869 * secret The derived secret.
sPymbed 17:ff9d1e86ad5f 870 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 871 */
sPymbed 17:ff9d1e86ad5f 872 static int DeriveResumptionPSK(WOLFSSL* ssl, byte* nonce, byte nonceLen,
sPymbed 17:ff9d1e86ad5f 873 byte* secret)
sPymbed 17:ff9d1e86ad5f 874 {
sPymbed 17:ff9d1e86ad5f 875 int digestAlg;
sPymbed 17:ff9d1e86ad5f 876 /* Only one protocol version defined at this time. */
sPymbed 17:ff9d1e86ad5f 877 const byte* protocol = tls13ProtocolLabel;
sPymbed 17:ff9d1e86ad5f 878 word32 protocolLen = TLS13_PROTOCOL_LABEL_SZ;
sPymbed 17:ff9d1e86ad5f 879
sPymbed 17:ff9d1e86ad5f 880 WOLFSSL_MSG("Derive Resumption PSK");
sPymbed 17:ff9d1e86ad5f 881
sPymbed 17:ff9d1e86ad5f 882 switch (ssl->specs.mac_algorithm) {
sPymbed 17:ff9d1e86ad5f 883 #ifndef NO_SHA256
sPymbed 17:ff9d1e86ad5f 884 case sha256_mac:
sPymbed 17:ff9d1e86ad5f 885 digestAlg = WC_SHA256;
sPymbed 17:ff9d1e86ad5f 886 break;
sPymbed 17:ff9d1e86ad5f 887 #endif
sPymbed 17:ff9d1e86ad5f 888
sPymbed 17:ff9d1e86ad5f 889 #ifdef WOLFSSL_SHA384
sPymbed 17:ff9d1e86ad5f 890 case sha384_mac:
sPymbed 17:ff9d1e86ad5f 891 digestAlg = WC_SHA384;
sPymbed 17:ff9d1e86ad5f 892 break;
sPymbed 17:ff9d1e86ad5f 893 #endif
sPymbed 17:ff9d1e86ad5f 894
sPymbed 17:ff9d1e86ad5f 895 #ifdef WOLFSSL_TLS13_SHA512
sPymbed 17:ff9d1e86ad5f 896 case sha512_mac:
sPymbed 17:ff9d1e86ad5f 897 digestAlg = WC_SHA512;
sPymbed 17:ff9d1e86ad5f 898 break;
sPymbed 17:ff9d1e86ad5f 899 #endif
sPymbed 17:ff9d1e86ad5f 900
sPymbed 17:ff9d1e86ad5f 901 default:
sPymbed 17:ff9d1e86ad5f 902 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 903 }
sPymbed 17:ff9d1e86ad5f 904
sPymbed 17:ff9d1e86ad5f 905 return HKDF_Expand_Label(secret, ssl->specs.hash_size,
sPymbed 17:ff9d1e86ad5f 906 ssl->session.masterSecret, ssl->specs.hash_size,
sPymbed 17:ff9d1e86ad5f 907 protocol, protocolLen, resumptionLabel,
sPymbed 17:ff9d1e86ad5f 908 RESUMPTION_LABEL_SZ, nonce, nonceLen, digestAlg);
sPymbed 17:ff9d1e86ad5f 909 }
sPymbed 17:ff9d1e86ad5f 910 #endif /* HAVE_SESSION_TICKET */
sPymbed 17:ff9d1e86ad5f 911 #endif /* WOLFSSL_TLS13_DRAFT_18 */
sPymbed 17:ff9d1e86ad5f 912
sPymbed 17:ff9d1e86ad5f 913
sPymbed 17:ff9d1e86ad5f 914 /* Calculate the HMAC of message data to this point.
sPymbed 17:ff9d1e86ad5f 915 *
sPymbed 17:ff9d1e86ad5f 916 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 917 * key The HMAC key.
sPymbed 17:ff9d1e86ad5f 918 * hash The hash result - verify data.
sPymbed 17:ff9d1e86ad5f 919 * returns length of verify data generated.
sPymbed 17:ff9d1e86ad5f 920 */
sPymbed 17:ff9d1e86ad5f 921 static int BuildTls13HandshakeHmac(WOLFSSL* ssl, byte* key, byte* hash,
sPymbed 17:ff9d1e86ad5f 922 word32* pHashSz)
sPymbed 17:ff9d1e86ad5f 923 {
sPymbed 17:ff9d1e86ad5f 924 Hmac verifyHmac;
sPymbed 17:ff9d1e86ad5f 925 int hashType = WC_SHA256;
sPymbed 17:ff9d1e86ad5f 926 int hashSz = WC_SHA256_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 927 int ret = BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 928
sPymbed 17:ff9d1e86ad5f 929 /* Get the hash of the previous handshake messages. */
sPymbed 17:ff9d1e86ad5f 930 switch (ssl->specs.mac_algorithm) {
sPymbed 17:ff9d1e86ad5f 931 #ifndef NO_SHA256
sPymbed 17:ff9d1e86ad5f 932 case sha256_mac:
sPymbed 17:ff9d1e86ad5f 933 hashType = WC_SHA256;
sPymbed 17:ff9d1e86ad5f 934 hashSz = WC_SHA256_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 935 ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash);
sPymbed 17:ff9d1e86ad5f 936 break;
sPymbed 17:ff9d1e86ad5f 937 #endif /* !NO_SHA256 */
sPymbed 17:ff9d1e86ad5f 938 #ifdef WOLFSSL_SHA384
sPymbed 17:ff9d1e86ad5f 939 case sha384_mac:
sPymbed 17:ff9d1e86ad5f 940 hashType = WC_SHA384;
sPymbed 17:ff9d1e86ad5f 941 hashSz = WC_SHA384_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 942 ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash);
sPymbed 17:ff9d1e86ad5f 943 break;
sPymbed 17:ff9d1e86ad5f 944 #endif /* WOLFSSL_SHA384 */
sPymbed 17:ff9d1e86ad5f 945 #ifdef WOLFSSL_TLS13_SHA512
sPymbed 17:ff9d1e86ad5f 946 case sha512_mac:
sPymbed 17:ff9d1e86ad5f 947 hashType = WC_SHA512;
sPymbed 17:ff9d1e86ad5f 948 hashSz = WC_SHA512_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 949 ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512, hash);
sPymbed 17:ff9d1e86ad5f 950 break;
sPymbed 17:ff9d1e86ad5f 951 #endif /* WOLFSSL_TLS13_SHA512 */
sPymbed 17:ff9d1e86ad5f 952 }
sPymbed 17:ff9d1e86ad5f 953 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 954 return ret;
sPymbed 17:ff9d1e86ad5f 955
sPymbed 17:ff9d1e86ad5f 956 /* Calculate the verify data. */
sPymbed 17:ff9d1e86ad5f 957 ret = wc_HmacInit(&verifyHmac, ssl->heap, ssl->devId);
sPymbed 17:ff9d1e86ad5f 958 if (ret == 0) {
sPymbed 17:ff9d1e86ad5f 959 ret = wc_HmacSetKey(&verifyHmac, hashType, key, ssl->specs.hash_size);
sPymbed 17:ff9d1e86ad5f 960 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 961 ret = wc_HmacUpdate(&verifyHmac, hash, hashSz);
sPymbed 17:ff9d1e86ad5f 962 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 963 ret = wc_HmacFinal(&verifyHmac, hash);
sPymbed 17:ff9d1e86ad5f 964 wc_HmacFree(&verifyHmac);
sPymbed 17:ff9d1e86ad5f 965 }
sPymbed 17:ff9d1e86ad5f 966
sPymbed 17:ff9d1e86ad5f 967 if (pHashSz)
sPymbed 17:ff9d1e86ad5f 968 *pHashSz = hashSz;
sPymbed 17:ff9d1e86ad5f 969
sPymbed 17:ff9d1e86ad5f 970 return ret;
sPymbed 17:ff9d1e86ad5f 971 }
sPymbed 17:ff9d1e86ad5f 972
sPymbed 17:ff9d1e86ad5f 973 /* The length of the label to use when deriving keys. */
sPymbed 17:ff9d1e86ad5f 974 #define WRITE_KEY_LABEL_SZ 3
sPymbed 17:ff9d1e86ad5f 975 /* The length of the label to use when deriving IVs. */
sPymbed 17:ff9d1e86ad5f 976 #define WRITE_IV_LABEL_SZ 2
sPymbed 17:ff9d1e86ad5f 977 /* The label to use when deriving keys. */
sPymbed 17:ff9d1e86ad5f 978 static const byte writeKeyLabel[WRITE_KEY_LABEL_SZ+1] = "key";
sPymbed 17:ff9d1e86ad5f 979 /* The label to use when deriving IVs. */
sPymbed 17:ff9d1e86ad5f 980 static const byte writeIVLabel[WRITE_IV_LABEL_SZ+1] = "iv";
sPymbed 17:ff9d1e86ad5f 981
sPymbed 17:ff9d1e86ad5f 982 /* Derive the keys and IVs for TLS v1.3.
sPymbed 17:ff9d1e86ad5f 983 *
sPymbed 17:ff9d1e86ad5f 984 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 985 * sercret early_data_key when deriving the key and IV for encrypting early
sPymbed 17:ff9d1e86ad5f 986 * data application data and end_of_early_data messages.
sPymbed 17:ff9d1e86ad5f 987 * handshake_key when deriving keys and IVs for encrypting handshake
sPymbed 17:ff9d1e86ad5f 988 * messages.
sPymbed 17:ff9d1e86ad5f 989 * traffic_key when deriving first keys and IVs for encrypting
sPymbed 17:ff9d1e86ad5f 990 * traffic messages.
sPymbed 17:ff9d1e86ad5f 991 * update_traffic_key when deriving next keys and IVs for encrypting
sPymbed 17:ff9d1e86ad5f 992 * traffic messages.
sPymbed 17:ff9d1e86ad5f 993 * side ENCRYPT_SIDE_ONLY when only encryption secret needs to be derived.
sPymbed 17:ff9d1e86ad5f 994 * DECRYPT_SIDE_ONLY when only decryption secret needs to be derived.
sPymbed 17:ff9d1e86ad5f 995 * ENCRYPT_AND_DECRYPT_SIDE when both secret needs to be derived.
sPymbed 17:ff9d1e86ad5f 996 * store 1 indicates to derive the keys and IVs from derived secret and
sPymbed 17:ff9d1e86ad5f 997 * store ready for provisioning.
sPymbed 17:ff9d1e86ad5f 998 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 999 */
sPymbed 17:ff9d1e86ad5f 1000 static int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store)
sPymbed 17:ff9d1e86ad5f 1001 {
sPymbed 17:ff9d1e86ad5f 1002 int ret = BAD_FUNC_ARG; /* Assume failure */
sPymbed 17:ff9d1e86ad5f 1003 int i = 0;
sPymbed 17:ff9d1e86ad5f 1004 #ifdef WOLFSSL_SMALL_STACK
sPymbed 17:ff9d1e86ad5f 1005 byte* key_dig;
sPymbed 17:ff9d1e86ad5f 1006 #else
sPymbed 17:ff9d1e86ad5f 1007 byte key_dig[MAX_PRF_DIG];
sPymbed 17:ff9d1e86ad5f 1008 #endif
sPymbed 17:ff9d1e86ad5f 1009 int provision;
sPymbed 17:ff9d1e86ad5f 1010
sPymbed 17:ff9d1e86ad5f 1011 #ifdef WOLFSSL_SMALL_STACK
sPymbed 17:ff9d1e86ad5f 1012 key_dig = (byte*)XMALLOC(MAX_PRF_DIG, ssl->heap, DYNAMIC_TYPE_DIGEST);
sPymbed 17:ff9d1e86ad5f 1013 if (key_dig == NULL)
sPymbed 17:ff9d1e86ad5f 1014 return MEMORY_E;
sPymbed 17:ff9d1e86ad5f 1015 #endif
sPymbed 17:ff9d1e86ad5f 1016
sPymbed 17:ff9d1e86ad5f 1017 if (side == ENCRYPT_AND_DECRYPT_SIDE) {
sPymbed 17:ff9d1e86ad5f 1018 provision = PROVISION_CLIENT_SERVER;
sPymbed 17:ff9d1e86ad5f 1019 }
sPymbed 17:ff9d1e86ad5f 1020 else {
sPymbed 17:ff9d1e86ad5f 1021 provision = ((ssl->options.side != WOLFSSL_CLIENT_END) ^
sPymbed 17:ff9d1e86ad5f 1022 (side == ENCRYPT_SIDE_ONLY)) ? PROVISION_CLIENT :
sPymbed 17:ff9d1e86ad5f 1023 PROVISION_SERVER;
sPymbed 17:ff9d1e86ad5f 1024 }
sPymbed 17:ff9d1e86ad5f 1025
sPymbed 17:ff9d1e86ad5f 1026 /* Derive the appropriate secret to use in the HKDF. */
sPymbed 17:ff9d1e86ad5f 1027 switch (secret) {
sPymbed 17:ff9d1e86ad5f 1028 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 1029 case early_data_key:
sPymbed 17:ff9d1e86ad5f 1030 ret = DeriveEarlyTrafficSecret(ssl, ssl->arrays->clientSecret);
sPymbed 17:ff9d1e86ad5f 1031 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1032 goto end;
sPymbed 17:ff9d1e86ad5f 1033 break;
sPymbed 17:ff9d1e86ad5f 1034 #endif
sPymbed 17:ff9d1e86ad5f 1035
sPymbed 17:ff9d1e86ad5f 1036 case handshake_key:
sPymbed 17:ff9d1e86ad5f 1037 if (provision & PROVISION_CLIENT) {
sPymbed 17:ff9d1e86ad5f 1038 ret = DeriveClientHandshakeSecret(ssl,
sPymbed 17:ff9d1e86ad5f 1039 ssl->arrays->clientSecret);
sPymbed 17:ff9d1e86ad5f 1040 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1041 goto end;
sPymbed 17:ff9d1e86ad5f 1042 }
sPymbed 17:ff9d1e86ad5f 1043 if (provision & PROVISION_SERVER) {
sPymbed 17:ff9d1e86ad5f 1044 ret = DeriveServerHandshakeSecret(ssl,
sPymbed 17:ff9d1e86ad5f 1045 ssl->arrays->serverSecret);
sPymbed 17:ff9d1e86ad5f 1046 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1047 goto end;
sPymbed 17:ff9d1e86ad5f 1048 }
sPymbed 17:ff9d1e86ad5f 1049 break;
sPymbed 17:ff9d1e86ad5f 1050
sPymbed 17:ff9d1e86ad5f 1051 case traffic_key:
sPymbed 17:ff9d1e86ad5f 1052 if (provision & PROVISION_CLIENT) {
sPymbed 17:ff9d1e86ad5f 1053 ret = DeriveClientTrafficSecret(ssl, ssl->arrays->clientSecret);
sPymbed 17:ff9d1e86ad5f 1054 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1055 goto end;
sPymbed 17:ff9d1e86ad5f 1056 }
sPymbed 17:ff9d1e86ad5f 1057 if (provision & PROVISION_SERVER) {
sPymbed 17:ff9d1e86ad5f 1058 ret = DeriveServerTrafficSecret(ssl, ssl->arrays->serverSecret);
sPymbed 17:ff9d1e86ad5f 1059 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1060 goto end;
sPymbed 17:ff9d1e86ad5f 1061 }
sPymbed 17:ff9d1e86ad5f 1062 break;
sPymbed 17:ff9d1e86ad5f 1063
sPymbed 17:ff9d1e86ad5f 1064 case update_traffic_key:
sPymbed 17:ff9d1e86ad5f 1065 if (provision & PROVISION_CLIENT) {
sPymbed 17:ff9d1e86ad5f 1066 ret = DeriveTrafficSecret(ssl, ssl->arrays->clientSecret);
sPymbed 17:ff9d1e86ad5f 1067 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1068 goto end;
sPymbed 17:ff9d1e86ad5f 1069 }
sPymbed 17:ff9d1e86ad5f 1070 if (provision & PROVISION_SERVER) {
sPymbed 17:ff9d1e86ad5f 1071 ret = DeriveTrafficSecret(ssl, ssl->arrays->serverSecret);
sPymbed 17:ff9d1e86ad5f 1072 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1073 goto end;
sPymbed 17:ff9d1e86ad5f 1074 }
sPymbed 17:ff9d1e86ad5f 1075 break;
sPymbed 17:ff9d1e86ad5f 1076 }
sPymbed 17:ff9d1e86ad5f 1077
sPymbed 17:ff9d1e86ad5f 1078 if (!store)
sPymbed 17:ff9d1e86ad5f 1079 goto end;
sPymbed 17:ff9d1e86ad5f 1080
sPymbed 17:ff9d1e86ad5f 1081 /* Key data = client key | server key | client IV | server IV */
sPymbed 17:ff9d1e86ad5f 1082
sPymbed 17:ff9d1e86ad5f 1083 if (provision & PROVISION_CLIENT) {
sPymbed 17:ff9d1e86ad5f 1084 /* Derive the client key. */
sPymbed 17:ff9d1e86ad5f 1085 WOLFSSL_MSG("Derive Client Key");
sPymbed 17:ff9d1e86ad5f 1086 ret = DeriveKey(ssl, &key_dig[i], ssl->specs.key_size,
sPymbed 17:ff9d1e86ad5f 1087 ssl->arrays->clientSecret, writeKeyLabel,
sPymbed 17:ff9d1e86ad5f 1088 WRITE_KEY_LABEL_SZ, ssl->specs.mac_algorithm, 0);
sPymbed 17:ff9d1e86ad5f 1089 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1090 goto end;
sPymbed 17:ff9d1e86ad5f 1091 i += ssl->specs.key_size;
sPymbed 17:ff9d1e86ad5f 1092 }
sPymbed 17:ff9d1e86ad5f 1093
sPymbed 17:ff9d1e86ad5f 1094 if (provision & PROVISION_SERVER) {
sPymbed 17:ff9d1e86ad5f 1095 /* Derive the server key. */
sPymbed 17:ff9d1e86ad5f 1096 WOLFSSL_MSG("Derive Server Key");
sPymbed 17:ff9d1e86ad5f 1097 ret = DeriveKey(ssl, &key_dig[i], ssl->specs.key_size,
sPymbed 17:ff9d1e86ad5f 1098 ssl->arrays->serverSecret, writeKeyLabel,
sPymbed 17:ff9d1e86ad5f 1099 WRITE_KEY_LABEL_SZ, ssl->specs.mac_algorithm, 0);
sPymbed 17:ff9d1e86ad5f 1100 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1101 goto end;
sPymbed 17:ff9d1e86ad5f 1102 i += ssl->specs.key_size;
sPymbed 17:ff9d1e86ad5f 1103 }
sPymbed 17:ff9d1e86ad5f 1104
sPymbed 17:ff9d1e86ad5f 1105 if (provision & PROVISION_CLIENT) {
sPymbed 17:ff9d1e86ad5f 1106 /* Derive the client IV. */
sPymbed 17:ff9d1e86ad5f 1107 WOLFSSL_MSG("Derive Client IV");
sPymbed 17:ff9d1e86ad5f 1108 ret = DeriveKey(ssl, &key_dig[i], ssl->specs.iv_size,
sPymbed 17:ff9d1e86ad5f 1109 ssl->arrays->clientSecret, writeIVLabel,
sPymbed 17:ff9d1e86ad5f 1110 WRITE_IV_LABEL_SZ, ssl->specs.mac_algorithm, 0);
sPymbed 17:ff9d1e86ad5f 1111 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1112 goto end;
sPymbed 17:ff9d1e86ad5f 1113 i += ssl->specs.iv_size;
sPymbed 17:ff9d1e86ad5f 1114 }
sPymbed 17:ff9d1e86ad5f 1115
sPymbed 17:ff9d1e86ad5f 1116 if (provision & PROVISION_SERVER) {
sPymbed 17:ff9d1e86ad5f 1117 /* Derive the server IV. */
sPymbed 17:ff9d1e86ad5f 1118 WOLFSSL_MSG("Derive Server IV");
sPymbed 17:ff9d1e86ad5f 1119 ret = DeriveKey(ssl, &key_dig[i], ssl->specs.iv_size,
sPymbed 17:ff9d1e86ad5f 1120 ssl->arrays->serverSecret, writeIVLabel,
sPymbed 17:ff9d1e86ad5f 1121 WRITE_IV_LABEL_SZ, ssl->specs.mac_algorithm, 0);
sPymbed 17:ff9d1e86ad5f 1122 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1123 goto end;
sPymbed 17:ff9d1e86ad5f 1124 }
sPymbed 17:ff9d1e86ad5f 1125
sPymbed 17:ff9d1e86ad5f 1126 /* Store keys and IVs but don't activate them. */
sPymbed 17:ff9d1e86ad5f 1127 ret = StoreKeys(ssl, key_dig, provision);
sPymbed 17:ff9d1e86ad5f 1128
sPymbed 17:ff9d1e86ad5f 1129 end:
sPymbed 17:ff9d1e86ad5f 1130 #ifdef WOLFSSL_SMALL_STACK
sPymbed 17:ff9d1e86ad5f 1131 XFREE(key_dig, ssl->heap, DYNAMIC_TYPE_DIGEST);
sPymbed 17:ff9d1e86ad5f 1132 #endif
sPymbed 17:ff9d1e86ad5f 1133
sPymbed 17:ff9d1e86ad5f 1134 return ret;
sPymbed 17:ff9d1e86ad5f 1135 }
sPymbed 17:ff9d1e86ad5f 1136
sPymbed 17:ff9d1e86ad5f 1137 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 1138 #if defined(USER_TICKS)
sPymbed 17:ff9d1e86ad5f 1139 #if 0
sPymbed 17:ff9d1e86ad5f 1140 word32 TimeNowInMilliseconds(void)
sPymbed 17:ff9d1e86ad5f 1141 {
sPymbed 17:ff9d1e86ad5f 1142 /*
sPymbed 17:ff9d1e86ad5f 1143 write your own clock tick function if don't want gettimeofday()
sPymbed 17:ff9d1e86ad5f 1144 needs millisecond accuracy but doesn't have to correlated to EPOCH
sPymbed 17:ff9d1e86ad5f 1145 */
sPymbed 17:ff9d1e86ad5f 1146 }
sPymbed 17:ff9d1e86ad5f 1147 #endif
sPymbed 17:ff9d1e86ad5f 1148
sPymbed 17:ff9d1e86ad5f 1149 #elif defined(TIME_OVERRIDES)
sPymbed 17:ff9d1e86ad5f 1150 #ifndef HAVE_TIME_T_TYPE
sPymbed 17:ff9d1e86ad5f 1151 typedef long time_t;
sPymbed 17:ff9d1e86ad5f 1152 #endif
sPymbed 17:ff9d1e86ad5f 1153 extern time_t XTIME(time_t * timer);
sPymbed 17:ff9d1e86ad5f 1154
sPymbed 17:ff9d1e86ad5f 1155 /* The time in milliseconds.
sPymbed 17:ff9d1e86ad5f 1156 * Used for tickets to represent difference between when first seen and when
sPymbed 17:ff9d1e86ad5f 1157 * sending.
sPymbed 17:ff9d1e86ad5f 1158 *
sPymbed 17:ff9d1e86ad5f 1159 * returns the time in milliseconds as a 32-bit value.
sPymbed 17:ff9d1e86ad5f 1160 */
sPymbed 17:ff9d1e86ad5f 1161 word32 TimeNowInMilliseconds(void)
sPymbed 17:ff9d1e86ad5f 1162 {
sPymbed 17:ff9d1e86ad5f 1163 return (word32) XTIME(0) * 1000;
sPymbed 17:ff9d1e86ad5f 1164 }
sPymbed 17:ff9d1e86ad5f 1165 #elif defined(USE_WINDOWS_API)
sPymbed 17:ff9d1e86ad5f 1166 /* The time in milliseconds.
sPymbed 17:ff9d1e86ad5f 1167 * Used for tickets to represent difference between when first seen and when
sPymbed 17:ff9d1e86ad5f 1168 * sending.
sPymbed 17:ff9d1e86ad5f 1169 *
sPymbed 17:ff9d1e86ad5f 1170 * returns the time in milliseconds as a 32-bit value.
sPymbed 17:ff9d1e86ad5f 1171 */
sPymbed 17:ff9d1e86ad5f 1172 word32 TimeNowInMilliseconds(void)
sPymbed 17:ff9d1e86ad5f 1173 {
sPymbed 17:ff9d1e86ad5f 1174 static int init = 0;
sPymbed 17:ff9d1e86ad5f 1175 static LARGE_INTEGER freq;
sPymbed 17:ff9d1e86ad5f 1176 LARGE_INTEGER count;
sPymbed 17:ff9d1e86ad5f 1177
sPymbed 17:ff9d1e86ad5f 1178 if (!init) {
sPymbed 17:ff9d1e86ad5f 1179 QueryPerformanceFrequency(&freq);
sPymbed 17:ff9d1e86ad5f 1180 init = 1;
sPymbed 17:ff9d1e86ad5f 1181 }
sPymbed 17:ff9d1e86ad5f 1182
sPymbed 17:ff9d1e86ad5f 1183 QueryPerformanceCounter(&count);
sPymbed 17:ff9d1e86ad5f 1184
sPymbed 17:ff9d1e86ad5f 1185 return (word32)(count.QuadPart / (freq.QuadPart / 1000));
sPymbed 17:ff9d1e86ad5f 1186 }
sPymbed 17:ff9d1e86ad5f 1187
sPymbed 17:ff9d1e86ad5f 1188 #elif defined(HAVE_RTP_SYS)
sPymbed 17:ff9d1e86ad5f 1189 #include "rtptime.h"
sPymbed 17:ff9d1e86ad5f 1190
sPymbed 17:ff9d1e86ad5f 1191 /* The time in milliseconds.
sPymbed 17:ff9d1e86ad5f 1192 * Used for tickets to represent difference between when first seen and when
sPymbed 17:ff9d1e86ad5f 1193 * sending.
sPymbed 17:ff9d1e86ad5f 1194 *
sPymbed 17:ff9d1e86ad5f 1195 * returns the time in milliseconds as a 32-bit value.
sPymbed 17:ff9d1e86ad5f 1196 */
sPymbed 17:ff9d1e86ad5f 1197 word32 TimeNowInMilliseconds(void)
sPymbed 17:ff9d1e86ad5f 1198 {
sPymbed 17:ff9d1e86ad5f 1199 return (word32)rtp_get_system_sec() * 1000;
sPymbed 17:ff9d1e86ad5f 1200 }
sPymbed 17:ff9d1e86ad5f 1201 #elif defined(MICRIUM)
sPymbed 17:ff9d1e86ad5f 1202 /* The time in milliseconds.
sPymbed 17:ff9d1e86ad5f 1203 * Used for tickets to represent difference between when first seen and when
sPymbed 17:ff9d1e86ad5f 1204 * sending.
sPymbed 17:ff9d1e86ad5f 1205 *
sPymbed 17:ff9d1e86ad5f 1206 * returns the time in milliseconds as a 32-bit value.
sPymbed 17:ff9d1e86ad5f 1207 */
sPymbed 17:ff9d1e86ad5f 1208 word32 TimeNowInMilliseconds(void)
sPymbed 17:ff9d1e86ad5f 1209 {
sPymbed 17:ff9d1e86ad5f 1210 OS_TICK ticks = 0;
sPymbed 17:ff9d1e86ad5f 1211 OS_ERR err;
sPymbed 17:ff9d1e86ad5f 1212
sPymbed 17:ff9d1e86ad5f 1213 ticks = OSTimeGet(&err);
sPymbed 17:ff9d1e86ad5f 1214
sPymbed 17:ff9d1e86ad5f 1215 return (word32) (ticks / OSCfg_TickRate_Hz) * 1000;
sPymbed 17:ff9d1e86ad5f 1216 }
sPymbed 17:ff9d1e86ad5f 1217 #elif defined(MICROCHIP_TCPIP_V5)
sPymbed 17:ff9d1e86ad5f 1218 /* The time in milliseconds.
sPymbed 17:ff9d1e86ad5f 1219 * Used for tickets to represent difference between when first seen and when
sPymbed 17:ff9d1e86ad5f 1220 * sending.
sPymbed 17:ff9d1e86ad5f 1221 *
sPymbed 17:ff9d1e86ad5f 1222 * returns the time in milliseconds as a 32-bit value.
sPymbed 17:ff9d1e86ad5f 1223 */
sPymbed 17:ff9d1e86ad5f 1224 word32 TimeNowInMilliseconds(void)
sPymbed 17:ff9d1e86ad5f 1225 {
sPymbed 17:ff9d1e86ad5f 1226 return (word32) (TickGet() / (TICKS_PER_SECOND / 1000));
sPymbed 17:ff9d1e86ad5f 1227 }
sPymbed 17:ff9d1e86ad5f 1228 #elif defined(MICROCHIP_TCPIP)
sPymbed 17:ff9d1e86ad5f 1229 #if defined(MICROCHIP_MPLAB_HARMONY)
sPymbed 17:ff9d1e86ad5f 1230 #include <system/tmr/sys_tmr.h>
sPymbed 17:ff9d1e86ad5f 1231
sPymbed 17:ff9d1e86ad5f 1232 /* The time in milliseconds.
sPymbed 17:ff9d1e86ad5f 1233 * Used for tickets to represent difference between when first seen and when
sPymbed 17:ff9d1e86ad5f 1234 * sending.
sPymbed 17:ff9d1e86ad5f 1235 *
sPymbed 17:ff9d1e86ad5f 1236 * returns the time in milliseconds as a 32-bit value.
sPymbed 17:ff9d1e86ad5f 1237 */
sPymbed 17:ff9d1e86ad5f 1238 word32 TimeNowInMilliseconds(void)
sPymbed 17:ff9d1e86ad5f 1239 {
sPymbed 17:ff9d1e86ad5f 1240 return (word32)(SYS_TMR_TickCountGet() /
sPymbed 17:ff9d1e86ad5f 1241 (SYS_TMR_TickCounterFrequencyGet() / 1000));
sPymbed 17:ff9d1e86ad5f 1242 }
sPymbed 17:ff9d1e86ad5f 1243 #else
sPymbed 17:ff9d1e86ad5f 1244 /* The time in milliseconds.
sPymbed 17:ff9d1e86ad5f 1245 * Used for tickets to represent difference between when first seen and when
sPymbed 17:ff9d1e86ad5f 1246 * sending.
sPymbed 17:ff9d1e86ad5f 1247 *
sPymbed 17:ff9d1e86ad5f 1248 * returns the time in milliseconds as a 32-bit value.
sPymbed 17:ff9d1e86ad5f 1249 */
sPymbed 17:ff9d1e86ad5f 1250 word32 TimeNowInMilliseconds(void)
sPymbed 17:ff9d1e86ad5f 1251 {
sPymbed 17:ff9d1e86ad5f 1252 return (word32)(SYS_TICK_Get() / (SYS_TICK_TicksPerSecondGet() / 1000));
sPymbed 17:ff9d1e86ad5f 1253 }
sPymbed 17:ff9d1e86ad5f 1254
sPymbed 17:ff9d1e86ad5f 1255 #endif
sPymbed 17:ff9d1e86ad5f 1256
sPymbed 17:ff9d1e86ad5f 1257 #elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
sPymbed 17:ff9d1e86ad5f 1258 /* The time in milliseconds.
sPymbed 17:ff9d1e86ad5f 1259 * Used for tickets to represent difference between when first seen and when
sPymbed 17:ff9d1e86ad5f 1260 * sending.
sPymbed 17:ff9d1e86ad5f 1261 *
sPymbed 17:ff9d1e86ad5f 1262 * returns the time in milliseconds as a 32-bit value.
sPymbed 17:ff9d1e86ad5f 1263 */
sPymbed 17:ff9d1e86ad5f 1264 word32 TimeNowInMilliseconds(void)
sPymbed 17:ff9d1e86ad5f 1265 {
sPymbed 17:ff9d1e86ad5f 1266 TIME_STRUCT mqxTime;
sPymbed 17:ff9d1e86ad5f 1267
sPymbed 17:ff9d1e86ad5f 1268 _time_get_elapsed(&mqxTime);
sPymbed 17:ff9d1e86ad5f 1269
sPymbed 17:ff9d1e86ad5f 1270 return (word32) mqxTime.SECONDS * 1000;
sPymbed 17:ff9d1e86ad5f 1271 }
sPymbed 17:ff9d1e86ad5f 1272 #elif defined(FREESCALE_FREE_RTOS) || defined(FREESCALE_KSDK_FREERTOS)
sPymbed 17:ff9d1e86ad5f 1273 #include "include/task.h"
sPymbed 17:ff9d1e86ad5f 1274
sPymbed 17:ff9d1e86ad5f 1275 /* The time in milliseconds.
sPymbed 17:ff9d1e86ad5f 1276 * Used for tickets to represent difference between when first seen and when
sPymbed 17:ff9d1e86ad5f 1277 * sending.
sPymbed 17:ff9d1e86ad5f 1278 *
sPymbed 17:ff9d1e86ad5f 1279 * returns the time in milliseconds as a 32-bit value.
sPymbed 17:ff9d1e86ad5f 1280 */
sPymbed 17:ff9d1e86ad5f 1281 word32 TimeNowInMilliseconds(void)
sPymbed 17:ff9d1e86ad5f 1282 {
sPymbed 17:ff9d1e86ad5f 1283 return (unsigned int)(((float)xTaskGetTickCount()) /
sPymbed 17:ff9d1e86ad5f 1284 (configTICK_RATE_HZ / 1000));
sPymbed 17:ff9d1e86ad5f 1285 }
sPymbed 17:ff9d1e86ad5f 1286 #elif defined(FREESCALE_KSDK_BM)
sPymbed 17:ff9d1e86ad5f 1287 #include "lwip/sys.h" /* lwIP */
sPymbed 17:ff9d1e86ad5f 1288
sPymbed 17:ff9d1e86ad5f 1289 /* The time in milliseconds.
sPymbed 17:ff9d1e86ad5f 1290 * Used for tickets to represent difference between when first seen and when
sPymbed 17:ff9d1e86ad5f 1291 * sending.
sPymbed 17:ff9d1e86ad5f 1292 *
sPymbed 17:ff9d1e86ad5f 1293 * returns the time in milliseconds as a 32-bit value.
sPymbed 17:ff9d1e86ad5f 1294 */
sPymbed 17:ff9d1e86ad5f 1295 word32 TimeNowInMilliseconds(void)
sPymbed 17:ff9d1e86ad5f 1296 {
sPymbed 17:ff9d1e86ad5f 1297 return sys_now();
sPymbed 17:ff9d1e86ad5f 1298 }
sPymbed 17:ff9d1e86ad5f 1299 #elif defined(WOLFSSL_TIRTOS)
sPymbed 17:ff9d1e86ad5f 1300 /* The time in milliseconds.
sPymbed 17:ff9d1e86ad5f 1301 * Used for tickets to represent difference between when first seen and when
sPymbed 17:ff9d1e86ad5f 1302 * sending.
sPymbed 17:ff9d1e86ad5f 1303 *
sPymbed 17:ff9d1e86ad5f 1304 * returns the time in milliseconds as a 32-bit value.
sPymbed 17:ff9d1e86ad5f 1305 */
sPymbed 17:ff9d1e86ad5f 1306 word32 TimeNowInMilliseconds(void)
sPymbed 17:ff9d1e86ad5f 1307 {
sPymbed 17:ff9d1e86ad5f 1308 return (word32) Seconds_get() * 1000;
sPymbed 17:ff9d1e86ad5f 1309 }
sPymbed 17:ff9d1e86ad5f 1310 #elif defined(WOLFSSL_UTASKER)
sPymbed 17:ff9d1e86ad5f 1311 /* The time in milliseconds.
sPymbed 17:ff9d1e86ad5f 1312 * Used for tickets to represent difference between when first seen and when
sPymbed 17:ff9d1e86ad5f 1313 * sending.
sPymbed 17:ff9d1e86ad5f 1314 *
sPymbed 17:ff9d1e86ad5f 1315 * returns the time in milliseconds as a 32-bit value.
sPymbed 17:ff9d1e86ad5f 1316 */
sPymbed 17:ff9d1e86ad5f 1317 word32 TimeNowInMilliseconds(void)
sPymbed 17:ff9d1e86ad5f 1318 {
sPymbed 17:ff9d1e86ad5f 1319 return (word32)(uTaskerSystemTick / (TICK_RESOLUTION / 1000));
sPymbed 17:ff9d1e86ad5f 1320 }
sPymbed 17:ff9d1e86ad5f 1321 #else
sPymbed 17:ff9d1e86ad5f 1322 /* The time in milliseconds.
sPymbed 17:ff9d1e86ad5f 1323 * Used for tickets to represent difference between when first seen and when
sPymbed 17:ff9d1e86ad5f 1324 * sending.
sPymbed 17:ff9d1e86ad5f 1325 *
sPymbed 17:ff9d1e86ad5f 1326 * returns the time in milliseconds as a 32-bit value.
sPymbed 17:ff9d1e86ad5f 1327 */
sPymbed 17:ff9d1e86ad5f 1328 word32 TimeNowInMilliseconds(void)
sPymbed 17:ff9d1e86ad5f 1329 {
sPymbed 17:ff9d1e86ad5f 1330 struct timeval now;
sPymbed 17:ff9d1e86ad5f 1331
sPymbed 17:ff9d1e86ad5f 1332 if (gettimeofday(&now, 0) < 0)
sPymbed 17:ff9d1e86ad5f 1333 return GETTIME_ERROR;
sPymbed 17:ff9d1e86ad5f 1334 /* Convert to milliseconds number. */
sPymbed 17:ff9d1e86ad5f 1335 return (word32)(now.tv_sec * 1000 + now.tv_usec / 1000);
sPymbed 17:ff9d1e86ad5f 1336 }
sPymbed 17:ff9d1e86ad5f 1337 #endif
sPymbed 17:ff9d1e86ad5f 1338 #endif /* HAVE_SESSION_TICKET || !NO_PSK */
sPymbed 17:ff9d1e86ad5f 1339
sPymbed 17:ff9d1e86ad5f 1340
sPymbed 17:ff9d1e86ad5f 1341 #if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_SESSION_TICKET) || \
sPymbed 17:ff9d1e86ad5f 1342 !defined(NO_PSK))
sPymbed 17:ff9d1e86ad5f 1343 /* Add input to all handshake hashes.
sPymbed 17:ff9d1e86ad5f 1344 *
sPymbed 17:ff9d1e86ad5f 1345 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 1346 * input The data to hash.
sPymbed 17:ff9d1e86ad5f 1347 * sz The size of the data to hash.
sPymbed 17:ff9d1e86ad5f 1348 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 1349 */
sPymbed 17:ff9d1e86ad5f 1350 static int HashInputRaw(WOLFSSL* ssl, const byte* input, int sz)
sPymbed 17:ff9d1e86ad5f 1351 {
sPymbed 17:ff9d1e86ad5f 1352 int ret = BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 1353
sPymbed 17:ff9d1e86ad5f 1354 #ifndef NO_SHA256
sPymbed 17:ff9d1e86ad5f 1355 ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, input, sz);
sPymbed 17:ff9d1e86ad5f 1356 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1357 return ret;
sPymbed 17:ff9d1e86ad5f 1358 #endif
sPymbed 17:ff9d1e86ad5f 1359 #ifdef WOLFSSL_SHA384
sPymbed 17:ff9d1e86ad5f 1360 ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, input, sz);
sPymbed 17:ff9d1e86ad5f 1361 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1362 return ret;
sPymbed 17:ff9d1e86ad5f 1363 #endif
sPymbed 17:ff9d1e86ad5f 1364 #ifdef WOLFSSL_TLS13_SHA512
sPymbed 17:ff9d1e86ad5f 1365 ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, input, sz);
sPymbed 17:ff9d1e86ad5f 1366 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1367 return ret;
sPymbed 17:ff9d1e86ad5f 1368 #endif
sPymbed 17:ff9d1e86ad5f 1369
sPymbed 17:ff9d1e86ad5f 1370 return ret;
sPymbed 17:ff9d1e86ad5f 1371 }
sPymbed 17:ff9d1e86ad5f 1372 #endif
sPymbed 17:ff9d1e86ad5f 1373
sPymbed 17:ff9d1e86ad5f 1374 /* Extract the handshake header information.
sPymbed 17:ff9d1e86ad5f 1375 *
sPymbed 17:ff9d1e86ad5f 1376 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 1377 * input The buffer holding the message data.
sPymbed 17:ff9d1e86ad5f 1378 * inOutIdx On entry, the index into the buffer of the handshake data.
sPymbed 17:ff9d1e86ad5f 1379 * On exit, the start of the hanshake data.
sPymbed 17:ff9d1e86ad5f 1380 * type Type of handshake message.
sPymbed 17:ff9d1e86ad5f 1381 * size The length of the handshake message data.
sPymbed 17:ff9d1e86ad5f 1382 * totalSz The total size of data in the buffer.
sPymbed 17:ff9d1e86ad5f 1383 * returns BUFFER_E if there is not enough input data and 0 on success.
sPymbed 17:ff9d1e86ad5f 1384 */
sPymbed 17:ff9d1e86ad5f 1385 static int GetHandshakeHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
sPymbed 17:ff9d1e86ad5f 1386 byte* type, word32* size, word32 totalSz)
sPymbed 17:ff9d1e86ad5f 1387 {
sPymbed 17:ff9d1e86ad5f 1388 const byte* ptr = input + *inOutIdx;
sPymbed 17:ff9d1e86ad5f 1389 (void)ssl;
sPymbed 17:ff9d1e86ad5f 1390
sPymbed 17:ff9d1e86ad5f 1391 *inOutIdx += HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 1392 if (*inOutIdx > totalSz)
sPymbed 17:ff9d1e86ad5f 1393 return BUFFER_E;
sPymbed 17:ff9d1e86ad5f 1394
sPymbed 17:ff9d1e86ad5f 1395 *type = ptr[0];
sPymbed 17:ff9d1e86ad5f 1396 c24to32(&ptr[1], size);
sPymbed 17:ff9d1e86ad5f 1397
sPymbed 17:ff9d1e86ad5f 1398 return 0;
sPymbed 17:ff9d1e86ad5f 1399 }
sPymbed 17:ff9d1e86ad5f 1400
sPymbed 17:ff9d1e86ad5f 1401 /* Add record layer header to message.
sPymbed 17:ff9d1e86ad5f 1402 *
sPymbed 17:ff9d1e86ad5f 1403 * output The buffer to write the record layer header into.
sPymbed 17:ff9d1e86ad5f 1404 * length The length of the record data.
sPymbed 17:ff9d1e86ad5f 1405 * type The type of record message.
sPymbed 17:ff9d1e86ad5f 1406 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 1407 */
sPymbed 17:ff9d1e86ad5f 1408 static void AddTls13RecordHeader(byte* output, word32 length, byte type,
sPymbed 17:ff9d1e86ad5f 1409 WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 1410 {
sPymbed 17:ff9d1e86ad5f 1411 RecordLayerHeader* rl;
sPymbed 17:ff9d1e86ad5f 1412
sPymbed 17:ff9d1e86ad5f 1413 rl = (RecordLayerHeader*)output;
sPymbed 17:ff9d1e86ad5f 1414 rl->type = type;
sPymbed 17:ff9d1e86ad5f 1415 rl->pvMajor = ssl->version.major;
sPymbed 17:ff9d1e86ad5f 1416 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 1417 rl->pvMinor = TLSv1_MINOR;
sPymbed 17:ff9d1e86ad5f 1418 #else
sPymbed 17:ff9d1e86ad5f 1419 rl->pvMinor = TLSv1_2_MINOR;
sPymbed 17:ff9d1e86ad5f 1420 #endif
sPymbed 17:ff9d1e86ad5f 1421 c16toa((word16)length, rl->length);
sPymbed 17:ff9d1e86ad5f 1422 }
sPymbed 17:ff9d1e86ad5f 1423
sPymbed 17:ff9d1e86ad5f 1424 /* Add handshake header to message.
sPymbed 17:ff9d1e86ad5f 1425 *
sPymbed 17:ff9d1e86ad5f 1426 * output The buffer to write the hanshake header into.
sPymbed 17:ff9d1e86ad5f 1427 * length The length of the handshake data.
sPymbed 17:ff9d1e86ad5f 1428 * fragOffset The offset of the fragment data. (DTLS)
sPymbed 17:ff9d1e86ad5f 1429 * fragLength The length of the fragment data. (DTLS)
sPymbed 17:ff9d1e86ad5f 1430 * type The type of handshake message.
sPymbed 17:ff9d1e86ad5f 1431 * ssl The SSL/TLS object. (DTLS)
sPymbed 17:ff9d1e86ad5f 1432 */
sPymbed 17:ff9d1e86ad5f 1433 static void AddTls13HandShakeHeader(byte* output, word32 length,
sPymbed 17:ff9d1e86ad5f 1434 word32 fragOffset, word32 fragLength,
sPymbed 17:ff9d1e86ad5f 1435 byte type, WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 1436 {
sPymbed 17:ff9d1e86ad5f 1437 HandShakeHeader* hs;
sPymbed 17:ff9d1e86ad5f 1438 (void)fragOffset;
sPymbed 17:ff9d1e86ad5f 1439 (void)fragLength;
sPymbed 17:ff9d1e86ad5f 1440 (void)ssl;
sPymbed 17:ff9d1e86ad5f 1441
sPymbed 17:ff9d1e86ad5f 1442 /* handshake header */
sPymbed 17:ff9d1e86ad5f 1443 hs = (HandShakeHeader*)output;
sPymbed 17:ff9d1e86ad5f 1444 hs->type = type;
sPymbed 17:ff9d1e86ad5f 1445 c32to24(length, hs->length);
sPymbed 17:ff9d1e86ad5f 1446 }
sPymbed 17:ff9d1e86ad5f 1447
sPymbed 17:ff9d1e86ad5f 1448
sPymbed 17:ff9d1e86ad5f 1449 /* Add both record layer and handshake header to message.
sPymbed 17:ff9d1e86ad5f 1450 *
sPymbed 17:ff9d1e86ad5f 1451 * output The buffer to write the headers into.
sPymbed 17:ff9d1e86ad5f 1452 * length The length of the handshake data.
sPymbed 17:ff9d1e86ad5f 1453 * type The type of record layer message.
sPymbed 17:ff9d1e86ad5f 1454 * ssl The SSL/TLS object. (DTLS)
sPymbed 17:ff9d1e86ad5f 1455 */
sPymbed 17:ff9d1e86ad5f 1456 static void AddTls13Headers(byte* output, word32 length, byte type,
sPymbed 17:ff9d1e86ad5f 1457 WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 1458 {
sPymbed 17:ff9d1e86ad5f 1459 word32 lengthAdj = HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 1460 word32 outputAdj = RECORD_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 1461
sPymbed 17:ff9d1e86ad5f 1462 AddTls13RecordHeader(output, length + lengthAdj, handshake, ssl);
sPymbed 17:ff9d1e86ad5f 1463 AddTls13HandShakeHeader(output + outputAdj, length, 0, length, type, ssl);
sPymbed 17:ff9d1e86ad5f 1464 }
sPymbed 17:ff9d1e86ad5f 1465
sPymbed 17:ff9d1e86ad5f 1466
sPymbed 17:ff9d1e86ad5f 1467 #ifndef NO_CERTS
sPymbed 17:ff9d1e86ad5f 1468 /* Add both record layer and fragement handshake header to message.
sPymbed 17:ff9d1e86ad5f 1469 *
sPymbed 17:ff9d1e86ad5f 1470 * output The buffer to write the headers into.
sPymbed 17:ff9d1e86ad5f 1471 * fragOffset The offset of the fragment data. (DTLS)
sPymbed 17:ff9d1e86ad5f 1472 * fragLength The length of the fragment data. (DTLS)
sPymbed 17:ff9d1e86ad5f 1473 * length The length of the handshake data.
sPymbed 17:ff9d1e86ad5f 1474 * type The type of record layer message.
sPymbed 17:ff9d1e86ad5f 1475 * ssl The SSL/TLS object. (DTLS)
sPymbed 17:ff9d1e86ad5f 1476 */
sPymbed 17:ff9d1e86ad5f 1477 static void AddTls13FragHeaders(byte* output, word32 fragSz, word32 fragOffset,
sPymbed 17:ff9d1e86ad5f 1478 word32 length, byte type, WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 1479 {
sPymbed 17:ff9d1e86ad5f 1480 word32 lengthAdj = HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 1481 word32 outputAdj = RECORD_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 1482 (void)fragSz;
sPymbed 17:ff9d1e86ad5f 1483
sPymbed 17:ff9d1e86ad5f 1484 AddTls13RecordHeader(output, fragSz + lengthAdj, handshake, ssl);
sPymbed 17:ff9d1e86ad5f 1485 AddTls13HandShakeHeader(output + outputAdj, length, fragOffset, fragSz,
sPymbed 17:ff9d1e86ad5f 1486 type, ssl);
sPymbed 17:ff9d1e86ad5f 1487 }
sPymbed 17:ff9d1e86ad5f 1488 #endif /* NO_CERTS */
sPymbed 17:ff9d1e86ad5f 1489
sPymbed 17:ff9d1e86ad5f 1490 /* Write the sequence number into the buffer.
sPymbed 17:ff9d1e86ad5f 1491 * No DTLS v1.3 support.
sPymbed 17:ff9d1e86ad5f 1492 *
sPymbed 17:ff9d1e86ad5f 1493 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 1494 * verifyOrder Which set of sequence numbers to use.
sPymbed 17:ff9d1e86ad5f 1495 * out The buffer to write into.
sPymbed 17:ff9d1e86ad5f 1496 */
sPymbed 17:ff9d1e86ad5f 1497 static WC_INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out)
sPymbed 17:ff9d1e86ad5f 1498 {
sPymbed 17:ff9d1e86ad5f 1499 word32 seq[2] = {0, 0};
sPymbed 17:ff9d1e86ad5f 1500
sPymbed 17:ff9d1e86ad5f 1501 if (verifyOrder) {
sPymbed 17:ff9d1e86ad5f 1502 seq[0] = ssl->keys.peer_sequence_number_hi;
sPymbed 17:ff9d1e86ad5f 1503 seq[1] = ssl->keys.peer_sequence_number_lo++;
sPymbed 17:ff9d1e86ad5f 1504 /* handle rollover */
sPymbed 17:ff9d1e86ad5f 1505 if (seq[1] > ssl->keys.peer_sequence_number_lo)
sPymbed 17:ff9d1e86ad5f 1506 ssl->keys.peer_sequence_number_hi++;
sPymbed 17:ff9d1e86ad5f 1507 }
sPymbed 17:ff9d1e86ad5f 1508 else {
sPymbed 17:ff9d1e86ad5f 1509 seq[0] = ssl->keys.sequence_number_hi;
sPymbed 17:ff9d1e86ad5f 1510 seq[1] = ssl->keys.sequence_number_lo++;
sPymbed 17:ff9d1e86ad5f 1511 /* handle rollover */
sPymbed 17:ff9d1e86ad5f 1512 if (seq[1] > ssl->keys.sequence_number_lo)
sPymbed 17:ff9d1e86ad5f 1513 ssl->keys.sequence_number_hi++;
sPymbed 17:ff9d1e86ad5f 1514 }
sPymbed 17:ff9d1e86ad5f 1515
sPymbed 17:ff9d1e86ad5f 1516 c32toa(seq[0], out);
sPymbed 17:ff9d1e86ad5f 1517 c32toa(seq[1], out + OPAQUE32_LEN);
sPymbed 17:ff9d1e86ad5f 1518 }
sPymbed 17:ff9d1e86ad5f 1519
sPymbed 17:ff9d1e86ad5f 1520 /* Build the nonce for TLS v1.3 encryption and decryption.
sPymbed 17:ff9d1e86ad5f 1521 *
sPymbed 17:ff9d1e86ad5f 1522 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 1523 * nonce The nonce data to use when encrypting or decrypting.
sPymbed 17:ff9d1e86ad5f 1524 * iv The derived IV.
sPymbed 17:ff9d1e86ad5f 1525 * order The side on which the message is to be or was sent.
sPymbed 17:ff9d1e86ad5f 1526 */
sPymbed 17:ff9d1e86ad5f 1527 static WC_INLINE void BuildTls13Nonce(WOLFSSL* ssl, byte* nonce, const byte* iv,
sPymbed 17:ff9d1e86ad5f 1528 int order)
sPymbed 17:ff9d1e86ad5f 1529 {
sPymbed 17:ff9d1e86ad5f 1530 int i;
sPymbed 17:ff9d1e86ad5f 1531
sPymbed 17:ff9d1e86ad5f 1532 /* The nonce is the IV with the sequence XORed into the last bytes. */
sPymbed 17:ff9d1e86ad5f 1533 WriteSEQ(ssl, order, nonce + AEAD_NONCE_SZ - SEQ_SZ);
sPymbed 17:ff9d1e86ad5f 1534 for (i = 0; i < AEAD_NONCE_SZ - SEQ_SZ; i++)
sPymbed 17:ff9d1e86ad5f 1535 nonce[i] = iv[i];
sPymbed 17:ff9d1e86ad5f 1536 for (; i < AEAD_NONCE_SZ; i++)
sPymbed 17:ff9d1e86ad5f 1537 nonce[i] ^= iv[i];
sPymbed 17:ff9d1e86ad5f 1538 }
sPymbed 17:ff9d1e86ad5f 1539
sPymbed 17:ff9d1e86ad5f 1540 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
sPymbed 17:ff9d1e86ad5f 1541 /* Encrypt with ChaCha20 and create authenication tag with Poly1305.
sPymbed 17:ff9d1e86ad5f 1542 *
sPymbed 17:ff9d1e86ad5f 1543 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 1544 * output The buffer to write encrypted data and authentication tag into.
sPymbed 17:ff9d1e86ad5f 1545 * May be the same pointer as input.
sPymbed 17:ff9d1e86ad5f 1546 * input The data to encrypt.
sPymbed 17:ff9d1e86ad5f 1547 * sz The number of bytes to encrypt.
sPymbed 17:ff9d1e86ad5f 1548 * nonce The nonce to use with ChaCha20.
sPymbed 17:ff9d1e86ad5f 1549 * aad The additional authentication data.
sPymbed 17:ff9d1e86ad5f 1550 * aadSz The size of the addition authentication data.
sPymbed 17:ff9d1e86ad5f 1551 * tag The authentication tag buffer.
sPymbed 17:ff9d1e86ad5f 1552 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 1553 */
sPymbed 17:ff9d1e86ad5f 1554 static int ChaCha20Poly1305_Encrypt(WOLFSSL* ssl, byte* output,
sPymbed 17:ff9d1e86ad5f 1555 const byte* input, word16 sz, byte* nonce,
sPymbed 17:ff9d1e86ad5f 1556 const byte* aad, word16 aadSz, byte* tag)
sPymbed 17:ff9d1e86ad5f 1557 {
sPymbed 17:ff9d1e86ad5f 1558 int ret = 0;
sPymbed 17:ff9d1e86ad5f 1559 byte poly[CHACHA20_256_KEY_SIZE];
sPymbed 17:ff9d1e86ad5f 1560
sPymbed 17:ff9d1e86ad5f 1561 /* Poly1305 key is 256 bits of zero encrypted with ChaCha20. */
sPymbed 17:ff9d1e86ad5f 1562 XMEMSET(poly, 0, sizeof(poly));
sPymbed 17:ff9d1e86ad5f 1563
sPymbed 17:ff9d1e86ad5f 1564 /* Set the nonce for ChaCha and get Poly1305 key. */
sPymbed 17:ff9d1e86ad5f 1565 ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 0);
sPymbed 17:ff9d1e86ad5f 1566 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1567 return ret;
sPymbed 17:ff9d1e86ad5f 1568 /* Create Poly1305 key using ChaCha20 keystream. */
sPymbed 17:ff9d1e86ad5f 1569 ret = wc_Chacha_Process(ssl->encrypt.chacha, poly, poly, sizeof(poly));
sPymbed 17:ff9d1e86ad5f 1570 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1571 return ret;
sPymbed 17:ff9d1e86ad5f 1572 /* Encrypt the plain text. */
sPymbed 17:ff9d1e86ad5f 1573 ret = wc_Chacha_Process(ssl->encrypt.chacha, output, input, sz);
sPymbed 17:ff9d1e86ad5f 1574 if (ret != 0) {
sPymbed 17:ff9d1e86ad5f 1575 ForceZero(poly, sizeof(poly));
sPymbed 17:ff9d1e86ad5f 1576 return ret;
sPymbed 17:ff9d1e86ad5f 1577 }
sPymbed 17:ff9d1e86ad5f 1578
sPymbed 17:ff9d1e86ad5f 1579 /* Set key for Poly1305. */
sPymbed 17:ff9d1e86ad5f 1580 ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly, sizeof(poly));
sPymbed 17:ff9d1e86ad5f 1581 ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */
sPymbed 17:ff9d1e86ad5f 1582 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1583 return ret;
sPymbed 17:ff9d1e86ad5f 1584 /* Add authentication code of encrypted data to end. */
sPymbed 17:ff9d1e86ad5f 1585 ret = wc_Poly1305_MAC(ssl->auth.poly1305, (byte*)aad, aadSz, output, sz,
sPymbed 17:ff9d1e86ad5f 1586 tag, POLY1305_AUTH_SZ);
sPymbed 17:ff9d1e86ad5f 1587
sPymbed 17:ff9d1e86ad5f 1588 return ret;
sPymbed 17:ff9d1e86ad5f 1589 }
sPymbed 17:ff9d1e86ad5f 1590 #endif
sPymbed 17:ff9d1e86ad5f 1591
sPymbed 17:ff9d1e86ad5f 1592 /* Encrypt data for TLS v1.3.
sPymbed 17:ff9d1e86ad5f 1593 *
sPymbed 17:ff9d1e86ad5f 1594 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 1595 * output The buffer to write encrypted data and authentication tag into.
sPymbed 17:ff9d1e86ad5f 1596 * May be the same pointer as input.
sPymbed 17:ff9d1e86ad5f 1597 * input The record header and data to encrypt.
sPymbed 17:ff9d1e86ad5f 1598 * sz The number of bytes to encrypt.
sPymbed 17:ff9d1e86ad5f 1599 * aad The additional authentication data.
sPymbed 17:ff9d1e86ad5f 1600 * aadSz The size of the addition authentication data.
sPymbed 17:ff9d1e86ad5f 1601 * asyncOkay If non-zero can return WC_PENDING_E, otherwise blocks on crypto
sPymbed 17:ff9d1e86ad5f 1602 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 1603 */
sPymbed 17:ff9d1e86ad5f 1604 static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
sPymbed 17:ff9d1e86ad5f 1605 word16 sz, const byte* aad, word16 aadSz, int asyncOkay)
sPymbed 17:ff9d1e86ad5f 1606 {
sPymbed 17:ff9d1e86ad5f 1607 int ret = 0;
sPymbed 17:ff9d1e86ad5f 1608 word16 dataSz = sz - ssl->specs.aead_mac_size;
sPymbed 17:ff9d1e86ad5f 1609 word16 macSz = ssl->specs.aead_mac_size;
sPymbed 17:ff9d1e86ad5f 1610 word32 nonceSz = 0;
sPymbed 17:ff9d1e86ad5f 1611 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 1612 WC_ASYNC_DEV* asyncDev = NULL;
sPymbed 17:ff9d1e86ad5f 1613 word32 event_flags = WC_ASYNC_FLAG_CALL_AGAIN;
sPymbed 17:ff9d1e86ad5f 1614 #endif
sPymbed 17:ff9d1e86ad5f 1615
sPymbed 17:ff9d1e86ad5f 1616 WOLFSSL_ENTER("EncryptTls13");
sPymbed 17:ff9d1e86ad5f 1617
sPymbed 17:ff9d1e86ad5f 1618 (void)output;
sPymbed 17:ff9d1e86ad5f 1619 (void)input;
sPymbed 17:ff9d1e86ad5f 1620 (void)sz;
sPymbed 17:ff9d1e86ad5f 1621 (void)dataSz;
sPymbed 17:ff9d1e86ad5f 1622 (void)macSz;
sPymbed 17:ff9d1e86ad5f 1623 (void)asyncOkay;
sPymbed 17:ff9d1e86ad5f 1624 (void)nonceSz;
sPymbed 17:ff9d1e86ad5f 1625
sPymbed 17:ff9d1e86ad5f 1626 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 1627 if (ssl->error == WC_PENDING_E) {
sPymbed 17:ff9d1e86ad5f 1628 ssl->error = 0; /* clear async */
sPymbed 17:ff9d1e86ad5f 1629 }
sPymbed 17:ff9d1e86ad5f 1630 #endif
sPymbed 17:ff9d1e86ad5f 1631
sPymbed 17:ff9d1e86ad5f 1632 switch (ssl->encrypt.state) {
sPymbed 17:ff9d1e86ad5f 1633 case CIPHER_STATE_BEGIN:
sPymbed 17:ff9d1e86ad5f 1634 {
sPymbed 17:ff9d1e86ad5f 1635 #ifdef WOLFSSL_DEBUG_TLS
sPymbed 17:ff9d1e86ad5f 1636 WOLFSSL_MSG("Data to encrypt");
sPymbed 17:ff9d1e86ad5f 1637 WOLFSSL_BUFFER(input, dataSz);
sPymbed 17:ff9d1e86ad5f 1638 #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22) && \
sPymbed 17:ff9d1e86ad5f 1639 !defined(WOLFSSL_TLS13_DRAFT_23)
sPymbed 17:ff9d1e86ad5f 1640 WOLFSSL_MSG("Additional Authentication Data");
sPymbed 17:ff9d1e86ad5f 1641 WOLFSSL_BUFFER(aad, aadSz);
sPymbed 17:ff9d1e86ad5f 1642 #endif
sPymbed 17:ff9d1e86ad5f 1643 #endif
sPymbed 17:ff9d1e86ad5f 1644
sPymbed 17:ff9d1e86ad5f 1645 if (ssl->encrypt.nonce == NULL)
sPymbed 17:ff9d1e86ad5f 1646 ssl->encrypt.nonce = (byte*)XMALLOC(AEAD_NONCE_SZ,
sPymbed 17:ff9d1e86ad5f 1647 ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
sPymbed 17:ff9d1e86ad5f 1648 if (ssl->encrypt.nonce == NULL)
sPymbed 17:ff9d1e86ad5f 1649 return MEMORY_E;
sPymbed 17:ff9d1e86ad5f 1650
sPymbed 17:ff9d1e86ad5f 1651 BuildTls13Nonce(ssl, ssl->encrypt.nonce, ssl->keys.aead_enc_imp_IV,
sPymbed 17:ff9d1e86ad5f 1652 CUR_ORDER);
sPymbed 17:ff9d1e86ad5f 1653
sPymbed 17:ff9d1e86ad5f 1654 /* Advance state and proceed */
sPymbed 17:ff9d1e86ad5f 1655 ssl->encrypt.state = CIPHER_STATE_DO;
sPymbed 17:ff9d1e86ad5f 1656 }
sPymbed 17:ff9d1e86ad5f 1657 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 1658
sPymbed 17:ff9d1e86ad5f 1659 case CIPHER_STATE_DO:
sPymbed 17:ff9d1e86ad5f 1660 {
sPymbed 17:ff9d1e86ad5f 1661 switch (ssl->specs.bulk_cipher_algorithm) {
sPymbed 17:ff9d1e86ad5f 1662 #ifdef BUILD_AESGCM
sPymbed 17:ff9d1e86ad5f 1663 case wolfssl_aes_gcm:
sPymbed 17:ff9d1e86ad5f 1664 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 1665 /* initialize event */
sPymbed 17:ff9d1e86ad5f 1666 asyncDev = &ssl->encrypt.aes->asyncDev;
sPymbed 17:ff9d1e86ad5f 1667 ret = wolfSSL_AsyncInit(ssl, asyncDev, event_flags);
sPymbed 17:ff9d1e86ad5f 1668 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1669 break;
sPymbed 17:ff9d1e86ad5f 1670 #endif
sPymbed 17:ff9d1e86ad5f 1671
sPymbed 17:ff9d1e86ad5f 1672 nonceSz = AESGCM_NONCE_SZ;
sPymbed 17:ff9d1e86ad5f 1673 ret = wc_AesGcmEncrypt(ssl->encrypt.aes, output, input,
sPymbed 17:ff9d1e86ad5f 1674 dataSz, ssl->encrypt.nonce, nonceSz,
sPymbed 17:ff9d1e86ad5f 1675 output + dataSz, macSz, aad, aadSz);
sPymbed 17:ff9d1e86ad5f 1676 break;
sPymbed 17:ff9d1e86ad5f 1677 #endif
sPymbed 17:ff9d1e86ad5f 1678
sPymbed 17:ff9d1e86ad5f 1679 #ifdef HAVE_AESCCM
sPymbed 17:ff9d1e86ad5f 1680 case wolfssl_aes_ccm:
sPymbed 17:ff9d1e86ad5f 1681 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 1682 /* initialize event */
sPymbed 17:ff9d1e86ad5f 1683 asyncDev = &ssl->encrypt.aes->asyncDev;
sPymbed 17:ff9d1e86ad5f 1684 ret = wolfSSL_AsyncInit(ssl, asyncDev, event_flags);
sPymbed 17:ff9d1e86ad5f 1685 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1686 break;
sPymbed 17:ff9d1e86ad5f 1687 #endif
sPymbed 17:ff9d1e86ad5f 1688
sPymbed 17:ff9d1e86ad5f 1689 nonceSz = AESCCM_NONCE_SZ;
sPymbed 17:ff9d1e86ad5f 1690 ret = wc_AesCcmEncrypt(ssl->encrypt.aes, output, input,
sPymbed 17:ff9d1e86ad5f 1691 dataSz, ssl->encrypt.nonce, nonceSz,
sPymbed 17:ff9d1e86ad5f 1692 output + dataSz, macSz, aad, aadSz);
sPymbed 17:ff9d1e86ad5f 1693 break;
sPymbed 17:ff9d1e86ad5f 1694 #endif
sPymbed 17:ff9d1e86ad5f 1695
sPymbed 17:ff9d1e86ad5f 1696 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
sPymbed 17:ff9d1e86ad5f 1697 case wolfssl_chacha:
sPymbed 17:ff9d1e86ad5f 1698 ret = ChaCha20Poly1305_Encrypt(ssl, output, input, dataSz,
sPymbed 17:ff9d1e86ad5f 1699 ssl->encrypt.nonce, aad, aadSz, output + dataSz);
sPymbed 17:ff9d1e86ad5f 1700 break;
sPymbed 17:ff9d1e86ad5f 1701 #endif
sPymbed 17:ff9d1e86ad5f 1702
sPymbed 17:ff9d1e86ad5f 1703 default:
sPymbed 17:ff9d1e86ad5f 1704 WOLFSSL_MSG("wolfSSL Encrypt programming error");
sPymbed 17:ff9d1e86ad5f 1705 return ENCRYPT_ERROR;
sPymbed 17:ff9d1e86ad5f 1706 }
sPymbed 17:ff9d1e86ad5f 1707
sPymbed 17:ff9d1e86ad5f 1708 /* Advance state */
sPymbed 17:ff9d1e86ad5f 1709 ssl->encrypt.state = CIPHER_STATE_END;
sPymbed 17:ff9d1e86ad5f 1710
sPymbed 17:ff9d1e86ad5f 1711 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 1712 if (ret == WC_PENDING_E) {
sPymbed 17:ff9d1e86ad5f 1713 /* if async is not okay, then block */
sPymbed 17:ff9d1e86ad5f 1714 if (!asyncOkay) {
sPymbed 17:ff9d1e86ad5f 1715 ret = wc_AsyncWait(ret, asyncDev, event_flags);
sPymbed 17:ff9d1e86ad5f 1716 }
sPymbed 17:ff9d1e86ad5f 1717 else {
sPymbed 17:ff9d1e86ad5f 1718 /* If pending, then leave and return will resume below */
sPymbed 17:ff9d1e86ad5f 1719 return wolfSSL_AsyncPush(ssl, asyncDev);
sPymbed 17:ff9d1e86ad5f 1720 }
sPymbed 17:ff9d1e86ad5f 1721 }
sPymbed 17:ff9d1e86ad5f 1722 #endif
sPymbed 17:ff9d1e86ad5f 1723 }
sPymbed 17:ff9d1e86ad5f 1724 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 1725
sPymbed 17:ff9d1e86ad5f 1726 case CIPHER_STATE_END:
sPymbed 17:ff9d1e86ad5f 1727 {
sPymbed 17:ff9d1e86ad5f 1728 #ifdef WOLFSSL_DEBUG_TLS
sPymbed 17:ff9d1e86ad5f 1729 WOLFSSL_MSG("Nonce");
sPymbed 17:ff9d1e86ad5f 1730 WOLFSSL_BUFFER(ssl->encrypt.nonce, ssl->specs.iv_size);
sPymbed 17:ff9d1e86ad5f 1731 WOLFSSL_MSG("Encrypted data");
sPymbed 17:ff9d1e86ad5f 1732 WOLFSSL_BUFFER(output, dataSz);
sPymbed 17:ff9d1e86ad5f 1733 WOLFSSL_MSG("Authentication Tag");
sPymbed 17:ff9d1e86ad5f 1734 WOLFSSL_BUFFER(output + dataSz, macSz);
sPymbed 17:ff9d1e86ad5f 1735 #endif
sPymbed 17:ff9d1e86ad5f 1736
sPymbed 17:ff9d1e86ad5f 1737 ForceZero(ssl->encrypt.nonce, AEAD_NONCE_SZ);
sPymbed 17:ff9d1e86ad5f 1738
sPymbed 17:ff9d1e86ad5f 1739 break;
sPymbed 17:ff9d1e86ad5f 1740 }
sPymbed 17:ff9d1e86ad5f 1741 }
sPymbed 17:ff9d1e86ad5f 1742
sPymbed 17:ff9d1e86ad5f 1743 /* Reset state */
sPymbed 17:ff9d1e86ad5f 1744 ssl->encrypt.state = CIPHER_STATE_BEGIN;
sPymbed 17:ff9d1e86ad5f 1745
sPymbed 17:ff9d1e86ad5f 1746 return ret;
sPymbed 17:ff9d1e86ad5f 1747 }
sPymbed 17:ff9d1e86ad5f 1748
sPymbed 17:ff9d1e86ad5f 1749 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
sPymbed 17:ff9d1e86ad5f 1750 /* Decrypt with ChaCha20 and check authenication tag with Poly1305.
sPymbed 17:ff9d1e86ad5f 1751 *
sPymbed 17:ff9d1e86ad5f 1752 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 1753 * output The buffer to write decrypted data into.
sPymbed 17:ff9d1e86ad5f 1754 * May be the same pointer as input.
sPymbed 17:ff9d1e86ad5f 1755 * input The data to decrypt.
sPymbed 17:ff9d1e86ad5f 1756 * sz The number of bytes to decrypt.
sPymbed 17:ff9d1e86ad5f 1757 * nonce The nonce to use with ChaCha20.
sPymbed 17:ff9d1e86ad5f 1758 * aad The additional authentication data.
sPymbed 17:ff9d1e86ad5f 1759 * aadSz The size of the addition authentication data.
sPymbed 17:ff9d1e86ad5f 1760 * tagIn The authentication tag data from packet.
sPymbed 17:ff9d1e86ad5f 1761 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 1762 */
sPymbed 17:ff9d1e86ad5f 1763 static int ChaCha20Poly1305_Decrypt(WOLFSSL* ssl, byte* output,
sPymbed 17:ff9d1e86ad5f 1764 const byte* input, word16 sz, byte* nonce,
sPymbed 17:ff9d1e86ad5f 1765 const byte* aad, word16 aadSz,
sPymbed 17:ff9d1e86ad5f 1766 const byte* tagIn)
sPymbed 17:ff9d1e86ad5f 1767 {
sPymbed 17:ff9d1e86ad5f 1768 int ret;
sPymbed 17:ff9d1e86ad5f 1769 byte tag[POLY1305_AUTH_SZ];
sPymbed 17:ff9d1e86ad5f 1770 byte poly[CHACHA20_256_KEY_SIZE]; /* generated key for mac */
sPymbed 17:ff9d1e86ad5f 1771
sPymbed 17:ff9d1e86ad5f 1772 /* Poly1305 key is 256 bits of zero encrypted with ChaCha20. */
sPymbed 17:ff9d1e86ad5f 1773 XMEMSET(poly, 0, sizeof(poly));
sPymbed 17:ff9d1e86ad5f 1774
sPymbed 17:ff9d1e86ad5f 1775 /* Set nonce and get Poly1305 key. */
sPymbed 17:ff9d1e86ad5f 1776 ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 0);
sPymbed 17:ff9d1e86ad5f 1777 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1778 return ret;
sPymbed 17:ff9d1e86ad5f 1779 /* Use ChaCha20 keystream to get Poly1305 key for tag. */
sPymbed 17:ff9d1e86ad5f 1780 ret = wc_Chacha_Process(ssl->decrypt.chacha, poly, poly, sizeof(poly));
sPymbed 17:ff9d1e86ad5f 1781 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1782 return ret;
sPymbed 17:ff9d1e86ad5f 1783
sPymbed 17:ff9d1e86ad5f 1784 /* Set key for Poly1305. */
sPymbed 17:ff9d1e86ad5f 1785 ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly, sizeof(poly));
sPymbed 17:ff9d1e86ad5f 1786 ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */
sPymbed 17:ff9d1e86ad5f 1787 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1788 return ret;
sPymbed 17:ff9d1e86ad5f 1789 /* Generate authentication tag for encrypted data. */
sPymbed 17:ff9d1e86ad5f 1790 if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, (byte*)aad, aadSz,
sPymbed 17:ff9d1e86ad5f 1791 (byte*)input, sz, tag, sizeof(tag))) != 0) {
sPymbed 17:ff9d1e86ad5f 1792 return ret;
sPymbed 17:ff9d1e86ad5f 1793 }
sPymbed 17:ff9d1e86ad5f 1794
sPymbed 17:ff9d1e86ad5f 1795 /* Check tag sent along with packet. */
sPymbed 17:ff9d1e86ad5f 1796 if (ConstantCompare(tagIn, tag, POLY1305_AUTH_SZ) != 0) {
sPymbed 17:ff9d1e86ad5f 1797 WOLFSSL_MSG("MAC did not match");
sPymbed 17:ff9d1e86ad5f 1798 return VERIFY_MAC_ERROR;
sPymbed 17:ff9d1e86ad5f 1799 }
sPymbed 17:ff9d1e86ad5f 1800
sPymbed 17:ff9d1e86ad5f 1801 /* If the tag was good decrypt message. */
sPymbed 17:ff9d1e86ad5f 1802 ret = wc_Chacha_Process(ssl->decrypt.chacha, output, input, sz);
sPymbed 17:ff9d1e86ad5f 1803
sPymbed 17:ff9d1e86ad5f 1804 return ret;
sPymbed 17:ff9d1e86ad5f 1805 }
sPymbed 17:ff9d1e86ad5f 1806 #endif
sPymbed 17:ff9d1e86ad5f 1807
sPymbed 17:ff9d1e86ad5f 1808 /* Decrypt data for TLS v1.3.
sPymbed 17:ff9d1e86ad5f 1809 *
sPymbed 17:ff9d1e86ad5f 1810 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 1811 * output The buffer to write decrypted data into.
sPymbed 17:ff9d1e86ad5f 1812 * May be the same pointer as input.
sPymbed 17:ff9d1e86ad5f 1813 * input The data to decrypt and authentication tag.
sPymbed 17:ff9d1e86ad5f 1814 * sz The length of the encrypted data plus authentication tag.
sPymbed 17:ff9d1e86ad5f 1815 * aad The additional authentication data.
sPymbed 17:ff9d1e86ad5f 1816 * aadSz The size of the addition authentication data.
sPymbed 17:ff9d1e86ad5f 1817 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 1818 */
sPymbed 17:ff9d1e86ad5f 1819 int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz,
sPymbed 17:ff9d1e86ad5f 1820 const byte* aad, word16 aadSz)
sPymbed 17:ff9d1e86ad5f 1821 {
sPymbed 17:ff9d1e86ad5f 1822 int ret = 0;
sPymbed 17:ff9d1e86ad5f 1823 word16 dataSz = sz - ssl->specs.aead_mac_size;
sPymbed 17:ff9d1e86ad5f 1824 word16 macSz = ssl->specs.aead_mac_size;
sPymbed 17:ff9d1e86ad5f 1825 word32 nonceSz = 0;
sPymbed 17:ff9d1e86ad5f 1826
sPymbed 17:ff9d1e86ad5f 1827 WOLFSSL_ENTER("DecryptTls13");
sPymbed 17:ff9d1e86ad5f 1828
sPymbed 17:ff9d1e86ad5f 1829 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 1830 ret = wolfSSL_AsyncPop(ssl, &ssl->decrypt.state);
sPymbed 17:ff9d1e86ad5f 1831 if (ret != WC_NOT_PENDING_E) {
sPymbed 17:ff9d1e86ad5f 1832 /* check for still pending */
sPymbed 17:ff9d1e86ad5f 1833 if (ret == WC_PENDING_E)
sPymbed 17:ff9d1e86ad5f 1834 return ret;
sPymbed 17:ff9d1e86ad5f 1835
sPymbed 17:ff9d1e86ad5f 1836 ssl->error = 0; /* clear async */
sPymbed 17:ff9d1e86ad5f 1837
sPymbed 17:ff9d1e86ad5f 1838 /* let failures through so CIPHER_STATE_END logic is run */
sPymbed 17:ff9d1e86ad5f 1839 }
sPymbed 17:ff9d1e86ad5f 1840 else
sPymbed 17:ff9d1e86ad5f 1841 #endif
sPymbed 17:ff9d1e86ad5f 1842 {
sPymbed 17:ff9d1e86ad5f 1843 /* Reset state */
sPymbed 17:ff9d1e86ad5f 1844 ret = 0;
sPymbed 17:ff9d1e86ad5f 1845 ssl->decrypt.state = CIPHER_STATE_BEGIN;
sPymbed 17:ff9d1e86ad5f 1846 }
sPymbed 17:ff9d1e86ad5f 1847
sPymbed 17:ff9d1e86ad5f 1848 (void)output;
sPymbed 17:ff9d1e86ad5f 1849 (void)input;
sPymbed 17:ff9d1e86ad5f 1850 (void)sz;
sPymbed 17:ff9d1e86ad5f 1851 (void)dataSz;
sPymbed 17:ff9d1e86ad5f 1852 (void)macSz;
sPymbed 17:ff9d1e86ad5f 1853 (void)nonceSz;
sPymbed 17:ff9d1e86ad5f 1854
sPymbed 17:ff9d1e86ad5f 1855 switch (ssl->decrypt.state) {
sPymbed 17:ff9d1e86ad5f 1856 case CIPHER_STATE_BEGIN:
sPymbed 17:ff9d1e86ad5f 1857 {
sPymbed 17:ff9d1e86ad5f 1858 #ifdef WOLFSSL_DEBUG_TLS
sPymbed 17:ff9d1e86ad5f 1859 WOLFSSL_MSG("Data to decrypt");
sPymbed 17:ff9d1e86ad5f 1860 WOLFSSL_BUFFER(input, dataSz);
sPymbed 17:ff9d1e86ad5f 1861 #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22) && \
sPymbed 17:ff9d1e86ad5f 1862 !defined(WOLFSSL_TLS13_DRAFT_23)
sPymbed 17:ff9d1e86ad5f 1863 WOLFSSL_MSG("Additional Authentication Data");
sPymbed 17:ff9d1e86ad5f 1864 WOLFSSL_BUFFER(aad, aadSz);
sPymbed 17:ff9d1e86ad5f 1865 #endif
sPymbed 17:ff9d1e86ad5f 1866 WOLFSSL_MSG("Authentication tag");
sPymbed 17:ff9d1e86ad5f 1867 WOLFSSL_BUFFER(input + dataSz, macSz);
sPymbed 17:ff9d1e86ad5f 1868 #endif
sPymbed 17:ff9d1e86ad5f 1869
sPymbed 17:ff9d1e86ad5f 1870 if (ssl->decrypt.nonce == NULL)
sPymbed 17:ff9d1e86ad5f 1871 ssl->decrypt.nonce = (byte*)XMALLOC(AEAD_NONCE_SZ,
sPymbed 17:ff9d1e86ad5f 1872 ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
sPymbed 17:ff9d1e86ad5f 1873 if (ssl->decrypt.nonce == NULL)
sPymbed 17:ff9d1e86ad5f 1874 return MEMORY_E;
sPymbed 17:ff9d1e86ad5f 1875
sPymbed 17:ff9d1e86ad5f 1876 BuildTls13Nonce(ssl, ssl->decrypt.nonce, ssl->keys.aead_dec_imp_IV,
sPymbed 17:ff9d1e86ad5f 1877 PEER_ORDER);
sPymbed 17:ff9d1e86ad5f 1878
sPymbed 17:ff9d1e86ad5f 1879 /* Advance state and proceed */
sPymbed 17:ff9d1e86ad5f 1880 ssl->decrypt.state = CIPHER_STATE_DO;
sPymbed 17:ff9d1e86ad5f 1881 }
sPymbed 17:ff9d1e86ad5f 1882 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 1883
sPymbed 17:ff9d1e86ad5f 1884 case CIPHER_STATE_DO:
sPymbed 17:ff9d1e86ad5f 1885 {
sPymbed 17:ff9d1e86ad5f 1886 switch (ssl->specs.bulk_cipher_algorithm) {
sPymbed 17:ff9d1e86ad5f 1887 #ifdef BUILD_AESGCM
sPymbed 17:ff9d1e86ad5f 1888 case wolfssl_aes_gcm:
sPymbed 17:ff9d1e86ad5f 1889 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 1890 /* initialize event */
sPymbed 17:ff9d1e86ad5f 1891 ret = wolfSSL_AsyncInit(ssl, &ssl->decrypt.aes->asyncDev,
sPymbed 17:ff9d1e86ad5f 1892 WC_ASYNC_FLAG_CALL_AGAIN);
sPymbed 17:ff9d1e86ad5f 1893 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1894 break;
sPymbed 17:ff9d1e86ad5f 1895 #endif
sPymbed 17:ff9d1e86ad5f 1896
sPymbed 17:ff9d1e86ad5f 1897 nonceSz = AESGCM_NONCE_SZ;
sPymbed 17:ff9d1e86ad5f 1898 ret = wc_AesGcmDecrypt(ssl->decrypt.aes, output, input,
sPymbed 17:ff9d1e86ad5f 1899 dataSz, ssl->decrypt.nonce, nonceSz,
sPymbed 17:ff9d1e86ad5f 1900 input + dataSz, macSz, aad, aadSz);
sPymbed 17:ff9d1e86ad5f 1901 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 1902 if (ret == WC_PENDING_E) {
sPymbed 17:ff9d1e86ad5f 1903 ret = wolfSSL_AsyncPush(ssl,
sPymbed 17:ff9d1e86ad5f 1904 &ssl->decrypt.aes->asyncDev);
sPymbed 17:ff9d1e86ad5f 1905 }
sPymbed 17:ff9d1e86ad5f 1906 #endif
sPymbed 17:ff9d1e86ad5f 1907 break;
sPymbed 17:ff9d1e86ad5f 1908 #endif
sPymbed 17:ff9d1e86ad5f 1909
sPymbed 17:ff9d1e86ad5f 1910 #ifdef HAVE_AESCCM
sPymbed 17:ff9d1e86ad5f 1911 case wolfssl_aes_ccm:
sPymbed 17:ff9d1e86ad5f 1912 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 1913 /* initialize event */
sPymbed 17:ff9d1e86ad5f 1914 ret = wolfSSL_AsyncInit(ssl, &ssl->decrypt.aes->asyncDev,
sPymbed 17:ff9d1e86ad5f 1915 WC_ASYNC_FLAG_CALL_AGAIN);
sPymbed 17:ff9d1e86ad5f 1916 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 1917 break;
sPymbed 17:ff9d1e86ad5f 1918 #endif
sPymbed 17:ff9d1e86ad5f 1919
sPymbed 17:ff9d1e86ad5f 1920 nonceSz = AESCCM_NONCE_SZ;
sPymbed 17:ff9d1e86ad5f 1921 ret = wc_AesCcmDecrypt(ssl->decrypt.aes, output, input,
sPymbed 17:ff9d1e86ad5f 1922 dataSz, ssl->decrypt.nonce, nonceSz,
sPymbed 17:ff9d1e86ad5f 1923 input + dataSz, macSz, aad, aadSz);
sPymbed 17:ff9d1e86ad5f 1924 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 1925 if (ret == WC_PENDING_E) {
sPymbed 17:ff9d1e86ad5f 1926 ret = wolfSSL_AsyncPush(ssl,
sPymbed 17:ff9d1e86ad5f 1927 &ssl->decrypt.aes->asyncDev);
sPymbed 17:ff9d1e86ad5f 1928 }
sPymbed 17:ff9d1e86ad5f 1929 #endif
sPymbed 17:ff9d1e86ad5f 1930 break;
sPymbed 17:ff9d1e86ad5f 1931 #endif
sPymbed 17:ff9d1e86ad5f 1932
sPymbed 17:ff9d1e86ad5f 1933 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
sPymbed 17:ff9d1e86ad5f 1934 case wolfssl_chacha:
sPymbed 17:ff9d1e86ad5f 1935 ret = ChaCha20Poly1305_Decrypt(ssl, output, input, dataSz,
sPymbed 17:ff9d1e86ad5f 1936 ssl->decrypt.nonce, aad, aadSz, input + dataSz);
sPymbed 17:ff9d1e86ad5f 1937 break;
sPymbed 17:ff9d1e86ad5f 1938 #endif
sPymbed 17:ff9d1e86ad5f 1939
sPymbed 17:ff9d1e86ad5f 1940 default:
sPymbed 17:ff9d1e86ad5f 1941 WOLFSSL_MSG("wolfSSL Decrypt programming error");
sPymbed 17:ff9d1e86ad5f 1942 return DECRYPT_ERROR;
sPymbed 17:ff9d1e86ad5f 1943 }
sPymbed 17:ff9d1e86ad5f 1944
sPymbed 17:ff9d1e86ad5f 1945 /* Advance state */
sPymbed 17:ff9d1e86ad5f 1946 ssl->decrypt.state = CIPHER_STATE_END;
sPymbed 17:ff9d1e86ad5f 1947
sPymbed 17:ff9d1e86ad5f 1948 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 1949 /* If pending, leave now */
sPymbed 17:ff9d1e86ad5f 1950 if (ret == WC_PENDING_E) {
sPymbed 17:ff9d1e86ad5f 1951 return ret;
sPymbed 17:ff9d1e86ad5f 1952 }
sPymbed 17:ff9d1e86ad5f 1953 #endif
sPymbed 17:ff9d1e86ad5f 1954 }
sPymbed 17:ff9d1e86ad5f 1955 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 1956
sPymbed 17:ff9d1e86ad5f 1957 case CIPHER_STATE_END:
sPymbed 17:ff9d1e86ad5f 1958 {
sPymbed 17:ff9d1e86ad5f 1959 #ifdef WOLFSSL_DEBUG_TLS
sPymbed 17:ff9d1e86ad5f 1960 WOLFSSL_MSG("Nonce");
sPymbed 17:ff9d1e86ad5f 1961 WOLFSSL_BUFFER(ssl->decrypt.nonce, ssl->specs.iv_size);
sPymbed 17:ff9d1e86ad5f 1962 WOLFSSL_MSG("Decrypted data");
sPymbed 17:ff9d1e86ad5f 1963 WOLFSSL_BUFFER(output, dataSz);
sPymbed 17:ff9d1e86ad5f 1964 #endif
sPymbed 17:ff9d1e86ad5f 1965
sPymbed 17:ff9d1e86ad5f 1966 ForceZero(ssl->decrypt.nonce, AEAD_NONCE_SZ);
sPymbed 17:ff9d1e86ad5f 1967
sPymbed 17:ff9d1e86ad5f 1968 break;
sPymbed 17:ff9d1e86ad5f 1969 }
sPymbed 17:ff9d1e86ad5f 1970 }
sPymbed 17:ff9d1e86ad5f 1971
sPymbed 17:ff9d1e86ad5f 1972 #ifndef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 1973 if (ret < 0) {
sPymbed 17:ff9d1e86ad5f 1974 SendAlert(ssl, alert_fatal, bad_record_mac);
sPymbed 17:ff9d1e86ad5f 1975 ret = VERIFY_MAC_ERROR;
sPymbed 17:ff9d1e86ad5f 1976 }
sPymbed 17:ff9d1e86ad5f 1977 #endif
sPymbed 17:ff9d1e86ad5f 1978
sPymbed 17:ff9d1e86ad5f 1979 return ret;
sPymbed 17:ff9d1e86ad5f 1980 }
sPymbed 17:ff9d1e86ad5f 1981
sPymbed 17:ff9d1e86ad5f 1982 /* Persistable BuildTls13Message arguments */
sPymbed 17:ff9d1e86ad5f 1983 typedef struct BuildMsg13Args {
sPymbed 17:ff9d1e86ad5f 1984 word32 sz;
sPymbed 17:ff9d1e86ad5f 1985 word32 idx;
sPymbed 17:ff9d1e86ad5f 1986 word32 headerSz;
sPymbed 17:ff9d1e86ad5f 1987 word16 size;
sPymbed 17:ff9d1e86ad5f 1988 } BuildMsg13Args;
sPymbed 17:ff9d1e86ad5f 1989
sPymbed 17:ff9d1e86ad5f 1990 static void FreeBuildMsg13Args(WOLFSSL* ssl, void* pArgs)
sPymbed 17:ff9d1e86ad5f 1991 {
sPymbed 17:ff9d1e86ad5f 1992 BuildMsg13Args* args = (BuildMsg13Args*)pArgs;
sPymbed 17:ff9d1e86ad5f 1993
sPymbed 17:ff9d1e86ad5f 1994 (void)ssl;
sPymbed 17:ff9d1e86ad5f 1995 (void)args;
sPymbed 17:ff9d1e86ad5f 1996
sPymbed 17:ff9d1e86ad5f 1997 /* no allocations in BuildTls13Message */
sPymbed 17:ff9d1e86ad5f 1998 }
sPymbed 17:ff9d1e86ad5f 1999
sPymbed 17:ff9d1e86ad5f 2000 /* Build SSL Message, encrypted.
sPymbed 17:ff9d1e86ad5f 2001 * TLS v1.3 encryption is AEAD only.
sPymbed 17:ff9d1e86ad5f 2002 *
sPymbed 17:ff9d1e86ad5f 2003 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 2004 * output The buffer to write record message to.
sPymbed 17:ff9d1e86ad5f 2005 * outSz Size of the buffer being written into.
sPymbed 17:ff9d1e86ad5f 2006 * input The record data to encrypt (excluding record header).
sPymbed 17:ff9d1e86ad5f 2007 * inSz The size of the record data.
sPymbed 17:ff9d1e86ad5f 2008 * type The recorder header content type.
sPymbed 17:ff9d1e86ad5f 2009 * hashOutput Whether to hash the unencrypted record data.
sPymbed 17:ff9d1e86ad5f 2010 * sizeOnly Only want the size of the record message.
sPymbed 17:ff9d1e86ad5f 2011 * asyncOkay If non-zero can return WC_PENDING_E, otherwise blocks on crypto
sPymbed 17:ff9d1e86ad5f 2012 * returns the size of the encrypted record message or negative value on error.
sPymbed 17:ff9d1e86ad5f 2013 */
sPymbed 17:ff9d1e86ad5f 2014 int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
sPymbed 17:ff9d1e86ad5f 2015 int inSz, int type, int hashOutput, int sizeOnly, int asyncOkay)
sPymbed 17:ff9d1e86ad5f 2016 {
sPymbed 17:ff9d1e86ad5f 2017 int ret = 0;
sPymbed 17:ff9d1e86ad5f 2018 BuildMsg13Args* args;
sPymbed 17:ff9d1e86ad5f 2019 BuildMsg13Args lcl_args;
sPymbed 17:ff9d1e86ad5f 2020 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 2021 args = (BuildMsg13Args*)ssl->async.args;
sPymbed 17:ff9d1e86ad5f 2022 typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
sPymbed 17:ff9d1e86ad5f 2023 (void)sizeof(args_test);
sPymbed 17:ff9d1e86ad5f 2024 #endif
sPymbed 17:ff9d1e86ad5f 2025
sPymbed 17:ff9d1e86ad5f 2026 WOLFSSL_ENTER("BuildTls13Message");
sPymbed 17:ff9d1e86ad5f 2027
sPymbed 17:ff9d1e86ad5f 2028 ret = WC_NOT_PENDING_E;
sPymbed 17:ff9d1e86ad5f 2029 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 2030 if (asyncOkay) {
sPymbed 17:ff9d1e86ad5f 2031 ret = wolfSSL_AsyncPop(ssl, &ssl->options.buildMsgState);
sPymbed 17:ff9d1e86ad5f 2032 if (ret != WC_NOT_PENDING_E) {
sPymbed 17:ff9d1e86ad5f 2033 /* Check for error */
sPymbed 17:ff9d1e86ad5f 2034 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 2035 goto exit_buildmsg;
sPymbed 17:ff9d1e86ad5f 2036 }
sPymbed 17:ff9d1e86ad5f 2037 }
sPymbed 17:ff9d1e86ad5f 2038 else
sPymbed 17:ff9d1e86ad5f 2039 #endif
sPymbed 17:ff9d1e86ad5f 2040 {
sPymbed 17:ff9d1e86ad5f 2041 args = &lcl_args;
sPymbed 17:ff9d1e86ad5f 2042 }
sPymbed 17:ff9d1e86ad5f 2043
sPymbed 17:ff9d1e86ad5f 2044 /* Reset state */
sPymbed 17:ff9d1e86ad5f 2045 if (ret == WC_NOT_PENDING_E) {
sPymbed 17:ff9d1e86ad5f 2046 ret = 0;
sPymbed 17:ff9d1e86ad5f 2047 ssl->options.buildMsgState = BUILD_MSG_BEGIN;
sPymbed 17:ff9d1e86ad5f 2048 XMEMSET(args, 0, sizeof(BuildMsg13Args));
sPymbed 17:ff9d1e86ad5f 2049
sPymbed 17:ff9d1e86ad5f 2050 args->sz = RECORD_HEADER_SZ + inSz;
sPymbed 17:ff9d1e86ad5f 2051 args->idx = RECORD_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 2052 args->headerSz = RECORD_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 2053 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 2054 ssl->async.freeArgs = FreeBuildMsg13Args;
sPymbed 17:ff9d1e86ad5f 2055 #endif
sPymbed 17:ff9d1e86ad5f 2056 }
sPymbed 17:ff9d1e86ad5f 2057
sPymbed 17:ff9d1e86ad5f 2058 switch (ssl->options.buildMsgState) {
sPymbed 17:ff9d1e86ad5f 2059 case BUILD_MSG_BEGIN:
sPymbed 17:ff9d1e86ad5f 2060 {
sPymbed 17:ff9d1e86ad5f 2061 /* catch mistaken sizeOnly parameter */
sPymbed 17:ff9d1e86ad5f 2062 if (sizeOnly) {
sPymbed 17:ff9d1e86ad5f 2063 if (output || input) {
sPymbed 17:ff9d1e86ad5f 2064 WOLFSSL_MSG("BuildTls13Message with sizeOnly "
sPymbed 17:ff9d1e86ad5f 2065 "doesn't need input or output");
sPymbed 17:ff9d1e86ad5f 2066 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 2067 }
sPymbed 17:ff9d1e86ad5f 2068 }
sPymbed 17:ff9d1e86ad5f 2069 else if (output == NULL || input == NULL) {
sPymbed 17:ff9d1e86ad5f 2070 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 2071 }
sPymbed 17:ff9d1e86ad5f 2072
sPymbed 17:ff9d1e86ad5f 2073 /* Record layer content type at the end of record data. */
sPymbed 17:ff9d1e86ad5f 2074 args->sz++;
sPymbed 17:ff9d1e86ad5f 2075 /* Authentication data at the end. */
sPymbed 17:ff9d1e86ad5f 2076 args->sz += ssl->specs.aead_mac_size;
sPymbed 17:ff9d1e86ad5f 2077
sPymbed 17:ff9d1e86ad5f 2078 if (sizeOnly)
sPymbed 17:ff9d1e86ad5f 2079 return args->sz;
sPymbed 17:ff9d1e86ad5f 2080
sPymbed 17:ff9d1e86ad5f 2081 if (args->sz > (word32)outSz) {
sPymbed 17:ff9d1e86ad5f 2082 WOLFSSL_MSG("Oops, want to write past output buffer size");
sPymbed 17:ff9d1e86ad5f 2083 return BUFFER_E;
sPymbed 17:ff9d1e86ad5f 2084 }
sPymbed 17:ff9d1e86ad5f 2085
sPymbed 17:ff9d1e86ad5f 2086 /* Record data length. */
sPymbed 17:ff9d1e86ad5f 2087 args->size = (word16)(args->sz - args->headerSz);
sPymbed 17:ff9d1e86ad5f 2088 /* Write/update the record header with the new size.
sPymbed 17:ff9d1e86ad5f 2089 * Always have the content type as application data for encrypted
sPymbed 17:ff9d1e86ad5f 2090 * messages in TLS v1.3.
sPymbed 17:ff9d1e86ad5f 2091 */
sPymbed 17:ff9d1e86ad5f 2092 AddTls13RecordHeader(output, args->size, application_data, ssl);
sPymbed 17:ff9d1e86ad5f 2093
sPymbed 17:ff9d1e86ad5f 2094 /* TLS v1.3 can do in place encryption. */
sPymbed 17:ff9d1e86ad5f 2095 if (input != output + args->idx)
sPymbed 17:ff9d1e86ad5f 2096 XMEMCPY(output + args->idx, input, inSz);
sPymbed 17:ff9d1e86ad5f 2097 args->idx += inSz;
sPymbed 17:ff9d1e86ad5f 2098
sPymbed 17:ff9d1e86ad5f 2099 ssl->options.buildMsgState = BUILD_MSG_HASH;
sPymbed 17:ff9d1e86ad5f 2100 }
sPymbed 17:ff9d1e86ad5f 2101 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 2102
sPymbed 17:ff9d1e86ad5f 2103 case BUILD_MSG_HASH:
sPymbed 17:ff9d1e86ad5f 2104 {
sPymbed 17:ff9d1e86ad5f 2105 if (hashOutput) {
sPymbed 17:ff9d1e86ad5f 2106 ret = HashOutput(ssl, output, args->headerSz + inSz, 0);
sPymbed 17:ff9d1e86ad5f 2107 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2108 goto exit_buildmsg;
sPymbed 17:ff9d1e86ad5f 2109 }
sPymbed 17:ff9d1e86ad5f 2110
sPymbed 17:ff9d1e86ad5f 2111 ssl->options.buildMsgState = BUILD_MSG_ENCRYPT;
sPymbed 17:ff9d1e86ad5f 2112 }
sPymbed 17:ff9d1e86ad5f 2113 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 2114
sPymbed 17:ff9d1e86ad5f 2115 case BUILD_MSG_ENCRYPT:
sPymbed 17:ff9d1e86ad5f 2116 {
sPymbed 17:ff9d1e86ad5f 2117 /* The real record content type goes at the end of the data. */
sPymbed 17:ff9d1e86ad5f 2118 output[args->idx++] = (byte)type;
sPymbed 17:ff9d1e86ad5f 2119
sPymbed 17:ff9d1e86ad5f 2120 #ifdef ATOMIC_USER
sPymbed 17:ff9d1e86ad5f 2121 if (ssl->ctx->MacEncryptCb) {
sPymbed 17:ff9d1e86ad5f 2122 /* User Record Layer Callback handling */
sPymbed 17:ff9d1e86ad5f 2123 byte* mac = output + args->idx;
sPymbed 17:ff9d1e86ad5f 2124 output += args->headerSz;
sPymbed 17:ff9d1e86ad5f 2125
sPymbed 17:ff9d1e86ad5f 2126 ret = ssl->ctx->MacEncryptCb(ssl, mac, output, inSz, type, 0,
sPymbed 17:ff9d1e86ad5f 2127 output, output, args->size, ssl->MacEncryptCtx);
sPymbed 17:ff9d1e86ad5f 2128 }
sPymbed 17:ff9d1e86ad5f 2129 else
sPymbed 17:ff9d1e86ad5f 2130 #endif
sPymbed 17:ff9d1e86ad5f 2131 {
sPymbed 17:ff9d1e86ad5f 2132 #if defined(WOLFSSL_TLS13_DRAFT_18) || defined(WOLFSSL_TLS13_DRAFT_22) || \
sPymbed 17:ff9d1e86ad5f 2133 defined(WOLFSSL_TLS13_DRAFT_23)
sPymbed 17:ff9d1e86ad5f 2134 output += args->headerSz;
sPymbed 17:ff9d1e86ad5f 2135 ret = EncryptTls13(ssl, output, output, args->size, NULL, 0,
sPymbed 17:ff9d1e86ad5f 2136 asyncOkay);
sPymbed 17:ff9d1e86ad5f 2137 #else
sPymbed 17:ff9d1e86ad5f 2138 const byte* aad = output;
sPymbed 17:ff9d1e86ad5f 2139 output += args->headerSz;
sPymbed 17:ff9d1e86ad5f 2140 ret = EncryptTls13(ssl, output, output, args->size, aad,
sPymbed 17:ff9d1e86ad5f 2141 RECORD_HEADER_SZ, asyncOkay);
sPymbed 17:ff9d1e86ad5f 2142 #endif
sPymbed 17:ff9d1e86ad5f 2143 }
sPymbed 17:ff9d1e86ad5f 2144 break;
sPymbed 17:ff9d1e86ad5f 2145 }
sPymbed 17:ff9d1e86ad5f 2146 }
sPymbed 17:ff9d1e86ad5f 2147
sPymbed 17:ff9d1e86ad5f 2148 exit_buildmsg:
sPymbed 17:ff9d1e86ad5f 2149
sPymbed 17:ff9d1e86ad5f 2150 WOLFSSL_LEAVE("BuildTls13Message", ret);
sPymbed 17:ff9d1e86ad5f 2151
sPymbed 17:ff9d1e86ad5f 2152 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 2153 if (ret == WC_PENDING_E) {
sPymbed 17:ff9d1e86ad5f 2154 return ret;
sPymbed 17:ff9d1e86ad5f 2155 }
sPymbed 17:ff9d1e86ad5f 2156 #endif
sPymbed 17:ff9d1e86ad5f 2157
sPymbed 17:ff9d1e86ad5f 2158 /* make sure build message state is reset */
sPymbed 17:ff9d1e86ad5f 2159 ssl->options.buildMsgState = BUILD_MSG_BEGIN;
sPymbed 17:ff9d1e86ad5f 2160
sPymbed 17:ff9d1e86ad5f 2161 /* return sz on success */
sPymbed 17:ff9d1e86ad5f 2162 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 2163 ret = args->sz;
sPymbed 17:ff9d1e86ad5f 2164
sPymbed 17:ff9d1e86ad5f 2165 /* Final cleanup */
sPymbed 17:ff9d1e86ad5f 2166 FreeBuildMsg13Args(ssl, args);
sPymbed 17:ff9d1e86ad5f 2167
sPymbed 17:ff9d1e86ad5f 2168 return ret;
sPymbed 17:ff9d1e86ad5f 2169 }
sPymbed 17:ff9d1e86ad5f 2170
sPymbed 17:ff9d1e86ad5f 2171 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 2172 /* Find the cipher suite in the suites set in the SSL.
sPymbed 17:ff9d1e86ad5f 2173 *
sPymbed 17:ff9d1e86ad5f 2174 * ssl SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 2175 * suite Cipher suite to look for.
sPymbed 17:ff9d1e86ad5f 2176 * returns 1 when suite is found in SSL/TLS object's list and 0 otherwise.
sPymbed 17:ff9d1e86ad5f 2177 */
sPymbed 17:ff9d1e86ad5f 2178 static int FindSuite(WOLFSSL* ssl, byte* suite)
sPymbed 17:ff9d1e86ad5f 2179 {
sPymbed 17:ff9d1e86ad5f 2180 int i;
sPymbed 17:ff9d1e86ad5f 2181
sPymbed 17:ff9d1e86ad5f 2182 for (i = 0; i < ssl->suites->suiteSz; i += 2) {
sPymbed 17:ff9d1e86ad5f 2183 if (ssl->suites->suites[i+0] == suite[0] &&
sPymbed 17:ff9d1e86ad5f 2184 ssl->suites->suites[i+1] == suite[1]) {
sPymbed 17:ff9d1e86ad5f 2185 return 1;
sPymbed 17:ff9d1e86ad5f 2186 }
sPymbed 17:ff9d1e86ad5f 2187 }
sPymbed 17:ff9d1e86ad5f 2188
sPymbed 17:ff9d1e86ad5f 2189 return 0;
sPymbed 17:ff9d1e86ad5f 2190 }
sPymbed 17:ff9d1e86ad5f 2191 #endif
sPymbed 17:ff9d1e86ad5f 2192
sPymbed 17:ff9d1e86ad5f 2193 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2194 #if defined(WOLFSSL_SEND_HRR_COOKIE) && !defined(NO_WOLFSSL_SERVER)
sPymbed 17:ff9d1e86ad5f 2195 /* Create Cookie extension using the hash of the first ClientHello.
sPymbed 17:ff9d1e86ad5f 2196 *
sPymbed 17:ff9d1e86ad5f 2197 * ssl SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 2198 * hash The hash data.
sPymbed 17:ff9d1e86ad5f 2199 * hashSz The size of the hash data in bytes.
sPymbed 17:ff9d1e86ad5f 2200 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 2201 */
sPymbed 17:ff9d1e86ad5f 2202 static int CreateCookie(WOLFSSL* ssl, byte* hash, byte hashSz)
sPymbed 17:ff9d1e86ad5f 2203 {
sPymbed 17:ff9d1e86ad5f 2204 int ret;
sPymbed 17:ff9d1e86ad5f 2205 byte mac[WC_MAX_DIGEST_SIZE];
sPymbed 17:ff9d1e86ad5f 2206 Hmac cookieHmac;
sPymbed 17:ff9d1e86ad5f 2207 byte cookieType;
sPymbed 17:ff9d1e86ad5f 2208 byte macSz;
sPymbed 17:ff9d1e86ad5f 2209
sPymbed 17:ff9d1e86ad5f 2210 #if !defined(NO_SHA) && defined(NO_SHA256)
sPymbed 17:ff9d1e86ad5f 2211 cookieType = SHA;
sPymbed 17:ff9d1e86ad5f 2212 macSz = WC_SHA_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 2213 #endif /* NO_SHA */
sPymbed 17:ff9d1e86ad5f 2214 #ifndef NO_SHA256
sPymbed 17:ff9d1e86ad5f 2215 cookieType = WC_SHA256;
sPymbed 17:ff9d1e86ad5f 2216 macSz = WC_SHA256_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 2217 #endif /* NO_SHA256 */
sPymbed 17:ff9d1e86ad5f 2218
sPymbed 17:ff9d1e86ad5f 2219 ret = wc_HmacSetKey(&cookieHmac, cookieType,
sPymbed 17:ff9d1e86ad5f 2220 ssl->buffers.tls13CookieSecret.buffer,
sPymbed 17:ff9d1e86ad5f 2221 ssl->buffers.tls13CookieSecret.length);
sPymbed 17:ff9d1e86ad5f 2222 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2223 return ret;
sPymbed 17:ff9d1e86ad5f 2224 if ((ret = wc_HmacUpdate(&cookieHmac, hash, hashSz)) != 0)
sPymbed 17:ff9d1e86ad5f 2225 return ret;
sPymbed 17:ff9d1e86ad5f 2226 if ((ret = wc_HmacFinal(&cookieHmac, mac)) != 0)
sPymbed 17:ff9d1e86ad5f 2227 return ret;
sPymbed 17:ff9d1e86ad5f 2228
sPymbed 17:ff9d1e86ad5f 2229 /* The cookie data is the hash and the integrity check. */
sPymbed 17:ff9d1e86ad5f 2230 return TLSX_Cookie_Use(ssl, hash, hashSz, mac, macSz, 1);
sPymbed 17:ff9d1e86ad5f 2231 }
sPymbed 17:ff9d1e86ad5f 2232 #endif
sPymbed 17:ff9d1e86ad5f 2233
sPymbed 17:ff9d1e86ad5f 2234 /* Restart the Hanshake hash with a hash of the previous messages.
sPymbed 17:ff9d1e86ad5f 2235 *
sPymbed 17:ff9d1e86ad5f 2236 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 2237 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 2238 */
sPymbed 17:ff9d1e86ad5f 2239 static int RestartHandshakeHash(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 2240 {
sPymbed 17:ff9d1e86ad5f 2241 int ret;
sPymbed 17:ff9d1e86ad5f 2242 Hashes hashes;
sPymbed 17:ff9d1e86ad5f 2243 byte header[HANDSHAKE_HEADER_SZ];
sPymbed 17:ff9d1e86ad5f 2244 byte* hash = NULL;
sPymbed 17:ff9d1e86ad5f 2245 byte hashSz = 0;
sPymbed 17:ff9d1e86ad5f 2246
sPymbed 17:ff9d1e86ad5f 2247 ret = BuildCertHashes(ssl, &hashes);
sPymbed 17:ff9d1e86ad5f 2248 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2249 return ret;
sPymbed 17:ff9d1e86ad5f 2250 switch (ssl->specs.mac_algorithm) {
sPymbed 17:ff9d1e86ad5f 2251 #ifndef NO_SHA256
sPymbed 17:ff9d1e86ad5f 2252 case sha256_mac:
sPymbed 17:ff9d1e86ad5f 2253 hash = hashes.sha256;
sPymbed 17:ff9d1e86ad5f 2254 break;
sPymbed 17:ff9d1e86ad5f 2255 #endif
sPymbed 17:ff9d1e86ad5f 2256 #ifdef WOLFSSL_SHA384
sPymbed 17:ff9d1e86ad5f 2257 case sha384_mac:
sPymbed 17:ff9d1e86ad5f 2258 hash = hashes.sha384;
sPymbed 17:ff9d1e86ad5f 2259 break;
sPymbed 17:ff9d1e86ad5f 2260 #endif
sPymbed 17:ff9d1e86ad5f 2261 #ifdef WOLFSSL_TLS13_SHA512
sPymbed 17:ff9d1e86ad5f 2262 case sha512_mac:
sPymbed 17:ff9d1e86ad5f 2263 hash = hashes.sha512;
sPymbed 17:ff9d1e86ad5f 2264 break;
sPymbed 17:ff9d1e86ad5f 2265 #endif
sPymbed 17:ff9d1e86ad5f 2266 }
sPymbed 17:ff9d1e86ad5f 2267 hashSz = ssl->specs.hash_size;
sPymbed 17:ff9d1e86ad5f 2268 AddTls13HandShakeHeader(header, hashSz, 0, 0, message_hash, ssl);
sPymbed 17:ff9d1e86ad5f 2269
sPymbed 17:ff9d1e86ad5f 2270 WOLFSSL_MSG("Restart Hash");
sPymbed 17:ff9d1e86ad5f 2271 WOLFSSL_BUFFER(hash, hashSz);
sPymbed 17:ff9d1e86ad5f 2272
sPymbed 17:ff9d1e86ad5f 2273 #if defined(WOLFSSL_SEND_HRR_COOKIE) && !defined(NO_WOLFSSL_SERVER)
sPymbed 17:ff9d1e86ad5f 2274 if (ssl->options.sendCookie) {
sPymbed 17:ff9d1e86ad5f 2275 byte cookie[OPAQUE8_LEN + WC_MAX_DIGEST_SIZE + OPAQUE16_LEN * 2];
sPymbed 17:ff9d1e86ad5f 2276 TLSX* ext;
sPymbed 17:ff9d1e86ad5f 2277 word32 idx = 0;
sPymbed 17:ff9d1e86ad5f 2278
sPymbed 17:ff9d1e86ad5f 2279 /* Cookie Data = Hash Len | Hash | CS | KeyShare Group */
sPymbed 17:ff9d1e86ad5f 2280 cookie[idx++] = hashSz;
sPymbed 17:ff9d1e86ad5f 2281 XMEMCPY(cookie + idx, hash, hashSz);
sPymbed 17:ff9d1e86ad5f 2282 idx += hashSz;
sPymbed 17:ff9d1e86ad5f 2283 cookie[idx++] = ssl->options.cipherSuite0;
sPymbed 17:ff9d1e86ad5f 2284 cookie[idx++] = ssl->options.cipherSuite;
sPymbed 17:ff9d1e86ad5f 2285 if ((ext = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE)) != NULL) {
sPymbed 17:ff9d1e86ad5f 2286 KeyShareEntry* kse = (KeyShareEntry*)ext->data;
sPymbed 17:ff9d1e86ad5f 2287 c16toa(kse->group, cookie + idx);
sPymbed 17:ff9d1e86ad5f 2288 idx += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 2289 }
sPymbed 17:ff9d1e86ad5f 2290 return CreateCookie(ssl, cookie, idx);
sPymbed 17:ff9d1e86ad5f 2291 }
sPymbed 17:ff9d1e86ad5f 2292 #endif
sPymbed 17:ff9d1e86ad5f 2293
sPymbed 17:ff9d1e86ad5f 2294 ret = InitHandshakeHashes(ssl);
sPymbed 17:ff9d1e86ad5f 2295 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2296 return ret;
sPymbed 17:ff9d1e86ad5f 2297 ret = HashOutputRaw(ssl, header, sizeof(header));
sPymbed 17:ff9d1e86ad5f 2298 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2299 return ret;
sPymbed 17:ff9d1e86ad5f 2300 return HashOutputRaw(ssl, hash, hashSz);
sPymbed 17:ff9d1e86ad5f 2301 }
sPymbed 17:ff9d1e86ad5f 2302
sPymbed 17:ff9d1e86ad5f 2303 /* The value in the random field of a ServerHello to indicate
sPymbed 17:ff9d1e86ad5f 2304 * HelloRetryRequest.
sPymbed 17:ff9d1e86ad5f 2305 */
sPymbed 17:ff9d1e86ad5f 2306 static byte helloRetryRequestRandom[] = {
sPymbed 17:ff9d1e86ad5f 2307 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
sPymbed 17:ff9d1e86ad5f 2308 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
sPymbed 17:ff9d1e86ad5f 2309 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E,
sPymbed 17:ff9d1e86ad5f 2310 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C
sPymbed 17:ff9d1e86ad5f 2311 };
sPymbed 17:ff9d1e86ad5f 2312 #endif /* WOLFSSL_TLS13_DRAFT_18 */
sPymbed 17:ff9d1e86ad5f 2313
sPymbed 17:ff9d1e86ad5f 2314 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 2315 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 2316 /* Setup pre-shared key based on the details in the extension data.
sPymbed 17:ff9d1e86ad5f 2317 *
sPymbed 17:ff9d1e86ad5f 2318 * ssl SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 2319 * psk Pre-shared key extension data.
sPymbed 17:ff9d1e86ad5f 2320 * returns 0 on success, PSK_KEY_ERROR when the client PSK callback fails and
sPymbed 17:ff9d1e86ad5f 2321 * other negative value on failure.
sPymbed 17:ff9d1e86ad5f 2322 */
sPymbed 17:ff9d1e86ad5f 2323 static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk)
sPymbed 17:ff9d1e86ad5f 2324 {
sPymbed 17:ff9d1e86ad5f 2325 int ret;
sPymbed 17:ff9d1e86ad5f 2326 byte suite[2];
sPymbed 17:ff9d1e86ad5f 2327
sPymbed 17:ff9d1e86ad5f 2328 if (ssl->options.noPskDheKe && ssl->arrays->preMasterSz != 0)
sPymbed 17:ff9d1e86ad5f 2329 return PSK_KEY_ERROR;
sPymbed 17:ff9d1e86ad5f 2330
sPymbed 17:ff9d1e86ad5f 2331 suite[0] = psk->cipherSuite0;
sPymbed 17:ff9d1e86ad5f 2332 suite[1] = psk->cipherSuite;
sPymbed 17:ff9d1e86ad5f 2333 if (!FindSuite(ssl, suite))
sPymbed 17:ff9d1e86ad5f 2334 return PSK_KEY_ERROR;
sPymbed 17:ff9d1e86ad5f 2335
sPymbed 17:ff9d1e86ad5f 2336 ssl->options.cipherSuite0 = psk->cipherSuite0;
sPymbed 17:ff9d1e86ad5f 2337 ssl->options.cipherSuite = psk->cipherSuite;
sPymbed 17:ff9d1e86ad5f 2338 if ((ret = SetCipherSpecs(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 2339 return ret;
sPymbed 17:ff9d1e86ad5f 2340
sPymbed 17:ff9d1e86ad5f 2341 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 2342 if (psk->resumption) {
sPymbed 17:ff9d1e86ad5f 2343 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 2344 if (ssl->session.maxEarlyDataSz == 0)
sPymbed 17:ff9d1e86ad5f 2345 ssl->earlyData = no_early_data;
sPymbed 17:ff9d1e86ad5f 2346 #endif
sPymbed 17:ff9d1e86ad5f 2347 /* Resumption PSK is master secret. */
sPymbed 17:ff9d1e86ad5f 2348 ssl->arrays->psk_keySz = ssl->specs.hash_size;
sPymbed 17:ff9d1e86ad5f 2349 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2350 XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret,
sPymbed 17:ff9d1e86ad5f 2351 ssl->arrays->psk_keySz);
sPymbed 17:ff9d1e86ad5f 2352 #else
sPymbed 17:ff9d1e86ad5f 2353 if ((ret = DeriveResumptionPSK(ssl, ssl->session.ticketNonce.data,
sPymbed 17:ff9d1e86ad5f 2354 ssl->session.ticketNonce.len, ssl->arrays->psk_key)) != 0) {
sPymbed 17:ff9d1e86ad5f 2355 return ret;
sPymbed 17:ff9d1e86ad5f 2356 }
sPymbed 17:ff9d1e86ad5f 2357 #endif
sPymbed 17:ff9d1e86ad5f 2358 }
sPymbed 17:ff9d1e86ad5f 2359 #endif
sPymbed 17:ff9d1e86ad5f 2360 #ifndef NO_PSK
sPymbed 17:ff9d1e86ad5f 2361 if (!psk->resumption) {
sPymbed 17:ff9d1e86ad5f 2362 /* Get the pre-shared key. */
sPymbed 17:ff9d1e86ad5f 2363 ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
sPymbed 17:ff9d1e86ad5f 2364 (char *)psk->identity, ssl->arrays->client_identity,
sPymbed 17:ff9d1e86ad5f 2365 MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
sPymbed 17:ff9d1e86ad5f 2366 if (ssl->arrays->psk_keySz == 0 ||
sPymbed 17:ff9d1e86ad5f 2367 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
sPymbed 17:ff9d1e86ad5f 2368 return PSK_KEY_ERROR;
sPymbed 17:ff9d1e86ad5f 2369 }
sPymbed 17:ff9d1e86ad5f 2370 /* TODO: Callback should be able to specify ciphersuite. */
sPymbed 17:ff9d1e86ad5f 2371
sPymbed 17:ff9d1e86ad5f 2372 if (psk->cipherSuite0 != TLS13_BYTE ||
sPymbed 17:ff9d1e86ad5f 2373 psk->cipherSuite != WOLFSSL_DEF_PSK_CIPHER) {
sPymbed 17:ff9d1e86ad5f 2374 return PSK_KEY_ERROR;
sPymbed 17:ff9d1e86ad5f 2375 }
sPymbed 17:ff9d1e86ad5f 2376 }
sPymbed 17:ff9d1e86ad5f 2377 #endif
sPymbed 17:ff9d1e86ad5f 2378
sPymbed 17:ff9d1e86ad5f 2379 /* Derive the early secret using the PSK. */
sPymbed 17:ff9d1e86ad5f 2380 return DeriveEarlySecret(ssl);
sPymbed 17:ff9d1e86ad5f 2381 }
sPymbed 17:ff9d1e86ad5f 2382
sPymbed 17:ff9d1e86ad5f 2383 /* Derive and write the binders into the ClientHello in space left when
sPymbed 17:ff9d1e86ad5f 2384 * writing the Pre-Shared Key extension.
sPymbed 17:ff9d1e86ad5f 2385 *
sPymbed 17:ff9d1e86ad5f 2386 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 2387 * output The buffer containing the ClientHello.
sPymbed 17:ff9d1e86ad5f 2388 * idx The index at the end of the completed ClientHello.
sPymbed 17:ff9d1e86ad5f 2389 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 2390 */
sPymbed 17:ff9d1e86ad5f 2391 static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
sPymbed 17:ff9d1e86ad5f 2392 {
sPymbed 17:ff9d1e86ad5f 2393 int ret;
sPymbed 17:ff9d1e86ad5f 2394 TLSX* ext;
sPymbed 17:ff9d1e86ad5f 2395 PreSharedKey* current;
sPymbed 17:ff9d1e86ad5f 2396 byte binderKey[WC_MAX_DIGEST_SIZE];
sPymbed 17:ff9d1e86ad5f 2397 word16 len;
sPymbed 17:ff9d1e86ad5f 2398
sPymbed 17:ff9d1e86ad5f 2399 WOLFSSL_ENTER("WritePSKBinders");
sPymbed 17:ff9d1e86ad5f 2400
sPymbed 17:ff9d1e86ad5f 2401 ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
sPymbed 17:ff9d1e86ad5f 2402 if (ext == NULL)
sPymbed 17:ff9d1e86ad5f 2403 return SANITY_MSG_E;
sPymbed 17:ff9d1e86ad5f 2404
sPymbed 17:ff9d1e86ad5f 2405 /* Get the size of the binders to determine where to write binders. */
sPymbed 17:ff9d1e86ad5f 2406 idx -= TLSX_PreSharedKey_GetSizeBinders((PreSharedKey*)ext->data,
sPymbed 17:ff9d1e86ad5f 2407 client_hello);
sPymbed 17:ff9d1e86ad5f 2408
sPymbed 17:ff9d1e86ad5f 2409 /* Hash truncated ClientHello - up to binders. */
sPymbed 17:ff9d1e86ad5f 2410 ret = HashOutput(ssl, output, idx, 0);
sPymbed 17:ff9d1e86ad5f 2411 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2412 return ret;
sPymbed 17:ff9d1e86ad5f 2413
sPymbed 17:ff9d1e86ad5f 2414 current = (PreSharedKey*)ext->data;
sPymbed 17:ff9d1e86ad5f 2415 /* Calculate the binder for each identity based on previous handshake data.
sPymbed 17:ff9d1e86ad5f 2416 */
sPymbed 17:ff9d1e86ad5f 2417 while (current != NULL) {
sPymbed 17:ff9d1e86ad5f 2418 if ((ret = SetupPskKey(ssl, current)) != 0)
sPymbed 17:ff9d1e86ad5f 2419 return ret;
sPymbed 17:ff9d1e86ad5f 2420
sPymbed 17:ff9d1e86ad5f 2421 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 2422 if (current->resumption)
sPymbed 17:ff9d1e86ad5f 2423 ret = DeriveBinderKeyResume(ssl, binderKey);
sPymbed 17:ff9d1e86ad5f 2424 #endif
sPymbed 17:ff9d1e86ad5f 2425 #ifndef NO_PSK
sPymbed 17:ff9d1e86ad5f 2426 if (!current->resumption)
sPymbed 17:ff9d1e86ad5f 2427 ret = DeriveBinderKey(ssl, binderKey);
sPymbed 17:ff9d1e86ad5f 2428 #endif
sPymbed 17:ff9d1e86ad5f 2429 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2430 return ret;
sPymbed 17:ff9d1e86ad5f 2431
sPymbed 17:ff9d1e86ad5f 2432 /* Derive the Finished message secret. */
sPymbed 17:ff9d1e86ad5f 2433 ret = DeriveFinishedSecret(ssl, binderKey,
sPymbed 17:ff9d1e86ad5f 2434 ssl->keys.client_write_MAC_secret);
sPymbed 17:ff9d1e86ad5f 2435 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2436 return ret;
sPymbed 17:ff9d1e86ad5f 2437
sPymbed 17:ff9d1e86ad5f 2438 /* Build the HMAC of the handshake message data = binder. */
sPymbed 17:ff9d1e86ad5f 2439 ret = BuildTls13HandshakeHmac(ssl, ssl->keys.client_write_MAC_secret,
sPymbed 17:ff9d1e86ad5f 2440 current->binder, &current->binderLen);
sPymbed 17:ff9d1e86ad5f 2441 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2442 return ret;
sPymbed 17:ff9d1e86ad5f 2443
sPymbed 17:ff9d1e86ad5f 2444 current = current->next;
sPymbed 17:ff9d1e86ad5f 2445 }
sPymbed 17:ff9d1e86ad5f 2446
sPymbed 17:ff9d1e86ad5f 2447 /* Data entered into extension, now write to message. */
sPymbed 17:ff9d1e86ad5f 2448 len = TLSX_PreSharedKey_WriteBinders((PreSharedKey*)ext->data, output + idx,
sPymbed 17:ff9d1e86ad5f 2449 client_hello);
sPymbed 17:ff9d1e86ad5f 2450
sPymbed 17:ff9d1e86ad5f 2451 /* Hash binders to complete the hash of the ClientHello. */
sPymbed 17:ff9d1e86ad5f 2452 ret = HashOutputRaw(ssl, output + idx, len);
sPymbed 17:ff9d1e86ad5f 2453 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 2454 return ret;
sPymbed 17:ff9d1e86ad5f 2455
sPymbed 17:ff9d1e86ad5f 2456 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 2457 if (ssl->earlyData != no_early_data) {
sPymbed 17:ff9d1e86ad5f 2458 if ((ret = SetupPskKey(ssl, (PreSharedKey*)ext->data)) != 0)
sPymbed 17:ff9d1e86ad5f 2459 return ret;
sPymbed 17:ff9d1e86ad5f 2460
sPymbed 17:ff9d1e86ad5f 2461 /* Derive early data encryption key. */
sPymbed 17:ff9d1e86ad5f 2462 ret = DeriveTls13Keys(ssl, early_data_key, ENCRYPT_SIDE_ONLY, 1);
sPymbed 17:ff9d1e86ad5f 2463 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2464 return ret;
sPymbed 17:ff9d1e86ad5f 2465 if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
sPymbed 17:ff9d1e86ad5f 2466 return ret;
sPymbed 17:ff9d1e86ad5f 2467 }
sPymbed 17:ff9d1e86ad5f 2468 #endif
sPymbed 17:ff9d1e86ad5f 2469
sPymbed 17:ff9d1e86ad5f 2470 WOLFSSL_LEAVE("WritePSKBinders", ret);
sPymbed 17:ff9d1e86ad5f 2471
sPymbed 17:ff9d1e86ad5f 2472 return ret;
sPymbed 17:ff9d1e86ad5f 2473 }
sPymbed 17:ff9d1e86ad5f 2474 #endif
sPymbed 17:ff9d1e86ad5f 2475
sPymbed 17:ff9d1e86ad5f 2476 /* handle generation of TLS 1.3 client_hello (1) */
sPymbed 17:ff9d1e86ad5f 2477 /* Send a ClientHello message to the server.
sPymbed 17:ff9d1e86ad5f 2478 * Include the information required to start a handshake with servers using
sPymbed 17:ff9d1e86ad5f 2479 * protocol versions less than TLS v1.3.
sPymbed 17:ff9d1e86ad5f 2480 * Only a client will send this message.
sPymbed 17:ff9d1e86ad5f 2481 *
sPymbed 17:ff9d1e86ad5f 2482 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 2483 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 2484 */
sPymbed 17:ff9d1e86ad5f 2485 int SendTls13ClientHello(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 2486 {
sPymbed 17:ff9d1e86ad5f 2487 byte* output;
sPymbed 17:ff9d1e86ad5f 2488 word16 length;
sPymbed 17:ff9d1e86ad5f 2489 word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 2490 int sendSz;
sPymbed 17:ff9d1e86ad5f 2491 int ret;
sPymbed 17:ff9d1e86ad5f 2492
sPymbed 17:ff9d1e86ad5f 2493 WOLFSSL_START(WC_FUNC_CLIENT_HELLO_SEND);
sPymbed 17:ff9d1e86ad5f 2494 WOLFSSL_ENTER("SendTls13ClientHello");
sPymbed 17:ff9d1e86ad5f 2495
sPymbed 17:ff9d1e86ad5f 2496 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 2497 if (ssl->options.resuming &&
sPymbed 17:ff9d1e86ad5f 2498 (ssl->session.version.major != ssl->version.major ||
sPymbed 17:ff9d1e86ad5f 2499 ssl->session.version.minor != ssl->version.minor)) {
sPymbed 17:ff9d1e86ad5f 2500 #ifndef WOLFSSL_NO_TLS12
sPymbed 17:ff9d1e86ad5f 2501 if (ssl->session.version.major == ssl->version.major &&
sPymbed 17:ff9d1e86ad5f 2502 ssl->session.version.minor < ssl->version.minor) {
sPymbed 17:ff9d1e86ad5f 2503 /* Cannot resume with a different protocol version. */
sPymbed 17:ff9d1e86ad5f 2504 ssl->options.resuming = 0;
sPymbed 17:ff9d1e86ad5f 2505 ssl->version.major = ssl->session.version.major;
sPymbed 17:ff9d1e86ad5f 2506 ssl->version.minor = ssl->session.version.minor;
sPymbed 17:ff9d1e86ad5f 2507 return SendClientHello(ssl);
sPymbed 17:ff9d1e86ad5f 2508 }
sPymbed 17:ff9d1e86ad5f 2509 else
sPymbed 17:ff9d1e86ad5f 2510 #endif
sPymbed 17:ff9d1e86ad5f 2511 return VERSION_ERROR;
sPymbed 17:ff9d1e86ad5f 2512 }
sPymbed 17:ff9d1e86ad5f 2513 #endif
sPymbed 17:ff9d1e86ad5f 2514
sPymbed 17:ff9d1e86ad5f 2515 if (ssl->suites == NULL) {
sPymbed 17:ff9d1e86ad5f 2516 WOLFSSL_MSG("Bad suites pointer in SendTls13ClientHello");
sPymbed 17:ff9d1e86ad5f 2517 return SUITES_ERROR;
sPymbed 17:ff9d1e86ad5f 2518 }
sPymbed 17:ff9d1e86ad5f 2519
sPymbed 17:ff9d1e86ad5f 2520 /* Version | Random | Session Id | Cipher Suites | Compression */
sPymbed 17:ff9d1e86ad5f 2521 length = VERSION_SZ + RAN_LEN + ENUM_LEN + ssl->suites->suiteSz +
sPymbed 17:ff9d1e86ad5f 2522 SUITE_LEN + COMP_LEN + ENUM_LEN;
sPymbed 17:ff9d1e86ad5f 2523 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2524 #if defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
sPymbed 17:ff9d1e86ad5f 2525 length += ID_LEN;
sPymbed 17:ff9d1e86ad5f 2526 #else
sPymbed 17:ff9d1e86ad5f 2527 if (ssl->session.sessionIDSz > 0)
sPymbed 17:ff9d1e86ad5f 2528 length += ssl->session.sessionIDSz;
sPymbed 17:ff9d1e86ad5f 2529 #endif
sPymbed 17:ff9d1e86ad5f 2530 #endif
sPymbed 17:ff9d1e86ad5f 2531
sPymbed 17:ff9d1e86ad5f 2532 /* Auto populate extensions supported unless user defined. */
sPymbed 17:ff9d1e86ad5f 2533 if ((ret = TLSX_PopulateExtensions(ssl, 0)) != 0)
sPymbed 17:ff9d1e86ad5f 2534 return ret;
sPymbed 17:ff9d1e86ad5f 2535 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 2536 #ifndef NO_PSK
sPymbed 17:ff9d1e86ad5f 2537 if (!ssl->options.resuming && ssl->options.client_psk_cb == NULL)
sPymbed 17:ff9d1e86ad5f 2538 #else
sPymbed 17:ff9d1e86ad5f 2539 if (!ssl->options.resuming)
sPymbed 17:ff9d1e86ad5f 2540 #endif
sPymbed 17:ff9d1e86ad5f 2541 ssl->earlyData = no_early_data;
sPymbed 17:ff9d1e86ad5f 2542 if (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE)
sPymbed 17:ff9d1e86ad5f 2543 ssl->earlyData = no_early_data;
sPymbed 17:ff9d1e86ad5f 2544 if (ssl->earlyData == no_early_data)
sPymbed 17:ff9d1e86ad5f 2545 TLSX_Remove(&ssl->extensions, TLSX_EARLY_DATA, ssl->heap);
sPymbed 17:ff9d1e86ad5f 2546 if (ssl->earlyData != no_early_data &&
sPymbed 17:ff9d1e86ad5f 2547 (ret = TLSX_EarlyData_Use(ssl, 0)) < 0) {
sPymbed 17:ff9d1e86ad5f 2548 return ret;
sPymbed 17:ff9d1e86ad5f 2549 }
sPymbed 17:ff9d1e86ad5f 2550 #endif
sPymbed 17:ff9d1e86ad5f 2551 #ifdef HAVE_QSH
sPymbed 17:ff9d1e86ad5f 2552 if (QSH_Init(ssl) != 0)
sPymbed 17:ff9d1e86ad5f 2553 return MEMORY_E;
sPymbed 17:ff9d1e86ad5f 2554 #endif
sPymbed 17:ff9d1e86ad5f 2555 /* Include length of TLS extensions. */
sPymbed 17:ff9d1e86ad5f 2556 ret = TLSX_GetRequestSize(ssl, client_hello, &length);
sPymbed 17:ff9d1e86ad5f 2557 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2558 return ret;
sPymbed 17:ff9d1e86ad5f 2559
sPymbed 17:ff9d1e86ad5f 2560 /* Total message size. */
sPymbed 17:ff9d1e86ad5f 2561 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 2562
sPymbed 17:ff9d1e86ad5f 2563 /* Check buffers are big enough and grow if needed. */
sPymbed 17:ff9d1e86ad5f 2564 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
sPymbed 17:ff9d1e86ad5f 2565 return ret;
sPymbed 17:ff9d1e86ad5f 2566
sPymbed 17:ff9d1e86ad5f 2567 /* Get position in output buffer to write new message to. */
sPymbed 17:ff9d1e86ad5f 2568 output = ssl->buffers.outputBuffer.buffer +
sPymbed 17:ff9d1e86ad5f 2569 ssl->buffers.outputBuffer.length;
sPymbed 17:ff9d1e86ad5f 2570
sPymbed 17:ff9d1e86ad5f 2571 /* Put the record and handshake headers on. */
sPymbed 17:ff9d1e86ad5f 2572 AddTls13Headers(output, length, client_hello, ssl);
sPymbed 17:ff9d1e86ad5f 2573
sPymbed 17:ff9d1e86ad5f 2574 /* Protocol version - negotiation now in extension: supported_versions. */
sPymbed 17:ff9d1e86ad5f 2575 output[idx++] = SSLv3_MAJOR;
sPymbed 17:ff9d1e86ad5f 2576 output[idx++] = TLSv1_2_MINOR;
sPymbed 17:ff9d1e86ad5f 2577 /* Keep for downgrade. */
sPymbed 17:ff9d1e86ad5f 2578 ssl->chVersion = ssl->version;
sPymbed 17:ff9d1e86ad5f 2579
sPymbed 17:ff9d1e86ad5f 2580 /* Client Random */
sPymbed 17:ff9d1e86ad5f 2581 if (ssl->options.connectState == CONNECT_BEGIN) {
sPymbed 17:ff9d1e86ad5f 2582 ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN);
sPymbed 17:ff9d1e86ad5f 2583 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2584 return ret;
sPymbed 17:ff9d1e86ad5f 2585
sPymbed 17:ff9d1e86ad5f 2586 /* Store random for possible second ClientHello. */
sPymbed 17:ff9d1e86ad5f 2587 XMEMCPY(ssl->arrays->clientRandom, output + idx, RAN_LEN);
sPymbed 17:ff9d1e86ad5f 2588 }
sPymbed 17:ff9d1e86ad5f 2589 else
sPymbed 17:ff9d1e86ad5f 2590 XMEMCPY(output + idx, ssl->arrays->clientRandom, RAN_LEN);
sPymbed 17:ff9d1e86ad5f 2591 idx += RAN_LEN;
sPymbed 17:ff9d1e86ad5f 2592
sPymbed 17:ff9d1e86ad5f 2593 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2594 /* TLS v1.3 does not use session id - 0 length. */
sPymbed 17:ff9d1e86ad5f 2595 output[idx++] = 0;
sPymbed 17:ff9d1e86ad5f 2596 #else
sPymbed 17:ff9d1e86ad5f 2597 if (ssl->session.sessionIDSz > 0) {
sPymbed 17:ff9d1e86ad5f 2598 /* Session resumption for old versions of protocol. */
sPymbed 17:ff9d1e86ad5f 2599 output[idx++] = ID_LEN;
sPymbed 17:ff9d1e86ad5f 2600 XMEMCPY(output + idx, ssl->session.sessionID, ssl->session.sessionIDSz);
sPymbed 17:ff9d1e86ad5f 2601 idx += ID_LEN;
sPymbed 17:ff9d1e86ad5f 2602 }
sPymbed 17:ff9d1e86ad5f 2603 else {
sPymbed 17:ff9d1e86ad5f 2604 #ifdef WOLFSSL_TLS13_MIDDLEBOX_COMPAT
sPymbed 17:ff9d1e86ad5f 2605 output[idx++] = ID_LEN;
sPymbed 17:ff9d1e86ad5f 2606 XMEMCPY(output + idx, ssl->arrays->clientRandom, ID_LEN);
sPymbed 17:ff9d1e86ad5f 2607 idx += ID_LEN;
sPymbed 17:ff9d1e86ad5f 2608 #else
sPymbed 17:ff9d1e86ad5f 2609 /* TLS v1.3 does not use session id - 0 length. */
sPymbed 17:ff9d1e86ad5f 2610 output[idx++] = 0;
sPymbed 17:ff9d1e86ad5f 2611 #endif /* WOLFSSL_TLS13_MIDDLEBOX_COMPAT */
sPymbed 17:ff9d1e86ad5f 2612 }
sPymbed 17:ff9d1e86ad5f 2613 #endif /* WOLFSSL_TLS13_DRAFT_18 */
sPymbed 17:ff9d1e86ad5f 2614
sPymbed 17:ff9d1e86ad5f 2615 /* Cipher suites */
sPymbed 17:ff9d1e86ad5f 2616 c16toa(ssl->suites->suiteSz, output + idx);
sPymbed 17:ff9d1e86ad5f 2617 idx += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 2618 XMEMCPY(output + idx, &ssl->suites->suites, ssl->suites->suiteSz);
sPymbed 17:ff9d1e86ad5f 2619 idx += ssl->suites->suiteSz;
sPymbed 17:ff9d1e86ad5f 2620
sPymbed 17:ff9d1e86ad5f 2621 /* Compression not supported in TLS v1.3. */
sPymbed 17:ff9d1e86ad5f 2622 output[idx++] = COMP_LEN;
sPymbed 17:ff9d1e86ad5f 2623 output[idx++] = NO_COMPRESSION;
sPymbed 17:ff9d1e86ad5f 2624
sPymbed 17:ff9d1e86ad5f 2625 /* Write out extensions for a request. */
sPymbed 17:ff9d1e86ad5f 2626 length = 0;
sPymbed 17:ff9d1e86ad5f 2627 ret = TLSX_WriteRequest(ssl, output + idx, client_hello, &length);
sPymbed 17:ff9d1e86ad5f 2628 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2629 return ret;
sPymbed 17:ff9d1e86ad5f 2630 idx += length;
sPymbed 17:ff9d1e86ad5f 2631
sPymbed 17:ff9d1e86ad5f 2632 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 2633 /* Resumption has a specific set of extensions and binder is calculated
sPymbed 17:ff9d1e86ad5f 2634 * for each identity.
sPymbed 17:ff9d1e86ad5f 2635 */
sPymbed 17:ff9d1e86ad5f 2636 if (TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY))
sPymbed 17:ff9d1e86ad5f 2637 ret = WritePSKBinders(ssl, output, idx);
sPymbed 17:ff9d1e86ad5f 2638 else
sPymbed 17:ff9d1e86ad5f 2639 #endif
sPymbed 17:ff9d1e86ad5f 2640 ret = HashOutput(ssl, output, idx, 0);
sPymbed 17:ff9d1e86ad5f 2641 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2642 return ret;
sPymbed 17:ff9d1e86ad5f 2643
sPymbed 17:ff9d1e86ad5f 2644 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
sPymbed 17:ff9d1e86ad5f 2645
sPymbed 17:ff9d1e86ad5f 2646 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 2647 if (ssl->hsInfoOn) AddPacketName(ssl, "ClientHello");
sPymbed 17:ff9d1e86ad5f 2648 if (ssl->toInfoOn) {
sPymbed 17:ff9d1e86ad5f 2649 AddPacketInfo(ssl, "ClientHello", handshake, output, sendSz,
sPymbed 17:ff9d1e86ad5f 2650 WRITE_PROTO, ssl->heap);
sPymbed 17:ff9d1e86ad5f 2651 }
sPymbed 17:ff9d1e86ad5f 2652 #endif
sPymbed 17:ff9d1e86ad5f 2653
sPymbed 17:ff9d1e86ad5f 2654 ssl->buffers.outputBuffer.length += sendSz;
sPymbed 17:ff9d1e86ad5f 2655
sPymbed 17:ff9d1e86ad5f 2656 ret = SendBuffered(ssl);
sPymbed 17:ff9d1e86ad5f 2657
sPymbed 17:ff9d1e86ad5f 2658 WOLFSSL_LEAVE("SendTls13ClientHello", ret);
sPymbed 17:ff9d1e86ad5f 2659 WOLFSSL_END(WC_FUNC_CLIENT_HELLO_SEND);
sPymbed 17:ff9d1e86ad5f 2660
sPymbed 17:ff9d1e86ad5f 2661 return ret;
sPymbed 17:ff9d1e86ad5f 2662 }
sPymbed 17:ff9d1e86ad5f 2663
sPymbed 17:ff9d1e86ad5f 2664 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2665 /* handle rocessing of TLS 1.3 hello_retry_request (6) */
sPymbed 17:ff9d1e86ad5f 2666 /* Parse and handle a HelloRetryRequest message.
sPymbed 17:ff9d1e86ad5f 2667 * Only a client will receive this message.
sPymbed 17:ff9d1e86ad5f 2668 *
sPymbed 17:ff9d1e86ad5f 2669 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 2670 * input The message buffer.
sPymbed 17:ff9d1e86ad5f 2671 * inOutIdx On entry, the index into the message buffer of
sPymbed 17:ff9d1e86ad5f 2672 * HelloRetryRequest.
sPymbed 17:ff9d1e86ad5f 2673 * On exit, the index of byte after the HelloRetryRequest message.
sPymbed 17:ff9d1e86ad5f 2674 * totalSz The length of the current handshake message.
sPymbed 17:ff9d1e86ad5f 2675 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 2676 */
sPymbed 17:ff9d1e86ad5f 2677 static int DoTls13HelloRetryRequest(WOLFSSL* ssl, const byte* input,
sPymbed 17:ff9d1e86ad5f 2678 word32* inOutIdx, word32 totalSz)
sPymbed 17:ff9d1e86ad5f 2679 {
sPymbed 17:ff9d1e86ad5f 2680 int ret;
sPymbed 17:ff9d1e86ad5f 2681 word32 begin = *inOutIdx;
sPymbed 17:ff9d1e86ad5f 2682 word32 i = begin;
sPymbed 17:ff9d1e86ad5f 2683 word16 totalExtSz;
sPymbed 17:ff9d1e86ad5f 2684 ProtocolVersion pv;
sPymbed 17:ff9d1e86ad5f 2685
sPymbed 17:ff9d1e86ad5f 2686 WOLFSSL_ENTER("DoTls13HelloRetryRequest");
sPymbed 17:ff9d1e86ad5f 2687
sPymbed 17:ff9d1e86ad5f 2688 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 2689 if (ssl->hsInfoOn) AddPacketName(ssl, "HelloRetryRequest");
sPymbed 17:ff9d1e86ad5f 2690 if (ssl->toInfoOn) AddLateName("HelloRetryRequest", &ssl->timeoutInfo);
sPymbed 17:ff9d1e86ad5f 2691 #endif
sPymbed 17:ff9d1e86ad5f 2692
sPymbed 17:ff9d1e86ad5f 2693 /* Version info and length field of extension data. */
sPymbed 17:ff9d1e86ad5f 2694 if (totalSz < i - begin + OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
sPymbed 17:ff9d1e86ad5f 2695 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 2696
sPymbed 17:ff9d1e86ad5f 2697 /* Protocol version. */
sPymbed 17:ff9d1e86ad5f 2698 XMEMCPY(&pv, input + i, OPAQUE16_LEN);
sPymbed 17:ff9d1e86ad5f 2699 i += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 2700 ret = CheckVersion(ssl, pv);
sPymbed 17:ff9d1e86ad5f 2701 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2702 return ret;
sPymbed 17:ff9d1e86ad5f 2703
sPymbed 17:ff9d1e86ad5f 2704 /* Length of extension data. */
sPymbed 17:ff9d1e86ad5f 2705 ato16(&input[i], &totalExtSz);
sPymbed 17:ff9d1e86ad5f 2706 i += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 2707 if (totalExtSz == 0) {
sPymbed 17:ff9d1e86ad5f 2708 WOLFSSL_MSG("HelloRetryRequest must contain extensions");
sPymbed 17:ff9d1e86ad5f 2709 return MISSING_HANDSHAKE_DATA;
sPymbed 17:ff9d1e86ad5f 2710 }
sPymbed 17:ff9d1e86ad5f 2711
sPymbed 17:ff9d1e86ad5f 2712 /* Extension data. */
sPymbed 17:ff9d1e86ad5f 2713 if (i - begin + totalExtSz > totalSz)
sPymbed 17:ff9d1e86ad5f 2714 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 2715 if ((ret = TLSX_Parse(ssl, (byte *)(input + i), totalExtSz,
sPymbed 17:ff9d1e86ad5f 2716 hello_retry_request, NULL)) != 0)
sPymbed 17:ff9d1e86ad5f 2717 return ret;
sPymbed 17:ff9d1e86ad5f 2718 /* The KeyShare extension parsing fails when not valid. */
sPymbed 17:ff9d1e86ad5f 2719
sPymbed 17:ff9d1e86ad5f 2720 /* Move index to byte after message. */
sPymbed 17:ff9d1e86ad5f 2721 *inOutIdx = i + totalExtSz;
sPymbed 17:ff9d1e86ad5f 2722
sPymbed 17:ff9d1e86ad5f 2723 ssl->options.tls1_3 = 1;
sPymbed 17:ff9d1e86ad5f 2724 ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST_COMPLETE;
sPymbed 17:ff9d1e86ad5f 2725
sPymbed 17:ff9d1e86ad5f 2726 WOLFSSL_LEAVE("DoTls13HelloRetryRequest", ret);
sPymbed 17:ff9d1e86ad5f 2727
sPymbed 17:ff9d1e86ad5f 2728 return ret;
sPymbed 17:ff9d1e86ad5f 2729 }
sPymbed 17:ff9d1e86ad5f 2730 #endif
sPymbed 17:ff9d1e86ad5f 2731
sPymbed 17:ff9d1e86ad5f 2732
sPymbed 17:ff9d1e86ad5f 2733 /* handle processing of TLS 1.3 server_hello (2) and hello_retry_request (6) */
sPymbed 17:ff9d1e86ad5f 2734 /* Handle the ServerHello message from the server.
sPymbed 17:ff9d1e86ad5f 2735 * Only a client will receive this message.
sPymbed 17:ff9d1e86ad5f 2736 *
sPymbed 17:ff9d1e86ad5f 2737 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 2738 * input The message buffer.
sPymbed 17:ff9d1e86ad5f 2739 * inOutIdx On entry, the index into the message buffer of ServerHello.
sPymbed 17:ff9d1e86ad5f 2740 * On exit, the index of byte after the ServerHello message.
sPymbed 17:ff9d1e86ad5f 2741 * helloSz The length of the current handshake message.
sPymbed 17:ff9d1e86ad5f 2742 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 2743 */
sPymbed 17:ff9d1e86ad5f 2744 int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
sPymbed 17:ff9d1e86ad5f 2745 word32 helloSz, byte* extMsgType)
sPymbed 17:ff9d1e86ad5f 2746 {
sPymbed 17:ff9d1e86ad5f 2747 ProtocolVersion pv;
sPymbed 17:ff9d1e86ad5f 2748 word32 i = *inOutIdx;
sPymbed 17:ff9d1e86ad5f 2749 word32 begin = i;
sPymbed 17:ff9d1e86ad5f 2750 int ret;
sPymbed 17:ff9d1e86ad5f 2751 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2752 byte sessIdSz;
sPymbed 17:ff9d1e86ad5f 2753 const byte* sessId;
sPymbed 17:ff9d1e86ad5f 2754 byte b;
sPymbed 17:ff9d1e86ad5f 2755 #endif
sPymbed 17:ff9d1e86ad5f 2756 word16 totalExtSz;
sPymbed 17:ff9d1e86ad5f 2757 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 2758 TLSX* ext;
sPymbed 17:ff9d1e86ad5f 2759 PreSharedKey* psk = NULL;
sPymbed 17:ff9d1e86ad5f 2760 #endif
sPymbed 17:ff9d1e86ad5f 2761
sPymbed 17:ff9d1e86ad5f 2762 WOLFSSL_START(WC_FUNC_SERVER_HELLO_DO);
sPymbed 17:ff9d1e86ad5f 2763 WOLFSSL_ENTER("DoTls13ServerHello");
sPymbed 17:ff9d1e86ad5f 2764
sPymbed 17:ff9d1e86ad5f 2765 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 2766 if (ssl->hsInfoOn) AddPacketName(ssl, "ServerHello");
sPymbed 17:ff9d1e86ad5f 2767 if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
sPymbed 17:ff9d1e86ad5f 2768 #endif
sPymbed 17:ff9d1e86ad5f 2769
sPymbed 17:ff9d1e86ad5f 2770 /* Protocol version length check. */
sPymbed 17:ff9d1e86ad5f 2771 if (OPAQUE16_LEN > helloSz)
sPymbed 17:ff9d1e86ad5f 2772 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 2773
sPymbed 17:ff9d1e86ad5f 2774 /* Protocol version */
sPymbed 17:ff9d1e86ad5f 2775 XMEMCPY(&pv, input + i, OPAQUE16_LEN);
sPymbed 17:ff9d1e86ad5f 2776 i += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 2777 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2778 ret = CheckVersion(ssl, pv);
sPymbed 17:ff9d1e86ad5f 2779 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2780 return ret;
sPymbed 17:ff9d1e86ad5f 2781 if (!IsAtLeastTLSv1_3(pv) && pv.major != TLS_DRAFT_MAJOR) {
sPymbed 17:ff9d1e86ad5f 2782 #ifndef WOLFSSL_NO_TLS12
sPymbed 17:ff9d1e86ad5f 2783 if (ssl->options.downgrade) {
sPymbed 17:ff9d1e86ad5f 2784 ssl->version = pv;
sPymbed 17:ff9d1e86ad5f 2785 return DoServerHello(ssl, input, inOutIdx, helloSz);
sPymbed 17:ff9d1e86ad5f 2786 }
sPymbed 17:ff9d1e86ad5f 2787 #endif
sPymbed 17:ff9d1e86ad5f 2788
sPymbed 17:ff9d1e86ad5f 2789 WOLFSSL_MSG("Client using higher version, fatal error");
sPymbed 17:ff9d1e86ad5f 2790 return VERSION_ERROR;
sPymbed 17:ff9d1e86ad5f 2791 }
sPymbed 17:ff9d1e86ad5f 2792 #else
sPymbed 17:ff9d1e86ad5f 2793 #ifndef WOLFSSL_NO_TLS12
sPymbed 17:ff9d1e86ad5f 2794 if (pv.major == ssl->version.major && pv.minor < TLSv1_2_MINOR &&
sPymbed 17:ff9d1e86ad5f 2795 ssl->options.downgrade) {
sPymbed 17:ff9d1e86ad5f 2796 /* Force client hello version 1.2 to work for static RSA. */
sPymbed 17:ff9d1e86ad5f 2797 ssl->chVersion.minor = TLSv1_2_MINOR;
sPymbed 17:ff9d1e86ad5f 2798 ssl->version.minor = TLSv1_2_MINOR;
sPymbed 17:ff9d1e86ad5f 2799 return DoServerHello(ssl, input, inOutIdx, helloSz);
sPymbed 17:ff9d1e86ad5f 2800 }
sPymbed 17:ff9d1e86ad5f 2801 #endif
sPymbed 17:ff9d1e86ad5f 2802 if (pv.major != ssl->version.major || pv.minor != TLSv1_2_MINOR)
sPymbed 17:ff9d1e86ad5f 2803 return VERSION_ERROR;
sPymbed 17:ff9d1e86ad5f 2804 #endif
sPymbed 17:ff9d1e86ad5f 2805
sPymbed 17:ff9d1e86ad5f 2806 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2807 /* Random length check */
sPymbed 17:ff9d1e86ad5f 2808 if ((i - begin) + RAN_LEN > helloSz)
sPymbed 17:ff9d1e86ad5f 2809 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 2810 #else
sPymbed 17:ff9d1e86ad5f 2811 /* Random and session id length check */
sPymbed 17:ff9d1e86ad5f 2812 if ((i - begin) + RAN_LEN + ENUM_LEN > helloSz)
sPymbed 17:ff9d1e86ad5f 2813 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 2814
sPymbed 17:ff9d1e86ad5f 2815 if (XMEMCMP(input + i, helloRetryRequestRandom, RAN_LEN) == 0)
sPymbed 17:ff9d1e86ad5f 2816 *extMsgType = hello_retry_request;
sPymbed 17:ff9d1e86ad5f 2817 #endif
sPymbed 17:ff9d1e86ad5f 2818
sPymbed 17:ff9d1e86ad5f 2819 /* Server random - keep for debugging. */
sPymbed 17:ff9d1e86ad5f 2820 XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
sPymbed 17:ff9d1e86ad5f 2821 i += RAN_LEN;
sPymbed 17:ff9d1e86ad5f 2822
sPymbed 17:ff9d1e86ad5f 2823 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2824 /* Session id */
sPymbed 17:ff9d1e86ad5f 2825 sessIdSz = input[i++];
sPymbed 17:ff9d1e86ad5f 2826 if ((i - begin) + sessIdSz > helloSz)
sPymbed 17:ff9d1e86ad5f 2827 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 2828 sessId = input + i;
sPymbed 17:ff9d1e86ad5f 2829 i += sessIdSz;
sPymbed 17:ff9d1e86ad5f 2830 #endif /* WOLFSSL_TLS13_DRAFT_18 */
sPymbed 17:ff9d1e86ad5f 2831 ssl->options.haveSessionId = 1;
sPymbed 17:ff9d1e86ad5f 2832
sPymbed 17:ff9d1e86ad5f 2833 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2834 /* Ciphersuite check */
sPymbed 17:ff9d1e86ad5f 2835 if ((i - begin) + OPAQUE16_LEN + OPAQUE16_LEN > helloSz)
sPymbed 17:ff9d1e86ad5f 2836 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 2837 #else
sPymbed 17:ff9d1e86ad5f 2838 /* Ciphersuite and compression check */
sPymbed 17:ff9d1e86ad5f 2839 if ((i - begin) + OPAQUE16_LEN + OPAQUE8_LEN > helloSz)
sPymbed 17:ff9d1e86ad5f 2840 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 2841 #endif
sPymbed 17:ff9d1e86ad5f 2842
sPymbed 17:ff9d1e86ad5f 2843 /* Set the cipher suite from the message. */
sPymbed 17:ff9d1e86ad5f 2844 ssl->options.cipherSuite0 = input[i++];
sPymbed 17:ff9d1e86ad5f 2845 ssl->options.cipherSuite = input[i++];
sPymbed 17:ff9d1e86ad5f 2846
sPymbed 17:ff9d1e86ad5f 2847 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2848 /* Compression */
sPymbed 17:ff9d1e86ad5f 2849 b = input[i++];
sPymbed 17:ff9d1e86ad5f 2850 if (b != 0) {
sPymbed 17:ff9d1e86ad5f 2851 WOLFSSL_MSG("Must be no compression types in list");
sPymbed 17:ff9d1e86ad5f 2852 return INVALID_PARAMETER;
sPymbed 17:ff9d1e86ad5f 2853 }
sPymbed 17:ff9d1e86ad5f 2854 #endif
sPymbed 17:ff9d1e86ad5f 2855
sPymbed 17:ff9d1e86ad5f 2856 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2857 if ((i - begin) + OPAQUE16_LEN > helloSz) {
sPymbed 17:ff9d1e86ad5f 2858 if (!ssl->options.downgrade)
sPymbed 17:ff9d1e86ad5f 2859 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 2860 #ifndef WOLFSSL_NO_TLS12
sPymbed 17:ff9d1e86ad5f 2861 ssl->version.minor = TLSv1_2_MINOR;
sPymbed 17:ff9d1e86ad5f 2862 #endif
sPymbed 17:ff9d1e86ad5f 2863 ssl->options.haveEMS = 0;
sPymbed 17:ff9d1e86ad5f 2864 }
sPymbed 17:ff9d1e86ad5f 2865 if ((i - begin) < helloSz)
sPymbed 17:ff9d1e86ad5f 2866 #endif
sPymbed 17:ff9d1e86ad5f 2867 {
sPymbed 17:ff9d1e86ad5f 2868 /* Get extension length and length check. */
sPymbed 17:ff9d1e86ad5f 2869 if ((i - begin) + OPAQUE16_LEN > helloSz)
sPymbed 17:ff9d1e86ad5f 2870 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 2871 ato16(&input[i], &totalExtSz);
sPymbed 17:ff9d1e86ad5f 2872 i += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 2873 if ((i - begin) + totalExtSz > helloSz)
sPymbed 17:ff9d1e86ad5f 2874 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 2875
sPymbed 17:ff9d1e86ad5f 2876 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2877 if (ssl->options.downgrade)
sPymbed 17:ff9d1e86ad5f 2878 ssl->version.minor = TLSv1_2_MINOR;
sPymbed 17:ff9d1e86ad5f 2879 #endif
sPymbed 17:ff9d1e86ad5f 2880 /* Parse and handle extensions. */
sPymbed 17:ff9d1e86ad5f 2881 ret = TLSX_Parse(ssl, (byte *) input + i, totalExtSz, *extMsgType,
sPymbed 17:ff9d1e86ad5f 2882 NULL);
sPymbed 17:ff9d1e86ad5f 2883 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2884 return ret;
sPymbed 17:ff9d1e86ad5f 2885
sPymbed 17:ff9d1e86ad5f 2886 i += totalExtSz;
sPymbed 17:ff9d1e86ad5f 2887 }
sPymbed 17:ff9d1e86ad5f 2888 *inOutIdx = i;
sPymbed 17:ff9d1e86ad5f 2889
sPymbed 17:ff9d1e86ad5f 2890 ssl->options.serverState = SERVER_HELLO_COMPLETE;
sPymbed 17:ff9d1e86ad5f 2891
sPymbed 17:ff9d1e86ad5f 2892 #ifdef HAVE_SECRET_CALLBACK
sPymbed 17:ff9d1e86ad5f 2893 if (ssl->sessionSecretCb != NULL) {
sPymbed 17:ff9d1e86ad5f 2894 int secretSz = SECRET_LEN;
sPymbed 17:ff9d1e86ad5f 2895 ret = ssl->sessionSecretCb(ssl, ssl->session.masterSecret,
sPymbed 17:ff9d1e86ad5f 2896 &secretSz, ssl->sessionSecretCtx);
sPymbed 17:ff9d1e86ad5f 2897 if (ret != 0 || secretSz != SECRET_LEN)
sPymbed 17:ff9d1e86ad5f 2898 return SESSION_SECRET_CB_E;
sPymbed 17:ff9d1e86ad5f 2899 }
sPymbed 17:ff9d1e86ad5f 2900 #endif /* HAVE_SECRET_CALLBACK */
sPymbed 17:ff9d1e86ad5f 2901
sPymbed 17:ff9d1e86ad5f 2902 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2903 /* Version only negotiated in extensions for TLS v1.3.
sPymbed 17:ff9d1e86ad5f 2904 * Only now do we know how to deal with session id.
sPymbed 17:ff9d1e86ad5f 2905 */
sPymbed 17:ff9d1e86ad5f 2906 if (!IsAtLeastTLSv1_3(ssl->version)) {
sPymbed 17:ff9d1e86ad5f 2907 #ifndef WOLFSSL_NO_TLS12
sPymbed 17:ff9d1e86ad5f 2908 ssl->arrays->sessionIDSz = sessIdSz;
sPymbed 17:ff9d1e86ad5f 2909
sPymbed 17:ff9d1e86ad5f 2910 if (ssl->arrays->sessionIDSz > ID_LEN) {
sPymbed 17:ff9d1e86ad5f 2911 WOLFSSL_MSG("Invalid session ID size");
sPymbed 17:ff9d1e86ad5f 2912 ssl->arrays->sessionIDSz = 0;
sPymbed 17:ff9d1e86ad5f 2913 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 2914 }
sPymbed 17:ff9d1e86ad5f 2915 else if (ssl->arrays->sessionIDSz) {
sPymbed 17:ff9d1e86ad5f 2916 XMEMCPY(ssl->arrays->sessionID, sessId, ssl->arrays->sessionIDSz);
sPymbed 17:ff9d1e86ad5f 2917 ssl->options.haveSessionId = 1;
sPymbed 17:ff9d1e86ad5f 2918 }
sPymbed 17:ff9d1e86ad5f 2919
sPymbed 17:ff9d1e86ad5f 2920 /* Force client hello version 1.2 to work for static RSA. */
sPymbed 17:ff9d1e86ad5f 2921 ssl->chVersion.minor = TLSv1_2_MINOR;
sPymbed 17:ff9d1e86ad5f 2922 /* Complete TLS v1.2 processing of ServerHello. */
sPymbed 17:ff9d1e86ad5f 2923 ret = CompleteServerHello(ssl);
sPymbed 17:ff9d1e86ad5f 2924 #else
sPymbed 17:ff9d1e86ad5f 2925 WOLFSSL_MSG("Client using higher version, fatal error");
sPymbed 17:ff9d1e86ad5f 2926 ret = VERSION_ERROR;
sPymbed 17:ff9d1e86ad5f 2927 #endif
sPymbed 17:ff9d1e86ad5f 2928
sPymbed 17:ff9d1e86ad5f 2929 WOLFSSL_LEAVE("DoTls13ServerHello", ret);
sPymbed 17:ff9d1e86ad5f 2930
sPymbed 17:ff9d1e86ad5f 2931 return ret;
sPymbed 17:ff9d1e86ad5f 2932 }
sPymbed 17:ff9d1e86ad5f 2933
sPymbed 17:ff9d1e86ad5f 2934 #ifdef WOLFSSL_TLS13_MIDDLEBOX_COMPAT
sPymbed 17:ff9d1e86ad5f 2935 if (sessIdSz == 0)
sPymbed 17:ff9d1e86ad5f 2936 return INVALID_PARAMETER;
sPymbed 17:ff9d1e86ad5f 2937 if (ssl->session.sessionIDSz != 0) {
sPymbed 17:ff9d1e86ad5f 2938 if (ssl->session.sessionIDSz != sessIdSz ||
sPymbed 17:ff9d1e86ad5f 2939 XMEMCMP(ssl->session.sessionID, sessId, sessIdSz) != 0) {
sPymbed 17:ff9d1e86ad5f 2940 return INVALID_PARAMETER;
sPymbed 17:ff9d1e86ad5f 2941 }
sPymbed 17:ff9d1e86ad5f 2942 }
sPymbed 17:ff9d1e86ad5f 2943 else if (XMEMCMP(ssl->arrays->clientRandom, sessId, sessIdSz) != 0)
sPymbed 17:ff9d1e86ad5f 2944 return INVALID_PARAMETER;
sPymbed 17:ff9d1e86ad5f 2945 #else
sPymbed 17:ff9d1e86ad5f 2946 if (sessIdSz != ssl->session.sessionIDSz || (sessIdSz > 0 &&
sPymbed 17:ff9d1e86ad5f 2947 XMEMCMP(ssl->session.sessionID, sessId, sessIdSz) != 0)) {
sPymbed 17:ff9d1e86ad5f 2948 WOLFSSL_MSG("Server sent different session id");
sPymbed 17:ff9d1e86ad5f 2949 return INVALID_PARAMETER;
sPymbed 17:ff9d1e86ad5f 2950 }
sPymbed 17:ff9d1e86ad5f 2951 #endif /* WOLFSSL_TLS13_MIDDLEBOX_COMPAT */
sPymbed 17:ff9d1e86ad5f 2952 #endif
sPymbed 17:ff9d1e86ad5f 2953
sPymbed 17:ff9d1e86ad5f 2954 ret = SetCipherSpecs(ssl);
sPymbed 17:ff9d1e86ad5f 2955 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 2956 return ret;
sPymbed 17:ff9d1e86ad5f 2957
sPymbed 17:ff9d1e86ad5f 2958 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 2959 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2960 if (*extMsgType == server_hello)
sPymbed 17:ff9d1e86ad5f 2961 #endif
sPymbed 17:ff9d1e86ad5f 2962 {
sPymbed 17:ff9d1e86ad5f 2963 ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
sPymbed 17:ff9d1e86ad5f 2964 if (ext != NULL)
sPymbed 17:ff9d1e86ad5f 2965 psk = (PreSharedKey*)ext->data;
sPymbed 17:ff9d1e86ad5f 2966 while (psk != NULL && !psk->chosen)
sPymbed 17:ff9d1e86ad5f 2967 psk = psk->next;
sPymbed 17:ff9d1e86ad5f 2968 if (psk == NULL) {
sPymbed 17:ff9d1e86ad5f 2969 ssl->options.resuming = 0;
sPymbed 17:ff9d1e86ad5f 2970 ssl->arrays->psk_keySz = 0;
sPymbed 17:ff9d1e86ad5f 2971 XMEMSET(ssl->arrays->psk_key, 0, MAX_PSK_KEY_LEN);
sPymbed 17:ff9d1e86ad5f 2972 }
sPymbed 17:ff9d1e86ad5f 2973 else if ((ret = SetupPskKey(ssl, psk)) != 0)
sPymbed 17:ff9d1e86ad5f 2974 return ret;
sPymbed 17:ff9d1e86ad5f 2975 }
sPymbed 17:ff9d1e86ad5f 2976 #endif
sPymbed 17:ff9d1e86ad5f 2977
sPymbed 17:ff9d1e86ad5f 2978 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 2979 ssl->keys.encryptionOn = 1;
sPymbed 17:ff9d1e86ad5f 2980 #else
sPymbed 17:ff9d1e86ad5f 2981 if (*extMsgType == server_hello) {
sPymbed 17:ff9d1e86ad5f 2982 ssl->keys.encryptionOn = 1;
sPymbed 17:ff9d1e86ad5f 2983 ssl->options.serverState = SERVER_HELLO_COMPLETE;
sPymbed 17:ff9d1e86ad5f 2984 }
sPymbed 17:ff9d1e86ad5f 2985 else {
sPymbed 17:ff9d1e86ad5f 2986 ssl->options.tls1_3 = 1;
sPymbed 17:ff9d1e86ad5f 2987 ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST_COMPLETE;
sPymbed 17:ff9d1e86ad5f 2988
sPymbed 17:ff9d1e86ad5f 2989 ret = RestartHandshakeHash(ssl);
sPymbed 17:ff9d1e86ad5f 2990 }
sPymbed 17:ff9d1e86ad5f 2991 #endif
sPymbed 17:ff9d1e86ad5f 2992
sPymbed 17:ff9d1e86ad5f 2993 WOLFSSL_LEAVE("DoTls13ServerHello", ret);
sPymbed 17:ff9d1e86ad5f 2994 WOLFSSL_END(WC_FUNC_SERVER_HELLO_DO);
sPymbed 17:ff9d1e86ad5f 2995
sPymbed 17:ff9d1e86ad5f 2996 return ret;
sPymbed 17:ff9d1e86ad5f 2997 }
sPymbed 17:ff9d1e86ad5f 2998
sPymbed 17:ff9d1e86ad5f 2999 /* handle processing TLS 1.3 encrypted_extensions (8) */
sPymbed 17:ff9d1e86ad5f 3000 /* Parse and handle an EncryptedExtensions message.
sPymbed 17:ff9d1e86ad5f 3001 * Only a client will receive this message.
sPymbed 17:ff9d1e86ad5f 3002 *
sPymbed 17:ff9d1e86ad5f 3003 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 3004 * input The message buffer.
sPymbed 17:ff9d1e86ad5f 3005 * inOutIdx On entry, the index into the message buffer of
sPymbed 17:ff9d1e86ad5f 3006 * EncryptedExtensions.
sPymbed 17:ff9d1e86ad5f 3007 * On exit, the index of byte after the EncryptedExtensions
sPymbed 17:ff9d1e86ad5f 3008 * message.
sPymbed 17:ff9d1e86ad5f 3009 * totalSz The length of the current handshake message.
sPymbed 17:ff9d1e86ad5f 3010 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 3011 */
sPymbed 17:ff9d1e86ad5f 3012 static int DoTls13EncryptedExtensions(WOLFSSL* ssl, const byte* input,
sPymbed 17:ff9d1e86ad5f 3013 word32* inOutIdx, word32 totalSz)
sPymbed 17:ff9d1e86ad5f 3014 {
sPymbed 17:ff9d1e86ad5f 3015 int ret;
sPymbed 17:ff9d1e86ad5f 3016 word32 begin = *inOutIdx;
sPymbed 17:ff9d1e86ad5f 3017 word32 i = begin;
sPymbed 17:ff9d1e86ad5f 3018 word16 totalExtSz;
sPymbed 17:ff9d1e86ad5f 3019
sPymbed 17:ff9d1e86ad5f 3020 WOLFSSL_START(WC_FUNC_ENCRYPTED_EXTENSIONS_DO);
sPymbed 17:ff9d1e86ad5f 3021 WOLFSSL_ENTER("DoTls13EncryptedExtensions");
sPymbed 17:ff9d1e86ad5f 3022
sPymbed 17:ff9d1e86ad5f 3023 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 3024 if (ssl->hsInfoOn) AddPacketName(ssl, "EncryptedExtensions");
sPymbed 17:ff9d1e86ad5f 3025 if (ssl->toInfoOn) AddLateName("EncryptedExtensions", &ssl->timeoutInfo);
sPymbed 17:ff9d1e86ad5f 3026 #endif
sPymbed 17:ff9d1e86ad5f 3027
sPymbed 17:ff9d1e86ad5f 3028 /* Length field of extension data. */
sPymbed 17:ff9d1e86ad5f 3029 if (totalSz < i - begin + OPAQUE16_LEN)
sPymbed 17:ff9d1e86ad5f 3030 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3031 ato16(&input[i], &totalExtSz);
sPymbed 17:ff9d1e86ad5f 3032 i += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 3033
sPymbed 17:ff9d1e86ad5f 3034 /* Extension data. */
sPymbed 17:ff9d1e86ad5f 3035 if (i - begin + totalExtSz > totalSz)
sPymbed 17:ff9d1e86ad5f 3036 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3037 if ((ret = TLSX_Parse(ssl, (byte *)(input + i), totalExtSz,
sPymbed 17:ff9d1e86ad5f 3038 encrypted_extensions, NULL)))
sPymbed 17:ff9d1e86ad5f 3039 return ret;
sPymbed 17:ff9d1e86ad5f 3040
sPymbed 17:ff9d1e86ad5f 3041 /* Move index to byte after message. */
sPymbed 17:ff9d1e86ad5f 3042 *inOutIdx = i + totalExtSz;
sPymbed 17:ff9d1e86ad5f 3043
sPymbed 17:ff9d1e86ad5f 3044 /* Always encrypted. */
sPymbed 17:ff9d1e86ad5f 3045 *inOutIdx += ssl->keys.padSz;
sPymbed 17:ff9d1e86ad5f 3046
sPymbed 17:ff9d1e86ad5f 3047 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 3048 if (ssl->earlyData != no_early_data) {
sPymbed 17:ff9d1e86ad5f 3049 TLSX* ext = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
sPymbed 17:ff9d1e86ad5f 3050 if (ext == NULL || !ext->val)
sPymbed 17:ff9d1e86ad5f 3051 ssl->earlyData = no_early_data;
sPymbed 17:ff9d1e86ad5f 3052 }
sPymbed 17:ff9d1e86ad5f 3053 #endif
sPymbed 17:ff9d1e86ad5f 3054
sPymbed 17:ff9d1e86ad5f 3055 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 3056 if (ssl->earlyData == no_early_data) {
sPymbed 17:ff9d1e86ad5f 3057 ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY);
sPymbed 17:ff9d1e86ad5f 3058 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3059 return ret;
sPymbed 17:ff9d1e86ad5f 3060 }
sPymbed 17:ff9d1e86ad5f 3061 #endif
sPymbed 17:ff9d1e86ad5f 3062
sPymbed 17:ff9d1e86ad5f 3063 ssl->options.serverState = SERVER_ENCRYPTED_EXTENSIONS_COMPLETE;
sPymbed 17:ff9d1e86ad5f 3064
sPymbed 17:ff9d1e86ad5f 3065 WOLFSSL_LEAVE("DoTls13EncryptedExtensions", ret);
sPymbed 17:ff9d1e86ad5f 3066 WOLFSSL_END(WC_FUNC_ENCRYPTED_EXTENSIONS_DO);
sPymbed 17:ff9d1e86ad5f 3067
sPymbed 17:ff9d1e86ad5f 3068 return ret;
sPymbed 17:ff9d1e86ad5f 3069 }
sPymbed 17:ff9d1e86ad5f 3070
sPymbed 17:ff9d1e86ad5f 3071 /* handle processing TLS v1.3 certificate_request (13) */
sPymbed 17:ff9d1e86ad5f 3072 /* Handle a TLS v1.3 CertificateRequest message.
sPymbed 17:ff9d1e86ad5f 3073 * This message is always encrypted.
sPymbed 17:ff9d1e86ad5f 3074 * Only a client will receive this message.
sPymbed 17:ff9d1e86ad5f 3075 *
sPymbed 17:ff9d1e86ad5f 3076 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 3077 * input The message buffer.
sPymbed 17:ff9d1e86ad5f 3078 * inOutIdx On entry, the index into the message buffer of CertificateRequest.
sPymbed 17:ff9d1e86ad5f 3079 * On exit, the index of byte after the CertificateRequest message.
sPymbed 17:ff9d1e86ad5f 3080 * size The length of the current handshake message.
sPymbed 17:ff9d1e86ad5f 3081 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 3082 */
sPymbed 17:ff9d1e86ad5f 3083 static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
sPymbed 17:ff9d1e86ad5f 3084 word32* inOutIdx, word32 size)
sPymbed 17:ff9d1e86ad5f 3085 {
sPymbed 17:ff9d1e86ad5f 3086 word16 len;
sPymbed 17:ff9d1e86ad5f 3087 word32 begin = *inOutIdx;
sPymbed 17:ff9d1e86ad5f 3088 int ret = 0;
sPymbed 17:ff9d1e86ad5f 3089 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 3090 Suites peerSuites;
sPymbed 17:ff9d1e86ad5f 3091 #endif
sPymbed 17:ff9d1e86ad5f 3092 #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
sPymbed 17:ff9d1e86ad5f 3093 CertReqCtx* certReqCtx;
sPymbed 17:ff9d1e86ad5f 3094 #endif
sPymbed 17:ff9d1e86ad5f 3095
sPymbed 17:ff9d1e86ad5f 3096 WOLFSSL_START(WC_FUNC_CERTIFICATE_REQUEST_DO);
sPymbed 17:ff9d1e86ad5f 3097 WOLFSSL_ENTER("DoTls13CertificateRequest");
sPymbed 17:ff9d1e86ad5f 3098
sPymbed 17:ff9d1e86ad5f 3099 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 3100 if (ssl->hsInfoOn) AddPacketName(ssl, "CertificateRequest");
sPymbed 17:ff9d1e86ad5f 3101 if (ssl->toInfoOn) AddLateName("CertificateRequest", &ssl->timeoutInfo);
sPymbed 17:ff9d1e86ad5f 3102 #endif
sPymbed 17:ff9d1e86ad5f 3103
sPymbed 17:ff9d1e86ad5f 3104 if ((*inOutIdx - begin) + OPAQUE8_LEN > size)
sPymbed 17:ff9d1e86ad5f 3105 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3106
sPymbed 17:ff9d1e86ad5f 3107 /* Length of the request context. */
sPymbed 17:ff9d1e86ad5f 3108 len = input[(*inOutIdx)++];
sPymbed 17:ff9d1e86ad5f 3109 if ((*inOutIdx - begin) + len > size)
sPymbed 17:ff9d1e86ad5f 3110 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3111 if (ssl->options.connectState < FINISHED_DONE && len > 0)
sPymbed 17:ff9d1e86ad5f 3112 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3113
sPymbed 17:ff9d1e86ad5f 3114 #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
sPymbed 17:ff9d1e86ad5f 3115 /* CertReqCtx has one byte at end for context value.
sPymbed 17:ff9d1e86ad5f 3116 * Increase size to handle other implementations sending more than one byte.
sPymbed 17:ff9d1e86ad5f 3117 * That is, allocate extra space, over one byte, to hold the context value.
sPymbed 17:ff9d1e86ad5f 3118 */
sPymbed 17:ff9d1e86ad5f 3119 certReqCtx = (CertReqCtx*)XMALLOC(sizeof(CertReqCtx) + len - 1, ssl->heap,
sPymbed 17:ff9d1e86ad5f 3120 DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 17:ff9d1e86ad5f 3121 if (certReqCtx == NULL)
sPymbed 17:ff9d1e86ad5f 3122 return MEMORY_E;
sPymbed 17:ff9d1e86ad5f 3123 certReqCtx->next = ssl->certReqCtx;
sPymbed 17:ff9d1e86ad5f 3124 certReqCtx->len = len;
sPymbed 17:ff9d1e86ad5f 3125 XMEMCPY(&certReqCtx->ctx, input + *inOutIdx, len);
sPymbed 17:ff9d1e86ad5f 3126 ssl->certReqCtx = certReqCtx;
sPymbed 17:ff9d1e86ad5f 3127 #endif
sPymbed 17:ff9d1e86ad5f 3128 *inOutIdx += len;
sPymbed 17:ff9d1e86ad5f 3129
sPymbed 17:ff9d1e86ad5f 3130 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 3131 /* Signature and hash algorithms. */
sPymbed 17:ff9d1e86ad5f 3132 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
sPymbed 17:ff9d1e86ad5f 3133 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3134 ato16(input + *inOutIdx, &len);
sPymbed 17:ff9d1e86ad5f 3135 *inOutIdx += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 3136 if ((*inOutIdx - begin) + len > size)
sPymbed 17:ff9d1e86ad5f 3137 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3138 PickHashSigAlgo(ssl, input + *inOutIdx, len);
sPymbed 17:ff9d1e86ad5f 3139 *inOutIdx += len;
sPymbed 17:ff9d1e86ad5f 3140
sPymbed 17:ff9d1e86ad5f 3141 /* Length of certificate authority data. */
sPymbed 17:ff9d1e86ad5f 3142 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
sPymbed 17:ff9d1e86ad5f 3143 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3144 ato16(input + *inOutIdx, &len);
sPymbed 17:ff9d1e86ad5f 3145 *inOutIdx += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 3146 if ((*inOutIdx - begin) + len > size)
sPymbed 17:ff9d1e86ad5f 3147 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3148
sPymbed 17:ff9d1e86ad5f 3149 /* Certificate authorities. */
sPymbed 17:ff9d1e86ad5f 3150 while (len) {
sPymbed 17:ff9d1e86ad5f 3151 word16 dnSz;
sPymbed 17:ff9d1e86ad5f 3152
sPymbed 17:ff9d1e86ad5f 3153 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
sPymbed 17:ff9d1e86ad5f 3154 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3155
sPymbed 17:ff9d1e86ad5f 3156 ato16(input + *inOutIdx, &dnSz);
sPymbed 17:ff9d1e86ad5f 3157 *inOutIdx += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 3158
sPymbed 17:ff9d1e86ad5f 3159 if ((*inOutIdx - begin) + dnSz > size)
sPymbed 17:ff9d1e86ad5f 3160 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3161
sPymbed 17:ff9d1e86ad5f 3162 *inOutIdx += dnSz;
sPymbed 17:ff9d1e86ad5f 3163 len -= OPAQUE16_LEN + dnSz;
sPymbed 17:ff9d1e86ad5f 3164 }
sPymbed 17:ff9d1e86ad5f 3165
sPymbed 17:ff9d1e86ad5f 3166 /* Certificate extensions */
sPymbed 17:ff9d1e86ad5f 3167 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
sPymbed 17:ff9d1e86ad5f 3168 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3169 ato16(input + *inOutIdx, &len);
sPymbed 17:ff9d1e86ad5f 3170 *inOutIdx += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 3171 if ((*inOutIdx - begin) + len > size)
sPymbed 17:ff9d1e86ad5f 3172 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3173 *inOutIdx += len;
sPymbed 17:ff9d1e86ad5f 3174 #else
sPymbed 17:ff9d1e86ad5f 3175 /* TODO: Add support for more extensions:
sPymbed 17:ff9d1e86ad5f 3176 * signed_certificate_timestamp, certificate_authorities, oid_filters.
sPymbed 17:ff9d1e86ad5f 3177 */
sPymbed 17:ff9d1e86ad5f 3178 /* Certificate extensions */
sPymbed 17:ff9d1e86ad5f 3179 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
sPymbed 17:ff9d1e86ad5f 3180 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3181 ato16(input + *inOutIdx, &len);
sPymbed 17:ff9d1e86ad5f 3182 *inOutIdx += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 3183 if ((*inOutIdx - begin) + len > size)
sPymbed 17:ff9d1e86ad5f 3184 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3185 if (len == 0)
sPymbed 17:ff9d1e86ad5f 3186 return INVALID_PARAMETER;
sPymbed 17:ff9d1e86ad5f 3187 if ((ret = TLSX_Parse(ssl, (byte *)(input + *inOutIdx), len,
sPymbed 17:ff9d1e86ad5f 3188 certificate_request, &peerSuites))) {
sPymbed 17:ff9d1e86ad5f 3189 return ret;
sPymbed 17:ff9d1e86ad5f 3190 }
sPymbed 17:ff9d1e86ad5f 3191 *inOutIdx += len;
sPymbed 17:ff9d1e86ad5f 3192
sPymbed 17:ff9d1e86ad5f 3193 PickHashSigAlgo(ssl, peerSuites.hashSigAlgo, peerSuites.hashSigAlgoSz);
sPymbed 17:ff9d1e86ad5f 3194 #endif
sPymbed 17:ff9d1e86ad5f 3195
sPymbed 17:ff9d1e86ad5f 3196 if (ssl->buffers.certificate && ssl->buffers.certificate->buffer &&
sPymbed 17:ff9d1e86ad5f 3197 ssl->buffers.key && ssl->buffers.key->buffer)
sPymbed 17:ff9d1e86ad5f 3198 ssl->options.sendVerify = SEND_CERT;
sPymbed 17:ff9d1e86ad5f 3199 else
sPymbed 17:ff9d1e86ad5f 3200 ssl->options.sendVerify = SEND_BLANK_CERT;
sPymbed 17:ff9d1e86ad5f 3201
sPymbed 17:ff9d1e86ad5f 3202 /* This message is always encrypted so add encryption padding. */
sPymbed 17:ff9d1e86ad5f 3203 *inOutIdx += ssl->keys.padSz;
sPymbed 17:ff9d1e86ad5f 3204
sPymbed 17:ff9d1e86ad5f 3205 WOLFSSL_LEAVE("DoTls13CertificateRequest", ret);
sPymbed 17:ff9d1e86ad5f 3206 WOLFSSL_END(WC_FUNC_CERTIFICATE_REQUEST_DO);
sPymbed 17:ff9d1e86ad5f 3207
sPymbed 17:ff9d1e86ad5f 3208 return ret;
sPymbed 17:ff9d1e86ad5f 3209 }
sPymbed 17:ff9d1e86ad5f 3210
sPymbed 17:ff9d1e86ad5f 3211 #endif /* !NO_WOLFSSL_CLIENT */
sPymbed 17:ff9d1e86ad5f 3212
sPymbed 17:ff9d1e86ad5f 3213 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 3214 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 3215 /* Refine list of supported cipher suites to those common to server and client.
sPymbed 17:ff9d1e86ad5f 3216 *
sPymbed 17:ff9d1e86ad5f 3217 * ssl SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 3218 * peerSuites The peer's advertised list of supported cipher suites.
sPymbed 17:ff9d1e86ad5f 3219 */
sPymbed 17:ff9d1e86ad5f 3220 static void RefineSuites(WOLFSSL* ssl, Suites* peerSuites)
sPymbed 17:ff9d1e86ad5f 3221 {
sPymbed 17:ff9d1e86ad5f 3222 byte suites[WOLFSSL_MAX_SUITE_SZ];
sPymbed 17:ff9d1e86ad5f 3223 int suiteSz = 0;
sPymbed 17:ff9d1e86ad5f 3224 int i, j;
sPymbed 17:ff9d1e86ad5f 3225
sPymbed 17:ff9d1e86ad5f 3226 for (i = 0; i < ssl->suites->suiteSz; i += 2) {
sPymbed 17:ff9d1e86ad5f 3227 for (j = 0; j < peerSuites->suiteSz; j += 2) {
sPymbed 17:ff9d1e86ad5f 3228 if (ssl->suites->suites[i+0] == peerSuites->suites[j+0] &&
sPymbed 17:ff9d1e86ad5f 3229 ssl->suites->suites[i+1] == peerSuites->suites[j+1]) {
sPymbed 17:ff9d1e86ad5f 3230 suites[suiteSz++] = peerSuites->suites[j+0];
sPymbed 17:ff9d1e86ad5f 3231 suites[suiteSz++] = peerSuites->suites[j+1];
sPymbed 17:ff9d1e86ad5f 3232 }
sPymbed 17:ff9d1e86ad5f 3233 }
sPymbed 17:ff9d1e86ad5f 3234 }
sPymbed 17:ff9d1e86ad5f 3235
sPymbed 17:ff9d1e86ad5f 3236 ssl->suites->suiteSz = suiteSz;
sPymbed 17:ff9d1e86ad5f 3237 XMEMCPY(ssl->suites->suites, &suites, sizeof(suites));
sPymbed 17:ff9d1e86ad5f 3238 }
sPymbed 17:ff9d1e86ad5f 3239
sPymbed 17:ff9d1e86ad5f 3240 /* Handle any Pre-Shared Key (PSK) extension.
sPymbed 17:ff9d1e86ad5f 3241 * Must do this in ClientHello as it requires a hash of the truncated message.
sPymbed 17:ff9d1e86ad5f 3242 * Don't know size of binders until Pre-Shared Key extension has been parsed.
sPymbed 17:ff9d1e86ad5f 3243 *
sPymbed 17:ff9d1e86ad5f 3244 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 3245 * input The ClientHello message.
sPymbed 17:ff9d1e86ad5f 3246 * helloSz The size of the ClientHello message (including binders if present).
sPymbed 17:ff9d1e86ad5f 3247 * usingPSK Indicates handshake is using Pre-Shared Keys.
sPymbed 17:ff9d1e86ad5f 3248 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 3249 */
sPymbed 17:ff9d1e86ad5f 3250 static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
sPymbed 17:ff9d1e86ad5f 3251 int* usingPSK)
sPymbed 17:ff9d1e86ad5f 3252 {
sPymbed 17:ff9d1e86ad5f 3253 int ret;
sPymbed 17:ff9d1e86ad5f 3254 TLSX* ext;
sPymbed 17:ff9d1e86ad5f 3255 word16 bindersLen;
sPymbed 17:ff9d1e86ad5f 3256 PreSharedKey* current;
sPymbed 17:ff9d1e86ad5f 3257 byte binderKey[WC_MAX_DIGEST_SIZE];
sPymbed 17:ff9d1e86ad5f 3258 byte binder[WC_MAX_DIGEST_SIZE];
sPymbed 17:ff9d1e86ad5f 3259 word32 binderLen;
sPymbed 17:ff9d1e86ad5f 3260 word16 modes;
sPymbed 17:ff9d1e86ad5f 3261 byte suite[2];
sPymbed 17:ff9d1e86ad5f 3262 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 3263 int pskCnt = 0;
sPymbed 17:ff9d1e86ad5f 3264 TLSX* extEarlyData;
sPymbed 17:ff9d1e86ad5f 3265 #endif
sPymbed 17:ff9d1e86ad5f 3266
sPymbed 17:ff9d1e86ad5f 3267 WOLFSSL_ENTER("DoPreSharedKeys");
sPymbed 17:ff9d1e86ad5f 3268
sPymbed 17:ff9d1e86ad5f 3269 ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
sPymbed 17:ff9d1e86ad5f 3270 if (ext == NULL) {
sPymbed 17:ff9d1e86ad5f 3271 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 3272 ssl->earlyData = no_early_data;
sPymbed 17:ff9d1e86ad5f 3273 #endif
sPymbed 17:ff9d1e86ad5f 3274 return 0;
sPymbed 17:ff9d1e86ad5f 3275 }
sPymbed 17:ff9d1e86ad5f 3276
sPymbed 17:ff9d1e86ad5f 3277 /* Extensions pushed on stack/list and PSK must be last. */
sPymbed 17:ff9d1e86ad5f 3278 if (ssl->extensions != ext)
sPymbed 17:ff9d1e86ad5f 3279 return PSK_KEY_ERROR;
sPymbed 17:ff9d1e86ad5f 3280
sPymbed 17:ff9d1e86ad5f 3281 /* Assume we are going to resume with a pre-shared key. */
sPymbed 17:ff9d1e86ad5f 3282 ssl->options.resuming = 1;
sPymbed 17:ff9d1e86ad5f 3283
sPymbed 17:ff9d1e86ad5f 3284 /* Find the pre-shared key extension and calculate hash of truncated
sPymbed 17:ff9d1e86ad5f 3285 * ClientHello for binders.
sPymbed 17:ff9d1e86ad5f 3286 */
sPymbed 17:ff9d1e86ad5f 3287 bindersLen = TLSX_PreSharedKey_GetSizeBinders((PreSharedKey*)ext->data,
sPymbed 17:ff9d1e86ad5f 3288 client_hello);
sPymbed 17:ff9d1e86ad5f 3289
sPymbed 17:ff9d1e86ad5f 3290 /* Hash data up to binders for deriving binders in PSK extension. */
sPymbed 17:ff9d1e86ad5f 3291 ret = HashInput(ssl, input, helloSz - bindersLen);
sPymbed 17:ff9d1e86ad5f 3292 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3293 return ret;
sPymbed 17:ff9d1e86ad5f 3294
sPymbed 17:ff9d1e86ad5f 3295 /* Look through all client's pre-shared keys for a match. */
sPymbed 17:ff9d1e86ad5f 3296 current = (PreSharedKey*)ext->data;
sPymbed 17:ff9d1e86ad5f 3297 while (current != NULL) {
sPymbed 17:ff9d1e86ad5f 3298 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 3299 pskCnt++;
sPymbed 17:ff9d1e86ad5f 3300 #endif
sPymbed 17:ff9d1e86ad5f 3301
sPymbed 17:ff9d1e86ad5f 3302 #ifndef NO_PSK
sPymbed 17:ff9d1e86ad5f 3303 XMEMCPY(ssl->arrays->client_identity, current->identity,
sPymbed 17:ff9d1e86ad5f 3304 current->identityLen);
sPymbed 17:ff9d1e86ad5f 3305 ssl->arrays->client_identity[current->identityLen] = '\0';
sPymbed 17:ff9d1e86ad5f 3306 #endif
sPymbed 17:ff9d1e86ad5f 3307
sPymbed 17:ff9d1e86ad5f 3308 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 3309 /* Decode the identity. */
sPymbed 17:ff9d1e86ad5f 3310 if ((ret = DoClientTicket(ssl, current->identity, current->identityLen))
sPymbed 17:ff9d1e86ad5f 3311 == WOLFSSL_TICKET_RET_OK) {
sPymbed 17:ff9d1e86ad5f 3312 word32 now;
sPymbed 17:ff9d1e86ad5f 3313 int diff;
sPymbed 17:ff9d1e86ad5f 3314
sPymbed 17:ff9d1e86ad5f 3315 now = TimeNowInMilliseconds();
sPymbed 17:ff9d1e86ad5f 3316 if (now == (word32)GETTIME_ERROR)
sPymbed 17:ff9d1e86ad5f 3317 return now;
sPymbed 17:ff9d1e86ad5f 3318 diff = now - ssl->session.ticketSeen;
sPymbed 17:ff9d1e86ad5f 3319 diff -= current->ticketAge - ssl->session.ticketAdd;
sPymbed 17:ff9d1e86ad5f 3320 /* Check session and ticket age timeout.
sPymbed 17:ff9d1e86ad5f 3321 * Allow +/- 1000 milliseconds on ticket age.
sPymbed 17:ff9d1e86ad5f 3322 */
sPymbed 17:ff9d1e86ad5f 3323 if (diff > (int)ssl->timeout * 1000 || diff < -1000 ||
sPymbed 17:ff9d1e86ad5f 3324 diff - MAX_TICKET_AGE_SECS * 1000 > 1000) {
sPymbed 17:ff9d1e86ad5f 3325 /* Invalid difference, fallback to full handshake. */
sPymbed 17:ff9d1e86ad5f 3326 ssl->options.resuming = 0;
sPymbed 17:ff9d1e86ad5f 3327 break;
sPymbed 17:ff9d1e86ad5f 3328 }
sPymbed 17:ff9d1e86ad5f 3329
sPymbed 17:ff9d1e86ad5f 3330 /* Check whether resumption is possible based on suites in SSL and
sPymbed 17:ff9d1e86ad5f 3331 * ciphersuite in ticket.
sPymbed 17:ff9d1e86ad5f 3332 */
sPymbed 17:ff9d1e86ad5f 3333 suite[0] = ssl->session.cipherSuite0;
sPymbed 17:ff9d1e86ad5f 3334 suite[1] = ssl->session.cipherSuite;
sPymbed 17:ff9d1e86ad5f 3335 if (!FindSuite(ssl, suite)) {
sPymbed 17:ff9d1e86ad5f 3336 current = current->next;
sPymbed 17:ff9d1e86ad5f 3337 continue;
sPymbed 17:ff9d1e86ad5f 3338 }
sPymbed 17:ff9d1e86ad5f 3339
sPymbed 17:ff9d1e86ad5f 3340 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 3341 ssl->options.maxEarlyDataSz = ssl->session.maxEarlyDataSz;
sPymbed 17:ff9d1e86ad5f 3342 #endif
sPymbed 17:ff9d1e86ad5f 3343 /* Use the same cipher suite as before and set up for use. */
sPymbed 17:ff9d1e86ad5f 3344 ssl->options.cipherSuite0 = ssl->session.cipherSuite0;
sPymbed 17:ff9d1e86ad5f 3345 ssl->options.cipherSuite = ssl->session.cipherSuite;
sPymbed 17:ff9d1e86ad5f 3346 ret = SetCipherSpecs(ssl);
sPymbed 17:ff9d1e86ad5f 3347 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3348 return ret;
sPymbed 17:ff9d1e86ad5f 3349
sPymbed 17:ff9d1e86ad5f 3350 /* Resumption PSK is resumption master secret. */
sPymbed 17:ff9d1e86ad5f 3351 ssl->arrays->psk_keySz = ssl->specs.hash_size;
sPymbed 17:ff9d1e86ad5f 3352 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 3353 XMEMCPY(ssl->arrays->psk_key, ssl->session.masterSecret,
sPymbed 17:ff9d1e86ad5f 3354 ssl->arrays->psk_keySz);
sPymbed 17:ff9d1e86ad5f 3355 #else
sPymbed 17:ff9d1e86ad5f 3356 if ((ret = DeriveResumptionPSK(ssl, ssl->session.ticketNonce.data,
sPymbed 17:ff9d1e86ad5f 3357 ssl->session.ticketNonce.len, ssl->arrays->psk_key)) != 0) {
sPymbed 17:ff9d1e86ad5f 3358 return ret;
sPymbed 17:ff9d1e86ad5f 3359 }
sPymbed 17:ff9d1e86ad5f 3360 #endif
sPymbed 17:ff9d1e86ad5f 3361
sPymbed 17:ff9d1e86ad5f 3362 /* Derive the early secret using the PSK. */
sPymbed 17:ff9d1e86ad5f 3363 ret = DeriveEarlySecret(ssl);
sPymbed 17:ff9d1e86ad5f 3364 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3365 return ret;
sPymbed 17:ff9d1e86ad5f 3366 /* Derive the binder key to use to with HMAC. */
sPymbed 17:ff9d1e86ad5f 3367 ret = DeriveBinderKeyResume(ssl, binderKey);
sPymbed 17:ff9d1e86ad5f 3368 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3369 return ret;
sPymbed 17:ff9d1e86ad5f 3370 }
sPymbed 17:ff9d1e86ad5f 3371 else
sPymbed 17:ff9d1e86ad5f 3372 #endif
sPymbed 17:ff9d1e86ad5f 3373 #ifndef NO_PSK
sPymbed 17:ff9d1e86ad5f 3374 if (ssl->options.server_psk_cb != NULL &&
sPymbed 17:ff9d1e86ad5f 3375 (ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
sPymbed 17:ff9d1e86ad5f 3376 ssl->arrays->client_identity, ssl->arrays->psk_key,
sPymbed 17:ff9d1e86ad5f 3377 MAX_PSK_KEY_LEN)) != 0) {
sPymbed 17:ff9d1e86ad5f 3378 if (ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
sPymbed 17:ff9d1e86ad5f 3379 return PSK_KEY_ERROR;
sPymbed 17:ff9d1e86ad5f 3380 /* TODO: Callback should be able to specify ciphersuite. */
sPymbed 17:ff9d1e86ad5f 3381
sPymbed 17:ff9d1e86ad5f 3382 suite[0] = TLS13_BYTE;
sPymbed 17:ff9d1e86ad5f 3383 suite[1] = WOLFSSL_DEF_PSK_CIPHER;
sPymbed 17:ff9d1e86ad5f 3384 if (!FindSuite(ssl, suite)) {
sPymbed 17:ff9d1e86ad5f 3385 current = current->next;
sPymbed 17:ff9d1e86ad5f 3386 continue;
sPymbed 17:ff9d1e86ad5f 3387 }
sPymbed 17:ff9d1e86ad5f 3388
sPymbed 17:ff9d1e86ad5f 3389 /* Default to ciphersuite if cb doesn't specify. */
sPymbed 17:ff9d1e86ad5f 3390 ssl->options.resuming = 0;
sPymbed 17:ff9d1e86ad5f 3391
sPymbed 17:ff9d1e86ad5f 3392 /* PSK age is always zero. */
sPymbed 17:ff9d1e86ad5f 3393 if (current->ticketAge != ssl->session.ticketAdd)
sPymbed 17:ff9d1e86ad5f 3394 return PSK_KEY_ERROR;
sPymbed 17:ff9d1e86ad5f 3395
sPymbed 17:ff9d1e86ad5f 3396 /* Check whether PSK ciphersuite is in SSL. */
sPymbed 17:ff9d1e86ad5f 3397 ssl->options.cipherSuite0 = TLS13_BYTE;
sPymbed 17:ff9d1e86ad5f 3398 ssl->options.cipherSuite = WOLFSSL_DEF_PSK_CIPHER;
sPymbed 17:ff9d1e86ad5f 3399 ret = SetCipherSpecs(ssl);
sPymbed 17:ff9d1e86ad5f 3400 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3401 return ret;
sPymbed 17:ff9d1e86ad5f 3402
sPymbed 17:ff9d1e86ad5f 3403 /* Derive the early secret using the PSK. */
sPymbed 17:ff9d1e86ad5f 3404 ret = DeriveEarlySecret(ssl);
sPymbed 17:ff9d1e86ad5f 3405 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3406 return ret;
sPymbed 17:ff9d1e86ad5f 3407 /* Derive the binder key to use to with HMAC. */
sPymbed 17:ff9d1e86ad5f 3408 ret = DeriveBinderKey(ssl, binderKey);
sPymbed 17:ff9d1e86ad5f 3409 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3410 return ret;
sPymbed 17:ff9d1e86ad5f 3411 }
sPymbed 17:ff9d1e86ad5f 3412 else
sPymbed 17:ff9d1e86ad5f 3413 #endif
sPymbed 17:ff9d1e86ad5f 3414 {
sPymbed 17:ff9d1e86ad5f 3415 current = current->next;
sPymbed 17:ff9d1e86ad5f 3416 continue;
sPymbed 17:ff9d1e86ad5f 3417 }
sPymbed 17:ff9d1e86ad5f 3418
sPymbed 17:ff9d1e86ad5f 3419 ssl->options.sendVerify = 0;
sPymbed 17:ff9d1e86ad5f 3420
sPymbed 17:ff9d1e86ad5f 3421 /* Derive the Finished message secret. */
sPymbed 17:ff9d1e86ad5f 3422 ret = DeriveFinishedSecret(ssl, binderKey,
sPymbed 17:ff9d1e86ad5f 3423 ssl->keys.client_write_MAC_secret);
sPymbed 17:ff9d1e86ad5f 3424 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3425 return ret;
sPymbed 17:ff9d1e86ad5f 3426
sPymbed 17:ff9d1e86ad5f 3427 /* Derive the binder and compare with the one in the extension. */
sPymbed 17:ff9d1e86ad5f 3428 ret = BuildTls13HandshakeHmac(ssl,
sPymbed 17:ff9d1e86ad5f 3429 ssl->keys.client_write_MAC_secret, binder, &binderLen);
sPymbed 17:ff9d1e86ad5f 3430 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3431 return ret;
sPymbed 17:ff9d1e86ad5f 3432 if (binderLen != current->binderLen ||
sPymbed 17:ff9d1e86ad5f 3433 XMEMCMP(binder, current->binder, binderLen) != 0) {
sPymbed 17:ff9d1e86ad5f 3434 return BAD_BINDER;
sPymbed 17:ff9d1e86ad5f 3435 }
sPymbed 17:ff9d1e86ad5f 3436
sPymbed 17:ff9d1e86ad5f 3437 /* This PSK works, no need to try any more. */
sPymbed 17:ff9d1e86ad5f 3438 current->chosen = 1;
sPymbed 17:ff9d1e86ad5f 3439 ext->resp = 1;
sPymbed 17:ff9d1e86ad5f 3440 break;
sPymbed 17:ff9d1e86ad5f 3441 }
sPymbed 17:ff9d1e86ad5f 3442
sPymbed 17:ff9d1e86ad5f 3443 if (current == NULL) {
sPymbed 17:ff9d1e86ad5f 3444 #ifdef WOLFSSL_PSK_ID_PROTECTION
sPymbed 17:ff9d1e86ad5f 3445 #ifndef NO_CERTS
sPymbed 17:ff9d1e86ad5f 3446 if (ssl->buffers.certChainCnt != 0)
sPymbed 17:ff9d1e86ad5f 3447 return 0;
sPymbed 17:ff9d1e86ad5f 3448 #endif
sPymbed 17:ff9d1e86ad5f 3449 return BAD_BINDER;
sPymbed 17:ff9d1e86ad5f 3450 #else
sPymbed 17:ff9d1e86ad5f 3451 return 0;
sPymbed 17:ff9d1e86ad5f 3452 #endif
sPymbed 17:ff9d1e86ad5f 3453 }
sPymbed 17:ff9d1e86ad5f 3454
sPymbed 17:ff9d1e86ad5f 3455 /* Hash the rest of the ClientHello. */
sPymbed 17:ff9d1e86ad5f 3456 ret = HashInputRaw(ssl, input + helloSz - bindersLen, bindersLen);
sPymbed 17:ff9d1e86ad5f 3457 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3458 return ret;
sPymbed 17:ff9d1e86ad5f 3459
sPymbed 17:ff9d1e86ad5f 3460 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 3461 extEarlyData = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
sPymbed 17:ff9d1e86ad5f 3462 if (extEarlyData != NULL) {
sPymbed 17:ff9d1e86ad5f 3463 if (ssl->earlyData != no_early_data && current == ext->data) {
sPymbed 17:ff9d1e86ad5f 3464 extEarlyData->resp = 1;
sPymbed 17:ff9d1e86ad5f 3465
sPymbed 17:ff9d1e86ad5f 3466 /* Derive early data decryption key. */
sPymbed 17:ff9d1e86ad5f 3467 ret = DeriveTls13Keys(ssl, early_data_key, DECRYPT_SIDE_ONLY, 1);
sPymbed 17:ff9d1e86ad5f 3468 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3469 return ret;
sPymbed 17:ff9d1e86ad5f 3470 if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
sPymbed 17:ff9d1e86ad5f 3471 return ret;
sPymbed 17:ff9d1e86ad5f 3472
sPymbed 17:ff9d1e86ad5f 3473 ssl->earlyData = process_early_data;
sPymbed 17:ff9d1e86ad5f 3474 }
sPymbed 17:ff9d1e86ad5f 3475 else
sPymbed 17:ff9d1e86ad5f 3476 extEarlyData->resp = 0;
sPymbed 17:ff9d1e86ad5f 3477 }
sPymbed 17:ff9d1e86ad5f 3478 #endif
sPymbed 17:ff9d1e86ad5f 3479
sPymbed 17:ff9d1e86ad5f 3480 /* Get the PSK key exchange modes the client wants to negotiate. */
sPymbed 17:ff9d1e86ad5f 3481 ext = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES);
sPymbed 17:ff9d1e86ad5f 3482 if (ext == NULL)
sPymbed 17:ff9d1e86ad5f 3483 return MISSING_HANDSHAKE_DATA;
sPymbed 17:ff9d1e86ad5f 3484 modes = ext->val;
sPymbed 17:ff9d1e86ad5f 3485
sPymbed 17:ff9d1e86ad5f 3486 ext = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
sPymbed 17:ff9d1e86ad5f 3487 /* Use (EC)DHE for forward-security if possible. */
sPymbed 17:ff9d1e86ad5f 3488 if ((modes & (1 << PSK_DHE_KE)) != 0 && !ssl->options.noPskDheKe &&
sPymbed 17:ff9d1e86ad5f 3489 ext != NULL) {
sPymbed 17:ff9d1e86ad5f 3490 /* Only use named group used in last session. */
sPymbed 17:ff9d1e86ad5f 3491 ssl->namedGroup = ssl->session.namedGroup;
sPymbed 17:ff9d1e86ad5f 3492
sPymbed 17:ff9d1e86ad5f 3493 /* Pick key share and Generate a new key if not present. */
sPymbed 17:ff9d1e86ad5f 3494 ret = TLSX_KeyShare_Establish(ssl);
sPymbed 17:ff9d1e86ad5f 3495 if (ret == KEY_SHARE_ERROR) {
sPymbed 17:ff9d1e86ad5f 3496 ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST_COMPLETE;
sPymbed 17:ff9d1e86ad5f 3497 ret = 0;
sPymbed 17:ff9d1e86ad5f 3498 }
sPymbed 17:ff9d1e86ad5f 3499 else if (ret < 0)
sPymbed 17:ff9d1e86ad5f 3500 return ret;
sPymbed 17:ff9d1e86ad5f 3501
sPymbed 17:ff9d1e86ad5f 3502 /* Send new public key to client. */
sPymbed 17:ff9d1e86ad5f 3503 ext->resp = 1;
sPymbed 17:ff9d1e86ad5f 3504 }
sPymbed 17:ff9d1e86ad5f 3505 else {
sPymbed 17:ff9d1e86ad5f 3506 if ((modes & (1 << PSK_KE)) == 0)
sPymbed 17:ff9d1e86ad5f 3507 return PSK_KEY_ERROR;
sPymbed 17:ff9d1e86ad5f 3508 ssl->options.noPskDheKe = 1;
sPymbed 17:ff9d1e86ad5f 3509 }
sPymbed 17:ff9d1e86ad5f 3510
sPymbed 17:ff9d1e86ad5f 3511 *usingPSK = 1;
sPymbed 17:ff9d1e86ad5f 3512
sPymbed 17:ff9d1e86ad5f 3513 WOLFSSL_LEAVE("DoPreSharedKeys", ret);
sPymbed 17:ff9d1e86ad5f 3514
sPymbed 17:ff9d1e86ad5f 3515 return ret;
sPymbed 17:ff9d1e86ad5f 3516 }
sPymbed 17:ff9d1e86ad5f 3517 #endif
sPymbed 17:ff9d1e86ad5f 3518
sPymbed 17:ff9d1e86ad5f 3519 #if !defined(WOLFSSL_TLS13_DRAFT_18) && defined(WOLFSSL_SEND_HRR_COOKIE)
sPymbed 17:ff9d1e86ad5f 3520 /* Check that the Cookie data's integrity.
sPymbed 17:ff9d1e86ad5f 3521 *
sPymbed 17:ff9d1e86ad5f 3522 * ssl SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 3523 * cookie The cookie data - hash and MAC.
sPymbed 17:ff9d1e86ad5f 3524 * cookieSz The length of the cookie data in bytes.
sPymbed 17:ff9d1e86ad5f 3525 * returns Length of the hash on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 3526 */
sPymbed 17:ff9d1e86ad5f 3527 static int CheckCookie(WOLFSSL* ssl, byte* cookie, byte cookieSz)
sPymbed 17:ff9d1e86ad5f 3528 {
sPymbed 17:ff9d1e86ad5f 3529 int ret;
sPymbed 17:ff9d1e86ad5f 3530 byte mac[WC_MAX_DIGEST_SIZE];
sPymbed 17:ff9d1e86ad5f 3531 Hmac cookieHmac;
sPymbed 17:ff9d1e86ad5f 3532 byte cookieType;
sPymbed 17:ff9d1e86ad5f 3533 byte macSz;
sPymbed 17:ff9d1e86ad5f 3534
sPymbed 17:ff9d1e86ad5f 3535 #if !defined(NO_SHA) && defined(NO_SHA256)
sPymbed 17:ff9d1e86ad5f 3536 cookieType = SHA;
sPymbed 17:ff9d1e86ad5f 3537 macSz = WC_SHA_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 3538 #endif /* NO_SHA */
sPymbed 17:ff9d1e86ad5f 3539 #ifndef NO_SHA256
sPymbed 17:ff9d1e86ad5f 3540 cookieType = WC_SHA256;
sPymbed 17:ff9d1e86ad5f 3541 macSz = WC_SHA256_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 3542 #endif /* NO_SHA256 */
sPymbed 17:ff9d1e86ad5f 3543
sPymbed 17:ff9d1e86ad5f 3544 if (cookieSz < ssl->specs.hash_size + macSz)
sPymbed 17:ff9d1e86ad5f 3545 return HRR_COOKIE_ERROR;
sPymbed 17:ff9d1e86ad5f 3546 cookieSz -= macSz;
sPymbed 17:ff9d1e86ad5f 3547
sPymbed 17:ff9d1e86ad5f 3548 ret = wc_HmacSetKey(&cookieHmac, cookieType,
sPymbed 17:ff9d1e86ad5f 3549 ssl->buffers.tls13CookieSecret.buffer,
sPymbed 17:ff9d1e86ad5f 3550 ssl->buffers.tls13CookieSecret.length);
sPymbed 17:ff9d1e86ad5f 3551 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3552 return ret;
sPymbed 17:ff9d1e86ad5f 3553 if ((ret = wc_HmacUpdate(&cookieHmac, cookie, cookieSz)) != 0)
sPymbed 17:ff9d1e86ad5f 3554 return ret;
sPymbed 17:ff9d1e86ad5f 3555 if ((ret = wc_HmacFinal(&cookieHmac, mac)) != 0)
sPymbed 17:ff9d1e86ad5f 3556 return ret;
sPymbed 17:ff9d1e86ad5f 3557
sPymbed 17:ff9d1e86ad5f 3558 if (ConstantCompare(cookie + cookieSz, mac, macSz) != 0)
sPymbed 17:ff9d1e86ad5f 3559 return HRR_COOKIE_ERROR;
sPymbed 17:ff9d1e86ad5f 3560 return cookieSz;
sPymbed 17:ff9d1e86ad5f 3561 }
sPymbed 17:ff9d1e86ad5f 3562
sPymbed 17:ff9d1e86ad5f 3563 /* Length of the KeyShare Extension */
sPymbed 17:ff9d1e86ad5f 3564 #define HRR_KEY_SHARE_SZ (OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
sPymbed 17:ff9d1e86ad5f 3565 /* Length of the Supported Vresions Extension */
sPymbed 17:ff9d1e86ad5f 3566 #define HRR_VERSIONS_SZ (OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
sPymbed 17:ff9d1e86ad5f 3567 /* Length of the Cookie Extension excluding cookie data */
sPymbed 17:ff9d1e86ad5f 3568 #define HRR_COOKIE_HDR_SZ (OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
sPymbed 17:ff9d1e86ad5f 3569 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 3570 /* PV | CipherSuite | Ext Len */
sPymbed 17:ff9d1e86ad5f 3571 #define HRR_BODY_SZ (OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
sPymbed 17:ff9d1e86ad5f 3572 /* HH | PV | CipherSuite | Ext Len | Key Share | Cookie */
sPymbed 17:ff9d1e86ad5f 3573 #define MAX_HRR_SZ (HANDSHAKE_HEADER_SZ + \
sPymbed 17:ff9d1e86ad5f 3574 HRR_BODY_SZ + \
sPymbed 17:ff9d1e86ad5f 3575 HRR_KEY_SHARE_SZ + \
sPymbed 17:ff9d1e86ad5f 3576 HRR_COOKIE_HDR_SZ)
sPymbed 17:ff9d1e86ad5f 3577 #else
sPymbed 17:ff9d1e86ad5f 3578 /* PV | Random | Session Id | CipherSuite | Compression | Ext Len */
sPymbed 17:ff9d1e86ad5f 3579 #define HRR_BODY_SZ (VERSION_SZ + RAN_LEN + ENUM_LEN + ID_LEN + \
sPymbed 17:ff9d1e86ad5f 3580 SUITE_LEN + COMP_LEN + OPAQUE16_LEN)
sPymbed 17:ff9d1e86ad5f 3581 /* HH | PV | CipherSuite | Ext Len | Key Share | Supported Version | Cookie */
sPymbed 17:ff9d1e86ad5f 3582 #define MAX_HRR_SZ (HANDSHAKE_HEADER_SZ + \
sPymbed 17:ff9d1e86ad5f 3583 HRR_BODY_SZ + \
sPymbed 17:ff9d1e86ad5f 3584 HRR_KEY_SHARE_SZ + \
sPymbed 17:ff9d1e86ad5f 3585 HRR_VERSIONS_SZ + \
sPymbed 17:ff9d1e86ad5f 3586 HRR_COOKIE_HDR_SZ)
sPymbed 17:ff9d1e86ad5f 3587 #endif
sPymbed 17:ff9d1e86ad5f 3588
sPymbed 17:ff9d1e86ad5f 3589 /* Restart the Hanshake hash from the cookie value.
sPymbed 17:ff9d1e86ad5f 3590 *
sPymbed 17:ff9d1e86ad5f 3591 * ssl SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 3592 * cookie Cookie data from client.
sPymbed 17:ff9d1e86ad5f 3593 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 3594 */
sPymbed 17:ff9d1e86ad5f 3595 static int RestartHandshakeHashWithCookie(WOLFSSL* ssl, Cookie* cookie)
sPymbed 17:ff9d1e86ad5f 3596 {
sPymbed 17:ff9d1e86ad5f 3597 byte header[HANDSHAKE_HEADER_SZ];
sPymbed 17:ff9d1e86ad5f 3598 byte hrr[MAX_HRR_SZ];
sPymbed 17:ff9d1e86ad5f 3599 int hrrIdx;
sPymbed 17:ff9d1e86ad5f 3600 word32 idx;
sPymbed 17:ff9d1e86ad5f 3601 byte hashSz;
sPymbed 17:ff9d1e86ad5f 3602 byte* cookieData;
sPymbed 17:ff9d1e86ad5f 3603 byte cookieDataSz;
sPymbed 17:ff9d1e86ad5f 3604 word16 length;
sPymbed 17:ff9d1e86ad5f 3605 int keyShareExt = 0;
sPymbed 17:ff9d1e86ad5f 3606 int ret;
sPymbed 17:ff9d1e86ad5f 3607
sPymbed 17:ff9d1e86ad5f 3608 cookieDataSz = ret = CheckCookie(ssl, &cookie->data, cookie->len);
sPymbed 17:ff9d1e86ad5f 3609 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 3610 return ret;
sPymbed 17:ff9d1e86ad5f 3611 hashSz = cookie->data;
sPymbed 17:ff9d1e86ad5f 3612 cookieData = &cookie->data;
sPymbed 17:ff9d1e86ad5f 3613 idx = OPAQUE8_LEN;
sPymbed 17:ff9d1e86ad5f 3614
sPymbed 17:ff9d1e86ad5f 3615 /* Restart handshake hash with synthetic message hash. */
sPymbed 17:ff9d1e86ad5f 3616 AddTls13HandShakeHeader(header, hashSz, 0, 0, message_hash, ssl);
sPymbed 17:ff9d1e86ad5f 3617 if ((ret = InitHandshakeHashes(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 3618 return ret;
sPymbed 17:ff9d1e86ad5f 3619 if ((ret = HashOutputRaw(ssl, header, sizeof(header))) != 0)
sPymbed 17:ff9d1e86ad5f 3620 return ret;
sPymbed 17:ff9d1e86ad5f 3621 if ((ret = HashOutputRaw(ssl, cookieData + idx, hashSz)) != 0)
sPymbed 17:ff9d1e86ad5f 3622 return ret;
sPymbed 17:ff9d1e86ad5f 3623
sPymbed 17:ff9d1e86ad5f 3624 /* Reconstruct the HelloRetryMessage for handshake hash. */
sPymbed 17:ff9d1e86ad5f 3625 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 3626 length = HRR_BODY_SZ + HRR_COOKIE_HDR_SZ + cookie->len;
sPymbed 17:ff9d1e86ad5f 3627 #else
sPymbed 17:ff9d1e86ad5f 3628 length = HRR_BODY_SZ - ID_LEN + ssl->session.sessionIDSz +
sPymbed 17:ff9d1e86ad5f 3629 HRR_COOKIE_HDR_SZ + cookie->len;
sPymbed 17:ff9d1e86ad5f 3630 length += HRR_VERSIONS_SZ;
sPymbed 17:ff9d1e86ad5f 3631 #endif
sPymbed 17:ff9d1e86ad5f 3632 if (cookieDataSz > hashSz + OPAQUE16_LEN) {
sPymbed 17:ff9d1e86ad5f 3633 keyShareExt = 1;
sPymbed 17:ff9d1e86ad5f 3634 length += HRR_KEY_SHARE_SZ;
sPymbed 17:ff9d1e86ad5f 3635 }
sPymbed 17:ff9d1e86ad5f 3636 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 3637 AddTls13HandShakeHeader(hrr, length, 0, 0, hello_retry_request, ssl);
sPymbed 17:ff9d1e86ad5f 3638
sPymbed 17:ff9d1e86ad5f 3639 idx += hashSz;
sPymbed 17:ff9d1e86ad5f 3640 hrrIdx = HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 3641 /* TODO: [TLS13] Replace existing code with code in comment.
sPymbed 17:ff9d1e86ad5f 3642 * Use the TLS v1.3 draft version for now.
sPymbed 17:ff9d1e86ad5f 3643 *
sPymbed 17:ff9d1e86ad5f 3644 * Change to:
sPymbed 17:ff9d1e86ad5f 3645 * hrr[hrrIdx++] = ssl->version.major;
sPymbed 17:ff9d1e86ad5f 3646 * hrr[hrrIdx++] = ssl->version.minor;
sPymbed 17:ff9d1e86ad5f 3647 */
sPymbed 17:ff9d1e86ad5f 3648 /* The negotiated protocol version. */
sPymbed 17:ff9d1e86ad5f 3649 hrr[hrrIdx++] = TLS_DRAFT_MAJOR;
sPymbed 17:ff9d1e86ad5f 3650 hrr[hrrIdx++] = TLS_DRAFT_MINOR;
sPymbed 17:ff9d1e86ad5f 3651 /* Cipher Suite */
sPymbed 17:ff9d1e86ad5f 3652 hrr[hrrIdx++] = cookieData[idx++];
sPymbed 17:ff9d1e86ad5f 3653 hrr[hrrIdx++] = cookieData[idx++];
sPymbed 17:ff9d1e86ad5f 3654
sPymbed 17:ff9d1e86ad5f 3655 /* Extensions' length */
sPymbed 17:ff9d1e86ad5f 3656 length -= HRR_BODY_SZ;
sPymbed 17:ff9d1e86ad5f 3657 c16toa(length, hrr + hrrIdx);
sPymbed 17:ff9d1e86ad5f 3658 hrrIdx += 2;
sPymbed 17:ff9d1e86ad5f 3659 #else
sPymbed 17:ff9d1e86ad5f 3660 AddTls13HandShakeHeader(hrr, length, 0, 0, server_hello, ssl);
sPymbed 17:ff9d1e86ad5f 3661
sPymbed 17:ff9d1e86ad5f 3662 idx += hashSz;
sPymbed 17:ff9d1e86ad5f 3663 hrrIdx = HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 3664
sPymbed 17:ff9d1e86ad5f 3665 /* The negotiated protocol version. */
sPymbed 17:ff9d1e86ad5f 3666 hrr[hrrIdx++] = ssl->version.major;
sPymbed 17:ff9d1e86ad5f 3667 hrr[hrrIdx++] = TLSv1_2_MINOR;
sPymbed 17:ff9d1e86ad5f 3668
sPymbed 17:ff9d1e86ad5f 3669 /* HelloRetryRequest message has fixed value for random. */
sPymbed 17:ff9d1e86ad5f 3670 XMEMCPY(hrr + hrrIdx, helloRetryRequestRandom, RAN_LEN);
sPymbed 17:ff9d1e86ad5f 3671 hrrIdx += RAN_LEN;
sPymbed 17:ff9d1e86ad5f 3672
sPymbed 17:ff9d1e86ad5f 3673 hrr[hrrIdx++] = ssl->session.sessionIDSz;
sPymbed 17:ff9d1e86ad5f 3674 if (ssl->session.sessionIDSz > 0) {
sPymbed 17:ff9d1e86ad5f 3675 XMEMCPY(hrr + hrrIdx, ssl->session.sessionID, ssl->session.sessionIDSz);
sPymbed 17:ff9d1e86ad5f 3676 hrrIdx += ssl->session.sessionIDSz;
sPymbed 17:ff9d1e86ad5f 3677 }
sPymbed 17:ff9d1e86ad5f 3678
sPymbed 17:ff9d1e86ad5f 3679 /* Cipher Suite */
sPymbed 17:ff9d1e86ad5f 3680 hrr[hrrIdx++] = cookieData[idx++];
sPymbed 17:ff9d1e86ad5f 3681 hrr[hrrIdx++] = cookieData[idx++];
sPymbed 17:ff9d1e86ad5f 3682
sPymbed 17:ff9d1e86ad5f 3683 /* Compression not supported in TLS v1.3. */
sPymbed 17:ff9d1e86ad5f 3684 hrr[hrrIdx++] = 0;
sPymbed 17:ff9d1e86ad5f 3685
sPymbed 17:ff9d1e86ad5f 3686 /* Extensions' length */
sPymbed 17:ff9d1e86ad5f 3687 length -= HRR_BODY_SZ - ID_LEN + ssl->session.sessionIDSz;
sPymbed 17:ff9d1e86ad5f 3688 c16toa(length, hrr + hrrIdx);
sPymbed 17:ff9d1e86ad5f 3689 hrrIdx += 2;
sPymbed 17:ff9d1e86ad5f 3690
sPymbed 17:ff9d1e86ad5f 3691 #endif
sPymbed 17:ff9d1e86ad5f 3692 /* Optional KeyShare Extension */
sPymbed 17:ff9d1e86ad5f 3693 if (keyShareExt) {
sPymbed 17:ff9d1e86ad5f 3694 c16toa(TLSX_KEY_SHARE, hrr + hrrIdx);
sPymbed 17:ff9d1e86ad5f 3695 hrrIdx += 2;
sPymbed 17:ff9d1e86ad5f 3696 c16toa(OPAQUE16_LEN, hrr + hrrIdx);
sPymbed 17:ff9d1e86ad5f 3697 hrrIdx += 2;
sPymbed 17:ff9d1e86ad5f 3698 hrr[hrrIdx++] = cookieData[idx++];
sPymbed 17:ff9d1e86ad5f 3699 hrr[hrrIdx++] = cookieData[idx++];
sPymbed 17:ff9d1e86ad5f 3700 }
sPymbed 17:ff9d1e86ad5f 3701 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 3702 c16toa(TLSX_SUPPORTED_VERSIONS, hrr + hrrIdx);
sPymbed 17:ff9d1e86ad5f 3703 hrrIdx += 2;
sPymbed 17:ff9d1e86ad5f 3704 c16toa(OPAQUE16_LEN, hrr + hrrIdx);
sPymbed 17:ff9d1e86ad5f 3705 hrrIdx += 2;
sPymbed 17:ff9d1e86ad5f 3706 /* TODO: [TLS13] Change to ssl->version.major and minor once final. */
sPymbed 17:ff9d1e86ad5f 3707 #ifdef WOLFSSL_TLS13_FINAL
sPymbed 17:ff9d1e86ad5f 3708 hrr[hrrIdx++] = ssl->version.major;
sPymbed 17:ff9d1e86ad5f 3709 hrr[hrrIdx++] = ssl->version.minor;
sPymbed 17:ff9d1e86ad5f 3710 #else
sPymbed 17:ff9d1e86ad5f 3711 hrr[hrrIdx++] = TLS_DRAFT_MAJOR;
sPymbed 17:ff9d1e86ad5f 3712 hrr[hrrIdx++] = TLS_DRAFT_MINOR;
sPymbed 17:ff9d1e86ad5f 3713 #endif
sPymbed 17:ff9d1e86ad5f 3714 #endif
sPymbed 17:ff9d1e86ad5f 3715 /* Mandatory Cookie Extension */
sPymbed 17:ff9d1e86ad5f 3716 c16toa(TLSX_COOKIE, hrr + hrrIdx);
sPymbed 17:ff9d1e86ad5f 3717 hrrIdx += 2;
sPymbed 17:ff9d1e86ad5f 3718 c16toa(cookie->len + OPAQUE16_LEN, hrr + hrrIdx);
sPymbed 17:ff9d1e86ad5f 3719 hrrIdx += 2;
sPymbed 17:ff9d1e86ad5f 3720 c16toa(cookie->len, hrr + hrrIdx);
sPymbed 17:ff9d1e86ad5f 3721 hrrIdx += 2;
sPymbed 17:ff9d1e86ad5f 3722
sPymbed 17:ff9d1e86ad5f 3723 #ifdef WOLFSSL_DEBUG_TLS
sPymbed 17:ff9d1e86ad5f 3724 WOLFSSL_MSG("Reconstucted HelloRetryRequest");
sPymbed 17:ff9d1e86ad5f 3725 WOLFSSL_BUFFER(hrr, hrrIdx);
sPymbed 17:ff9d1e86ad5f 3726 WOLFSSL_MSG("Cookie");
sPymbed 17:ff9d1e86ad5f 3727 WOLFSSL_BUFFER(cookieData, cookie->len);
sPymbed 17:ff9d1e86ad5f 3728 #endif
sPymbed 17:ff9d1e86ad5f 3729
sPymbed 17:ff9d1e86ad5f 3730 if ((ret = HashOutputRaw(ssl, hrr, hrrIdx)) != 0)
sPymbed 17:ff9d1e86ad5f 3731 return ret;
sPymbed 17:ff9d1e86ad5f 3732 return HashOutputRaw(ssl, cookieData, cookie->len);
sPymbed 17:ff9d1e86ad5f 3733 }
sPymbed 17:ff9d1e86ad5f 3734 #endif
sPymbed 17:ff9d1e86ad5f 3735
sPymbed 17:ff9d1e86ad5f 3736 /* Handle a ClientHello handshake message.
sPymbed 17:ff9d1e86ad5f 3737 * If the protocol version in the message is not TLS v1.3 or higher, use
sPymbed 17:ff9d1e86ad5f 3738 * DoClientHello()
sPymbed 17:ff9d1e86ad5f 3739 * Only a server will receive this message.
sPymbed 17:ff9d1e86ad5f 3740 *
sPymbed 17:ff9d1e86ad5f 3741 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 3742 * input The message buffer.
sPymbed 17:ff9d1e86ad5f 3743 * inOutIdx On entry, the index into the message buffer of ClientHello.
sPymbed 17:ff9d1e86ad5f 3744 * On exit, the index of byte after the ClientHello message and
sPymbed 17:ff9d1e86ad5f 3745 * padding.
sPymbed 17:ff9d1e86ad5f 3746 * helloSz The length of the current handshake message.
sPymbed 17:ff9d1e86ad5f 3747 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 3748 */
sPymbed 17:ff9d1e86ad5f 3749 int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
sPymbed 17:ff9d1e86ad5f 3750 word32 helloSz)
sPymbed 17:ff9d1e86ad5f 3751 {
sPymbed 17:ff9d1e86ad5f 3752 int ret = VERSION_ERROR;
sPymbed 17:ff9d1e86ad5f 3753 byte b;
sPymbed 17:ff9d1e86ad5f 3754 ProtocolVersion pv;
sPymbed 17:ff9d1e86ad5f 3755 Suites clSuites;
sPymbed 17:ff9d1e86ad5f 3756 word32 i = *inOutIdx;
sPymbed 17:ff9d1e86ad5f 3757 word32 begin = i;
sPymbed 17:ff9d1e86ad5f 3758 word16 totalExtSz = 0;
sPymbed 17:ff9d1e86ad5f 3759 int usingPSK = 0;
sPymbed 17:ff9d1e86ad5f 3760 byte sessIdSz;
sPymbed 17:ff9d1e86ad5f 3761 #ifndef WOLFSSL_NO_TLS12
sPymbed 17:ff9d1e86ad5f 3762 int bogusID = 0;
sPymbed 17:ff9d1e86ad5f 3763 #endif
sPymbed 17:ff9d1e86ad5f 3764
sPymbed 17:ff9d1e86ad5f 3765 WOLFSSL_START(WC_FUNC_CLIENT_HELLO_DO);
sPymbed 17:ff9d1e86ad5f 3766 WOLFSSL_ENTER("DoTls13ClientHello");
sPymbed 17:ff9d1e86ad5f 3767
sPymbed 17:ff9d1e86ad5f 3768 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 3769 if (ssl->hsInfoOn) AddPacketName(ssl, "ClientHello");
sPymbed 17:ff9d1e86ad5f 3770 if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
sPymbed 17:ff9d1e86ad5f 3771 #endif
sPymbed 17:ff9d1e86ad5f 3772
sPymbed 17:ff9d1e86ad5f 3773 /* protocol version, random and session id length check */
sPymbed 17:ff9d1e86ad5f 3774 if ((i - begin) + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
sPymbed 17:ff9d1e86ad5f 3775 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3776
sPymbed 17:ff9d1e86ad5f 3777 /* Protocol version */
sPymbed 17:ff9d1e86ad5f 3778 XMEMCPY(&pv, input + i, OPAQUE16_LEN);
sPymbed 17:ff9d1e86ad5f 3779 ssl->chVersion = pv; /* store */
sPymbed 17:ff9d1e86ad5f 3780 i += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 3781 /* Legacy protocol version cannot negotiate TLS 1.3 or higher. */
sPymbed 17:ff9d1e86ad5f 3782 if (pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_3_MINOR)
sPymbed 17:ff9d1e86ad5f 3783 pv.minor = TLSv1_2_MINOR;
sPymbed 17:ff9d1e86ad5f 3784
sPymbed 17:ff9d1e86ad5f 3785 #ifndef WOLFSSL_NO_TLS12
sPymbed 17:ff9d1e86ad5f 3786 if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor < TLSv1_3_MINOR)
sPymbed 17:ff9d1e86ad5f 3787 return DoClientHello(ssl, input, inOutIdx, helloSz);
sPymbed 17:ff9d1e86ad5f 3788 #endif
sPymbed 17:ff9d1e86ad5f 3789
sPymbed 17:ff9d1e86ad5f 3790 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 3791 if (ssl->options.downgrade) {
sPymbed 17:ff9d1e86ad5f 3792 if ((ret = HashInput(ssl, input + begin, helloSz)) != 0)
sPymbed 17:ff9d1e86ad5f 3793 return ret;
sPymbed 17:ff9d1e86ad5f 3794 }
sPymbed 17:ff9d1e86ad5f 3795 #endif
sPymbed 17:ff9d1e86ad5f 3796
sPymbed 17:ff9d1e86ad5f 3797 /* Client random */
sPymbed 17:ff9d1e86ad5f 3798 XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
sPymbed 17:ff9d1e86ad5f 3799 i += RAN_LEN;
sPymbed 17:ff9d1e86ad5f 3800
sPymbed 17:ff9d1e86ad5f 3801 #ifdef WOLFSSL_DEBUG_TLS
sPymbed 17:ff9d1e86ad5f 3802 WOLFSSL_MSG("client random");
sPymbed 17:ff9d1e86ad5f 3803 WOLFSSL_BUFFER(ssl->arrays->clientRandom, RAN_LEN);
sPymbed 17:ff9d1e86ad5f 3804 #endif
sPymbed 17:ff9d1e86ad5f 3805
sPymbed 17:ff9d1e86ad5f 3806 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 3807 /* Session id - empty in TLS v1.3 */
sPymbed 17:ff9d1e86ad5f 3808 sessIdSz = input[i++];
sPymbed 17:ff9d1e86ad5f 3809 if (sessIdSz > 0 && !ssl->options.downgrade) {
sPymbed 17:ff9d1e86ad5f 3810 WOLFSSL_MSG("Client sent session id - not supported");
sPymbed 17:ff9d1e86ad5f 3811 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3812 }
sPymbed 17:ff9d1e86ad5f 3813 #else
sPymbed 17:ff9d1e86ad5f 3814 sessIdSz = input[i++];
sPymbed 17:ff9d1e86ad5f 3815 if (sessIdSz != ID_LEN && sessIdSz != 0)
sPymbed 17:ff9d1e86ad5f 3816 return INVALID_PARAMETER;
sPymbed 17:ff9d1e86ad5f 3817 #endif
sPymbed 17:ff9d1e86ad5f 3818 ssl->session.sessionIDSz = sessIdSz;
sPymbed 17:ff9d1e86ad5f 3819 if (sessIdSz == ID_LEN) {
sPymbed 17:ff9d1e86ad5f 3820 XMEMCPY(ssl->session.sessionID, input + i, sessIdSz);
sPymbed 17:ff9d1e86ad5f 3821 i += ID_LEN;
sPymbed 17:ff9d1e86ad5f 3822 }
sPymbed 17:ff9d1e86ad5f 3823 #ifndef WOLFSSL_NO_TLS12
sPymbed 17:ff9d1e86ad5f 3824 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 3825 if (sessIdSz > 0 && sessIdSz < ID_LEN)
sPymbed 17:ff9d1e86ad5f 3826 bogusID = 1;
sPymbed 17:ff9d1e86ad5f 3827 #endif
sPymbed 17:ff9d1e86ad5f 3828 #endif
sPymbed 17:ff9d1e86ad5f 3829
sPymbed 17:ff9d1e86ad5f 3830 /* Cipher suites */
sPymbed 17:ff9d1e86ad5f 3831 if ((i - begin) + OPAQUE16_LEN > helloSz)
sPymbed 17:ff9d1e86ad5f 3832 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3833 ato16(&input[i], &clSuites.suiteSz);
sPymbed 17:ff9d1e86ad5f 3834 i += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 3835 /* suites and compression length check */
sPymbed 17:ff9d1e86ad5f 3836 if ((i - begin) + clSuites.suiteSz + OPAQUE8_LEN > helloSz)
sPymbed 17:ff9d1e86ad5f 3837 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3838 if (clSuites.suiteSz > WOLFSSL_MAX_SUITE_SZ)
sPymbed 17:ff9d1e86ad5f 3839 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3840 XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
sPymbed 17:ff9d1e86ad5f 3841 i += clSuites.suiteSz;
sPymbed 17:ff9d1e86ad5f 3842 clSuites.hashSigAlgoSz = 0;
sPymbed 17:ff9d1e86ad5f 3843
sPymbed 17:ff9d1e86ad5f 3844 /* Compression */
sPymbed 17:ff9d1e86ad5f 3845 b = input[i++];
sPymbed 17:ff9d1e86ad5f 3846 if ((i - begin) + b > helloSz)
sPymbed 17:ff9d1e86ad5f 3847 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3848 if (b != COMP_LEN) {
sPymbed 17:ff9d1e86ad5f 3849 WOLFSSL_MSG("Must be one compression type in list");
sPymbed 17:ff9d1e86ad5f 3850 return INVALID_PARAMETER;
sPymbed 17:ff9d1e86ad5f 3851 }
sPymbed 17:ff9d1e86ad5f 3852 b = input[i++];
sPymbed 17:ff9d1e86ad5f 3853 if (b != NO_COMPRESSION) {
sPymbed 17:ff9d1e86ad5f 3854 WOLFSSL_MSG("Must be no compression type in list");
sPymbed 17:ff9d1e86ad5f 3855 return INVALID_PARAMETER;
sPymbed 17:ff9d1e86ad5f 3856 }
sPymbed 17:ff9d1e86ad5f 3857
sPymbed 17:ff9d1e86ad5f 3858 if ((i - begin) < helloSz) {
sPymbed 17:ff9d1e86ad5f 3859 if ((i - begin) + OPAQUE16_LEN > helloSz)
sPymbed 17:ff9d1e86ad5f 3860 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3861 ato16(&input[i], &totalExtSz);
sPymbed 17:ff9d1e86ad5f 3862 i += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 3863 if ((i - begin) + totalExtSz > helloSz)
sPymbed 17:ff9d1e86ad5f 3864 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 3865
sPymbed 17:ff9d1e86ad5f 3866 #ifdef HAVE_QSH
sPymbed 17:ff9d1e86ad5f 3867 QSH_Init(ssl);
sPymbed 17:ff9d1e86ad5f 3868 #endif
sPymbed 17:ff9d1e86ad5f 3869
sPymbed 17:ff9d1e86ad5f 3870 /* Auto populate extensions supported unless user defined. */
sPymbed 17:ff9d1e86ad5f 3871 if ((ret = TLSX_PopulateExtensions(ssl, 1)) != 0)
sPymbed 17:ff9d1e86ad5f 3872 return ret;
sPymbed 17:ff9d1e86ad5f 3873
sPymbed 17:ff9d1e86ad5f 3874 /* Parse extensions */
sPymbed 17:ff9d1e86ad5f 3875 if ((ret = TLSX_Parse(ssl, (byte*)input + i, totalExtSz, client_hello,
sPymbed 17:ff9d1e86ad5f 3876 &clSuites))) {
sPymbed 17:ff9d1e86ad5f 3877 return ret;
sPymbed 17:ff9d1e86ad5f 3878 }
sPymbed 17:ff9d1e86ad5f 3879
sPymbed 17:ff9d1e86ad5f 3880 #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
sPymbed 17:ff9d1e86ad5f 3881 defined(WOLFSSL_HAPROXY)
sPymbed 17:ff9d1e86ad5f 3882 if ((ret = SNI_Callback(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 3883 return ret;
sPymbed 17:ff9d1e86ad5f 3884 ssl->options.side = WOLFSSL_SERVER_END;
sPymbed 17:ff9d1e86ad5f 3885 #endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
sPymbed 17:ff9d1e86ad5f 3886 }
sPymbed 17:ff9d1e86ad5f 3887
sPymbed 17:ff9d1e86ad5f 3888 i += totalExtSz;
sPymbed 17:ff9d1e86ad5f 3889 *inOutIdx = i;
sPymbed 17:ff9d1e86ad5f 3890
sPymbed 17:ff9d1e86ad5f 3891 if (TLSX_Find(ssl->extensions, TLSX_SUPPORTED_VERSIONS) == NULL) {
sPymbed 17:ff9d1e86ad5f 3892 if (!ssl->options.downgrade) {
sPymbed 17:ff9d1e86ad5f 3893 WOLFSSL_MSG("Client trying to connect with lesser version than "
sPymbed 17:ff9d1e86ad5f 3894 "TLS v1.3");
sPymbed 17:ff9d1e86ad5f 3895 return VERSION_ERROR;
sPymbed 17:ff9d1e86ad5f 3896 }
sPymbed 17:ff9d1e86ad5f 3897
sPymbed 17:ff9d1e86ad5f 3898 if (pv.minor < ssl->options.minDowngrade)
sPymbed 17:ff9d1e86ad5f 3899 return VERSION_ERROR;
sPymbed 17:ff9d1e86ad5f 3900 ssl->version.minor = pv.minor;
sPymbed 17:ff9d1e86ad5f 3901 }
sPymbed 17:ff9d1e86ad5f 3902
sPymbed 17:ff9d1e86ad5f 3903 ssl->options.sendVerify = SEND_CERT;
sPymbed 17:ff9d1e86ad5f 3904
sPymbed 17:ff9d1e86ad5f 3905 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
sPymbed 17:ff9d1e86ad5f 3906 ssl->options.haveSessionId = 1;
sPymbed 17:ff9d1e86ad5f 3907
sPymbed 17:ff9d1e86ad5f 3908 if (IsAtLeastTLSv1_3(ssl->version)) {
sPymbed 17:ff9d1e86ad5f 3909 #if !defined(WOLFSSL_TLS13_DRAFT_18) && defined(WOLFSSL_SEND_HRR_COOKIE)
sPymbed 17:ff9d1e86ad5f 3910 if (ssl->options.sendCookie &&
sPymbed 17:ff9d1e86ad5f 3911 ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 3912 TLSX* ext;
sPymbed 17:ff9d1e86ad5f 3913
sPymbed 17:ff9d1e86ad5f 3914 if ((ext = TLSX_Find(ssl->extensions, TLSX_COOKIE)) == NULL)
sPymbed 17:ff9d1e86ad5f 3915 return HRR_COOKIE_ERROR;
sPymbed 17:ff9d1e86ad5f 3916 /* Ensure the cookie came from client and isn't the one in the
sPymbed 17:ff9d1e86ad5f 3917 * response - HelloRetryRequest.
sPymbed 17:ff9d1e86ad5f 3918 */
sPymbed 17:ff9d1e86ad5f 3919 if (ext->resp == 1)
sPymbed 17:ff9d1e86ad5f 3920 return HRR_COOKIE_ERROR;
sPymbed 17:ff9d1e86ad5f 3921 ret = RestartHandshakeHashWithCookie(ssl, (Cookie*)ext->data);
sPymbed 17:ff9d1e86ad5f 3922 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3923 return ret;
sPymbed 17:ff9d1e86ad5f 3924 }
sPymbed 17:ff9d1e86ad5f 3925 #endif
sPymbed 17:ff9d1e86ad5f 3926
sPymbed 17:ff9d1e86ad5f 3927 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 3928 if (ssl->options.downgrade) {
sPymbed 17:ff9d1e86ad5f 3929 if ((ret = InitHandshakeHashes(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 3930 return ret;
sPymbed 17:ff9d1e86ad5f 3931 }
sPymbed 17:ff9d1e86ad5f 3932
sPymbed 17:ff9d1e86ad5f 3933 /* Refine list for PSK processing. */
sPymbed 17:ff9d1e86ad5f 3934 RefineSuites(ssl, &clSuites);
sPymbed 17:ff9d1e86ad5f 3935
sPymbed 17:ff9d1e86ad5f 3936 /* Process the Pre-Shared Key extension if present. */
sPymbed 17:ff9d1e86ad5f 3937 ret = DoPreSharedKeys(ssl, input + begin, helloSz, &usingPSK);
sPymbed 17:ff9d1e86ad5f 3938 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3939 return ret;
sPymbed 17:ff9d1e86ad5f 3940 #endif
sPymbed 17:ff9d1e86ad5f 3941 }
sPymbed 17:ff9d1e86ad5f 3942 #ifndef WOLFSSL_NO_TLS12
sPymbed 17:ff9d1e86ad5f 3943 else if (ssl->options.resuming) {
sPymbed 17:ff9d1e86ad5f 3944 ret = HandleTlsResumption(ssl, bogusID, &clSuites);
sPymbed 17:ff9d1e86ad5f 3945 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 3946 return ret;
sPymbed 17:ff9d1e86ad5f 3947 /* Check wheter resuming has been chosen */
sPymbed 17:ff9d1e86ad5f 3948 if (ssl->options.clientState == CLIENT_KEYEXCHANGE_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 3949 WOLFSSL_LEAVE("DoTls13ClientHello", ret);
sPymbed 17:ff9d1e86ad5f 3950 WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO);
sPymbed 17:ff9d1e86ad5f 3951
sPymbed 17:ff9d1e86ad5f 3952 return ret;
sPymbed 17:ff9d1e86ad5f 3953 }
sPymbed 17:ff9d1e86ad5f 3954 }
sPymbed 17:ff9d1e86ad5f 3955 #else
sPymbed 17:ff9d1e86ad5f 3956 else {
sPymbed 17:ff9d1e86ad5f 3957 WOLFSSL_MSG("Negotiated lesser version than TLS v1.3");
sPymbed 17:ff9d1e86ad5f 3958 return VERSION_ERROR;
sPymbed 17:ff9d1e86ad5f 3959 }
sPymbed 17:ff9d1e86ad5f 3960 #endif
sPymbed 17:ff9d1e86ad5f 3961
sPymbed 17:ff9d1e86ad5f 3962 if (!usingPSK) {
sPymbed 17:ff9d1e86ad5f 3963 if ((ret = MatchSuite(ssl, &clSuites)) < 0) {
sPymbed 17:ff9d1e86ad5f 3964 WOLFSSL_MSG("Unsupported cipher suite, ClientHello");
sPymbed 17:ff9d1e86ad5f 3965 return ret;
sPymbed 17:ff9d1e86ad5f 3966 }
sPymbed 17:ff9d1e86ad5f 3967
sPymbed 17:ff9d1e86ad5f 3968 /* Check that the negotiated ciphersuite matches protocol version. */
sPymbed 17:ff9d1e86ad5f 3969 if (IsAtLeastTLSv1_3(ssl->version)) {
sPymbed 17:ff9d1e86ad5f 3970 if (ssl->options.cipherSuite0 != TLS13_BYTE) {
sPymbed 17:ff9d1e86ad5f 3971 WOLFSSL_MSG("Negotiated ciphersuite from lesser version than "
sPymbed 17:ff9d1e86ad5f 3972 "TLS v1.3");
sPymbed 17:ff9d1e86ad5f 3973 return VERSION_ERROR;
sPymbed 17:ff9d1e86ad5f 3974 }
sPymbed 17:ff9d1e86ad5f 3975 }
sPymbed 17:ff9d1e86ad5f 3976 /* VerifyServerSuite handles when version is less than 1.3 */
sPymbed 17:ff9d1e86ad5f 3977
sPymbed 17:ff9d1e86ad5f 3978 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 3979 if (ssl->options.resuming) {
sPymbed 17:ff9d1e86ad5f 3980 ssl->options.resuming = 0;
sPymbed 17:ff9d1e86ad5f 3981 XMEMSET(ssl->arrays->psk_key, 0, ssl->specs.hash_size);
sPymbed 17:ff9d1e86ad5f 3982 /* May or may not have done any hashing. */
sPymbed 17:ff9d1e86ad5f 3983 if ((ret = InitHandshakeHashes(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 3984 return ret;
sPymbed 17:ff9d1e86ad5f 3985 }
sPymbed 17:ff9d1e86ad5f 3986 #endif
sPymbed 17:ff9d1e86ad5f 3987
sPymbed 17:ff9d1e86ad5f 3988 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 3989 if (IsAtLeastTLSv1_3(ssl->version) || !ssl->options.downgrade)
sPymbed 17:ff9d1e86ad5f 3990 #endif
sPymbed 17:ff9d1e86ad5f 3991 {
sPymbed 17:ff9d1e86ad5f 3992 if ((ret = HashInput(ssl, input + begin, helloSz)) != 0)
sPymbed 17:ff9d1e86ad5f 3993 return ret;
sPymbed 17:ff9d1e86ad5f 3994 }
sPymbed 17:ff9d1e86ad5f 3995
sPymbed 17:ff9d1e86ad5f 3996 if (IsAtLeastTLSv1_3(ssl->version)) {
sPymbed 17:ff9d1e86ad5f 3997 /* Derive early secret for handshake secret. */
sPymbed 17:ff9d1e86ad5f 3998 if ((ret = DeriveEarlySecret(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 3999 return ret;
sPymbed 17:ff9d1e86ad5f 4000 }
sPymbed 17:ff9d1e86ad5f 4001 }
sPymbed 17:ff9d1e86ad5f 4002
sPymbed 17:ff9d1e86ad5f 4003 WOLFSSL_LEAVE("DoTls13ClientHello", ret);
sPymbed 17:ff9d1e86ad5f 4004 WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO);
sPymbed 17:ff9d1e86ad5f 4005
sPymbed 17:ff9d1e86ad5f 4006 return ret;
sPymbed 17:ff9d1e86ad5f 4007 }
sPymbed 17:ff9d1e86ad5f 4008
sPymbed 17:ff9d1e86ad5f 4009 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 4010 /* handle generation of TLS 1.3 hello_retry_request (6) */
sPymbed 17:ff9d1e86ad5f 4011 /* Send the HelloRetryRequest message to indicate the negotiated protocol
sPymbed 17:ff9d1e86ad5f 4012 * version and security parameters the server is willing to use.
sPymbed 17:ff9d1e86ad5f 4013 * Only a server will send this message.
sPymbed 17:ff9d1e86ad5f 4014 *
sPymbed 17:ff9d1e86ad5f 4015 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 4016 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 4017 */
sPymbed 17:ff9d1e86ad5f 4018 int SendTls13HelloRetryRequest(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 4019 {
sPymbed 17:ff9d1e86ad5f 4020 int ret;
sPymbed 17:ff9d1e86ad5f 4021 byte* output;
sPymbed 17:ff9d1e86ad5f 4022 word32 length;
sPymbed 17:ff9d1e86ad5f 4023 word16 len;
sPymbed 17:ff9d1e86ad5f 4024 word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4025 int sendSz;
sPymbed 17:ff9d1e86ad5f 4026
sPymbed 17:ff9d1e86ad5f 4027 WOLFSSL_ENTER("SendTls13HelloRetryRequest");
sPymbed 17:ff9d1e86ad5f 4028
sPymbed 17:ff9d1e86ad5f 4029 /* Get the length of the extensions that will be written. */
sPymbed 17:ff9d1e86ad5f 4030 len = 0;
sPymbed 17:ff9d1e86ad5f 4031 ret = TLSX_GetResponseSize(ssl, hello_retry_request, &len);
sPymbed 17:ff9d1e86ad5f 4032 /* There must be extensions sent to indicate what client needs to do. */
sPymbed 17:ff9d1e86ad5f 4033 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 4034 return MISSING_HANDSHAKE_DATA;
sPymbed 17:ff9d1e86ad5f 4035
sPymbed 17:ff9d1e86ad5f 4036 /* Protocol version + Extensions */
sPymbed 17:ff9d1e86ad5f 4037 length = OPAQUE16_LEN + len;
sPymbed 17:ff9d1e86ad5f 4038 sendSz = idx + length;
sPymbed 17:ff9d1e86ad5f 4039
sPymbed 17:ff9d1e86ad5f 4040 /* Check buffers are big enough and grow if needed. */
sPymbed 17:ff9d1e86ad5f 4041 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
sPymbed 17:ff9d1e86ad5f 4042 return ret;
sPymbed 17:ff9d1e86ad5f 4043
sPymbed 17:ff9d1e86ad5f 4044 /* Get position in output buffer to write new message to. */
sPymbed 17:ff9d1e86ad5f 4045 output = ssl->buffers.outputBuffer.buffer +
sPymbed 17:ff9d1e86ad5f 4046 ssl->buffers.outputBuffer.length;
sPymbed 17:ff9d1e86ad5f 4047 /* Add record and hanshake headers. */
sPymbed 17:ff9d1e86ad5f 4048 AddTls13Headers(output, length, hello_retry_request, ssl);
sPymbed 17:ff9d1e86ad5f 4049
sPymbed 17:ff9d1e86ad5f 4050 /* TODO: [TLS13] Replace existing code with code in comment.
sPymbed 17:ff9d1e86ad5f 4051 * Use the TLS v1.3 draft version for now.
sPymbed 17:ff9d1e86ad5f 4052 *
sPymbed 17:ff9d1e86ad5f 4053 * Change to:
sPymbed 17:ff9d1e86ad5f 4054 * output[idx++] = ssl->version.major;
sPymbed 17:ff9d1e86ad5f 4055 * output[idx++] = ssl->version.minor;
sPymbed 17:ff9d1e86ad5f 4056 */
sPymbed 17:ff9d1e86ad5f 4057 /* The negotiated protocol version. */
sPymbed 17:ff9d1e86ad5f 4058 output[idx++] = TLS_DRAFT_MAJOR;
sPymbed 17:ff9d1e86ad5f 4059 output[idx++] = TLS_DRAFT_MINOR;
sPymbed 17:ff9d1e86ad5f 4060
sPymbed 17:ff9d1e86ad5f 4061 /* Add TLS extensions. */
sPymbed 17:ff9d1e86ad5f 4062 ret = TLSX_WriteResponse(ssl, output + idx, hello_retry_request, NULL);
sPymbed 17:ff9d1e86ad5f 4063 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 4064 return ret;
sPymbed 17:ff9d1e86ad5f 4065 idx += len;
sPymbed 17:ff9d1e86ad5f 4066
sPymbed 17:ff9d1e86ad5f 4067 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 4068 if (ssl->hsInfoOn)
sPymbed 17:ff9d1e86ad5f 4069 AddPacketName(ssl, "HelloRetryRequest");
sPymbed 17:ff9d1e86ad5f 4070 if (ssl->toInfoOn) {
sPymbed 17:ff9d1e86ad5f 4071 AddPacketInfo(ssl, "HelloRetryRequest", handshake, output, sendSz,
sPymbed 17:ff9d1e86ad5f 4072 WRITE_PROTO, ssl->heap);
sPymbed 17:ff9d1e86ad5f 4073 }
sPymbed 17:ff9d1e86ad5f 4074 #endif
sPymbed 17:ff9d1e86ad5f 4075 if ((ret = HashOutput(ssl, output, idx, 0)) != 0)
sPymbed 17:ff9d1e86ad5f 4076 return ret;
sPymbed 17:ff9d1e86ad5f 4077
sPymbed 17:ff9d1e86ad5f 4078 ssl->buffers.outputBuffer.length += sendSz;
sPymbed 17:ff9d1e86ad5f 4079
sPymbed 17:ff9d1e86ad5f 4080 if (!ssl->options.groupMessages)
sPymbed 17:ff9d1e86ad5f 4081 ret = SendBuffered(ssl);
sPymbed 17:ff9d1e86ad5f 4082
sPymbed 17:ff9d1e86ad5f 4083 WOLFSSL_LEAVE("SendTls13HelloRetryRequest", ret);
sPymbed 17:ff9d1e86ad5f 4084
sPymbed 17:ff9d1e86ad5f 4085 return ret;
sPymbed 17:ff9d1e86ad5f 4086 }
sPymbed 17:ff9d1e86ad5f 4087 #endif /* WOLFSSL_TLS13_DRAFT_18 */
sPymbed 17:ff9d1e86ad5f 4088
sPymbed 17:ff9d1e86ad5f 4089 /* Send TLS v1.3 ServerHello message to client.
sPymbed 17:ff9d1e86ad5f 4090 * Only a server will send this message.
sPymbed 17:ff9d1e86ad5f 4091 *
sPymbed 17:ff9d1e86ad5f 4092 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 4093 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 4094 */
sPymbed 17:ff9d1e86ad5f 4095 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 4096 static
sPymbed 17:ff9d1e86ad5f 4097 #endif
sPymbed 17:ff9d1e86ad5f 4098 /* handle generation of TLS 1.3 server_hello (2) */
sPymbed 17:ff9d1e86ad5f 4099 int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType)
sPymbed 17:ff9d1e86ad5f 4100 {
sPymbed 17:ff9d1e86ad5f 4101 int ret;
sPymbed 17:ff9d1e86ad5f 4102 byte* output;
sPymbed 17:ff9d1e86ad5f 4103 word16 length;
sPymbed 17:ff9d1e86ad5f 4104 word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4105 int sendSz;
sPymbed 17:ff9d1e86ad5f 4106
sPymbed 17:ff9d1e86ad5f 4107 WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND);
sPymbed 17:ff9d1e86ad5f 4108 WOLFSSL_ENTER("SendTls13ServerHello");
sPymbed 17:ff9d1e86ad5f 4109
sPymbed 17:ff9d1e86ad5f 4110 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 4111 if (extMsgType == hello_retry_request) {
sPymbed 17:ff9d1e86ad5f 4112 if ((ret = RestartHandshakeHash(ssl)) < 0)
sPymbed 17:ff9d1e86ad5f 4113 return ret;
sPymbed 17:ff9d1e86ad5f 4114 }
sPymbed 17:ff9d1e86ad5f 4115 #endif
sPymbed 17:ff9d1e86ad5f 4116
sPymbed 17:ff9d1e86ad5f 4117 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 4118 /* Protocol version, server random, cipher suite and extensions. */
sPymbed 17:ff9d1e86ad5f 4119 length = VERSION_SZ + RAN_LEN + SUITE_LEN;
sPymbed 17:ff9d1e86ad5f 4120 ret = TLSX_GetResponseSize(ssl, server_hello, &length);
sPymbed 17:ff9d1e86ad5f 4121 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 4122 return ret;
sPymbed 17:ff9d1e86ad5f 4123 #else
sPymbed 17:ff9d1e86ad5f 4124 /* Protocol version, server random, session id, cipher suite, compression
sPymbed 17:ff9d1e86ad5f 4125 * and extensions.
sPymbed 17:ff9d1e86ad5f 4126 */
sPymbed 17:ff9d1e86ad5f 4127 length = VERSION_SZ + RAN_LEN + ENUM_LEN + ssl->session.sessionIDSz +
sPymbed 17:ff9d1e86ad5f 4128 SUITE_LEN + COMP_LEN;
sPymbed 17:ff9d1e86ad5f 4129 ret = TLSX_GetResponseSize(ssl, extMsgType, &length);
sPymbed 17:ff9d1e86ad5f 4130 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 4131 return ret;
sPymbed 17:ff9d1e86ad5f 4132 #endif
sPymbed 17:ff9d1e86ad5f 4133 sendSz = idx + length;
sPymbed 17:ff9d1e86ad5f 4134
sPymbed 17:ff9d1e86ad5f 4135 /* Check buffers are big enough and grow if needed. */
sPymbed 17:ff9d1e86ad5f 4136 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
sPymbed 17:ff9d1e86ad5f 4137 return ret;
sPymbed 17:ff9d1e86ad5f 4138
sPymbed 17:ff9d1e86ad5f 4139 /* Get position in output buffer to write new message to. */
sPymbed 17:ff9d1e86ad5f 4140 output = ssl->buffers.outputBuffer.buffer +
sPymbed 17:ff9d1e86ad5f 4141 ssl->buffers.outputBuffer.length;
sPymbed 17:ff9d1e86ad5f 4142
sPymbed 17:ff9d1e86ad5f 4143 /* Put the record and handshake headers on. */
sPymbed 17:ff9d1e86ad5f 4144 AddTls13Headers(output, length, server_hello, ssl);
sPymbed 17:ff9d1e86ad5f 4145
sPymbed 17:ff9d1e86ad5f 4146 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 4147 /* TODO: [TLS13] Replace existing code with code in comment.
sPymbed 17:ff9d1e86ad5f 4148 * Use the TLS v1.3 draft version for now.
sPymbed 17:ff9d1e86ad5f 4149 *
sPymbed 17:ff9d1e86ad5f 4150 * Change to:
sPymbed 17:ff9d1e86ad5f 4151 * output[idx++] = ssl->version.major;
sPymbed 17:ff9d1e86ad5f 4152 * output[idx++] = ssl->version.minor;
sPymbed 17:ff9d1e86ad5f 4153 */
sPymbed 17:ff9d1e86ad5f 4154 /* The negotiated protocol version. */
sPymbed 17:ff9d1e86ad5f 4155 output[idx++] = TLS_DRAFT_MAJOR;
sPymbed 17:ff9d1e86ad5f 4156 output[idx++] = TLS_DRAFT_MINOR;
sPymbed 17:ff9d1e86ad5f 4157 #else
sPymbed 17:ff9d1e86ad5f 4158 /* The protocol version must be TLS v1.2 for middleboxes. */
sPymbed 17:ff9d1e86ad5f 4159 output[idx++] = ssl->version.major;
sPymbed 17:ff9d1e86ad5f 4160 output[idx++] = TLSv1_2_MINOR;
sPymbed 17:ff9d1e86ad5f 4161 #endif
sPymbed 17:ff9d1e86ad5f 4162
sPymbed 17:ff9d1e86ad5f 4163 if (extMsgType == server_hello) {
sPymbed 17:ff9d1e86ad5f 4164 /* Generate server random. */
sPymbed 17:ff9d1e86ad5f 4165 if ((ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN)) != 0)
sPymbed 17:ff9d1e86ad5f 4166 return ret;
sPymbed 17:ff9d1e86ad5f 4167 }
sPymbed 17:ff9d1e86ad5f 4168 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 4169 else {
sPymbed 17:ff9d1e86ad5f 4170 /* HelloRetryRequest message has fixed value for random. */
sPymbed 17:ff9d1e86ad5f 4171 XMEMCPY(output + idx, helloRetryRequestRandom, RAN_LEN);
sPymbed 17:ff9d1e86ad5f 4172 }
sPymbed 17:ff9d1e86ad5f 4173 #endif
sPymbed 17:ff9d1e86ad5f 4174 /* Store in SSL for debugging. */
sPymbed 17:ff9d1e86ad5f 4175 XMEMCPY(ssl->arrays->serverRandom, output + idx, RAN_LEN);
sPymbed 17:ff9d1e86ad5f 4176 idx += RAN_LEN;
sPymbed 17:ff9d1e86ad5f 4177
sPymbed 17:ff9d1e86ad5f 4178 #ifdef WOLFSSL_DEBUG_TLS
sPymbed 17:ff9d1e86ad5f 4179 WOLFSSL_MSG("Server random");
sPymbed 17:ff9d1e86ad5f 4180 WOLFSSL_BUFFER(ssl->arrays->serverRandom, RAN_LEN);
sPymbed 17:ff9d1e86ad5f 4181 #endif
sPymbed 17:ff9d1e86ad5f 4182
sPymbed 17:ff9d1e86ad5f 4183 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 4184 output[idx++] = ssl->session.sessionIDSz;
sPymbed 17:ff9d1e86ad5f 4185 if (ssl->session.sessionIDSz > 0) {
sPymbed 17:ff9d1e86ad5f 4186 XMEMCPY(output + idx, ssl->session.sessionID, ssl->session.sessionIDSz);
sPymbed 17:ff9d1e86ad5f 4187 idx += ssl->session.sessionIDSz;
sPymbed 17:ff9d1e86ad5f 4188 }
sPymbed 17:ff9d1e86ad5f 4189 #endif
sPymbed 17:ff9d1e86ad5f 4190
sPymbed 17:ff9d1e86ad5f 4191 /* Chosen cipher suite */
sPymbed 17:ff9d1e86ad5f 4192 output[idx++] = ssl->options.cipherSuite0;
sPymbed 17:ff9d1e86ad5f 4193 output[idx++] = ssl->options.cipherSuite;
sPymbed 17:ff9d1e86ad5f 4194
sPymbed 17:ff9d1e86ad5f 4195 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 4196 /* Compression not supported in TLS v1.3. */
sPymbed 17:ff9d1e86ad5f 4197 output[idx++] = 0;
sPymbed 17:ff9d1e86ad5f 4198 #endif
sPymbed 17:ff9d1e86ad5f 4199
sPymbed 17:ff9d1e86ad5f 4200 /* Extensions */
sPymbed 17:ff9d1e86ad5f 4201 ret = TLSX_WriteResponse(ssl, output + idx, extMsgType, NULL);
sPymbed 17:ff9d1e86ad5f 4202 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 4203 return ret;
sPymbed 17:ff9d1e86ad5f 4204
sPymbed 17:ff9d1e86ad5f 4205 ssl->buffers.outputBuffer.length += sendSz;
sPymbed 17:ff9d1e86ad5f 4206
sPymbed 17:ff9d1e86ad5f 4207 if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0)
sPymbed 17:ff9d1e86ad5f 4208 return ret;
sPymbed 17:ff9d1e86ad5f 4209
sPymbed 17:ff9d1e86ad5f 4210 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 4211 if (ssl->hsInfoOn)
sPymbed 17:ff9d1e86ad5f 4212 AddPacketName(ssl, "ServerHello");
sPymbed 17:ff9d1e86ad5f 4213 if (ssl->toInfoOn) {
sPymbed 17:ff9d1e86ad5f 4214 AddPacketInfo(ssl, "ServerHello", handshake, output, sendSz,
sPymbed 17:ff9d1e86ad5f 4215 WRITE_PROTO, ssl->heap);
sPymbed 17:ff9d1e86ad5f 4216 }
sPymbed 17:ff9d1e86ad5f 4217 #endif
sPymbed 17:ff9d1e86ad5f 4218
sPymbed 17:ff9d1e86ad5f 4219 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 4220 ssl->options.serverState = SERVER_HELLO_COMPLETE;
sPymbed 17:ff9d1e86ad5f 4221 #else
sPymbed 17:ff9d1e86ad5f 4222 if (extMsgType == server_hello)
sPymbed 17:ff9d1e86ad5f 4223 ssl->options.serverState = SERVER_HELLO_COMPLETE;
sPymbed 17:ff9d1e86ad5f 4224 #endif
sPymbed 17:ff9d1e86ad5f 4225
sPymbed 17:ff9d1e86ad5f 4226 if (!ssl->options.groupMessages)
sPymbed 17:ff9d1e86ad5f 4227 ret = SendBuffered(ssl);
sPymbed 17:ff9d1e86ad5f 4228
sPymbed 17:ff9d1e86ad5f 4229 WOLFSSL_LEAVE("SendTls13ServerHello", ret);
sPymbed 17:ff9d1e86ad5f 4230 WOLFSSL_END(WC_FUNC_SERVER_HELLO_SEND);
sPymbed 17:ff9d1e86ad5f 4231
sPymbed 17:ff9d1e86ad5f 4232 return ret;
sPymbed 17:ff9d1e86ad5f 4233 }
sPymbed 17:ff9d1e86ad5f 4234
sPymbed 17:ff9d1e86ad5f 4235 /* handle generation of TLS 1.3 encrypted_extensions (8) */
sPymbed 17:ff9d1e86ad5f 4236 /* Send the rest of the extensions encrypted under the handshake key.
sPymbed 17:ff9d1e86ad5f 4237 * This message is always encrypted in TLS v1.3.
sPymbed 17:ff9d1e86ad5f 4238 * Only a server will send this message.
sPymbed 17:ff9d1e86ad5f 4239 *
sPymbed 17:ff9d1e86ad5f 4240 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 4241 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 4242 */
sPymbed 17:ff9d1e86ad5f 4243 static int SendTls13EncryptedExtensions(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 4244 {
sPymbed 17:ff9d1e86ad5f 4245 int ret;
sPymbed 17:ff9d1e86ad5f 4246 byte* output;
sPymbed 17:ff9d1e86ad5f 4247 word16 length = 0;
sPymbed 17:ff9d1e86ad5f 4248 word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4249 int sendSz;
sPymbed 17:ff9d1e86ad5f 4250
sPymbed 17:ff9d1e86ad5f 4251 WOLFSSL_START(WC_FUNC_ENCRYPTED_EXTENSIONS_SEND);
sPymbed 17:ff9d1e86ad5f 4252 WOLFSSL_ENTER("SendTls13EncryptedExtensions");
sPymbed 17:ff9d1e86ad5f 4253
sPymbed 17:ff9d1e86ad5f 4254 ssl->keys.encryptionOn = 1;
sPymbed 17:ff9d1e86ad5f 4255
sPymbed 17:ff9d1e86ad5f 4256 #ifndef WOLFSSL_NO_SERVER_GROUPS_EXT
sPymbed 17:ff9d1e86ad5f 4257 if ((ret = TLSX_SupportedCurve_CheckPriority(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 4258 return ret;
sPymbed 17:ff9d1e86ad5f 4259 #endif
sPymbed 17:ff9d1e86ad5f 4260
sPymbed 17:ff9d1e86ad5f 4261 /* Derive the handshake secret now that we are at first message to be
sPymbed 17:ff9d1e86ad5f 4262 * encrypted under the keys.
sPymbed 17:ff9d1e86ad5f 4263 */
sPymbed 17:ff9d1e86ad5f 4264 if ((ret = DeriveHandshakeSecret(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 4265 return ret;
sPymbed 17:ff9d1e86ad5f 4266 if ((ret = DeriveTls13Keys(ssl, handshake_key,
sPymbed 17:ff9d1e86ad5f 4267 ENCRYPT_AND_DECRYPT_SIDE, 1)) != 0)
sPymbed 17:ff9d1e86ad5f 4268 return ret;
sPymbed 17:ff9d1e86ad5f 4269
sPymbed 17:ff9d1e86ad5f 4270 /* Setup encrypt/decrypt keys for following messages. */
sPymbed 17:ff9d1e86ad5f 4271 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 4272 if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
sPymbed 17:ff9d1e86ad5f 4273 return ret;
sPymbed 17:ff9d1e86ad5f 4274 if (ssl->earlyData != process_early_data) {
sPymbed 17:ff9d1e86ad5f 4275 if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
sPymbed 17:ff9d1e86ad5f 4276 return ret;
sPymbed 17:ff9d1e86ad5f 4277 }
sPymbed 17:ff9d1e86ad5f 4278 #else
sPymbed 17:ff9d1e86ad5f 4279 if ((ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE)) != 0)
sPymbed 17:ff9d1e86ad5f 4280 return ret;
sPymbed 17:ff9d1e86ad5f 4281 #endif
sPymbed 17:ff9d1e86ad5f 4282
sPymbed 17:ff9d1e86ad5f 4283 ret = TLSX_GetResponseSize(ssl, encrypted_extensions, &length);
sPymbed 17:ff9d1e86ad5f 4284 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 4285 return ret;
sPymbed 17:ff9d1e86ad5f 4286
sPymbed 17:ff9d1e86ad5f 4287 sendSz = idx + length;
sPymbed 17:ff9d1e86ad5f 4288 /* Encryption always on. */
sPymbed 17:ff9d1e86ad5f 4289 sendSz += MAX_MSG_EXTRA;
sPymbed 17:ff9d1e86ad5f 4290
sPymbed 17:ff9d1e86ad5f 4291 /* Check buffers are big enough and grow if needed. */
sPymbed 17:ff9d1e86ad5f 4292 ret = CheckAvailableSize(ssl, sendSz);
sPymbed 17:ff9d1e86ad5f 4293 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 4294 return ret;
sPymbed 17:ff9d1e86ad5f 4295
sPymbed 17:ff9d1e86ad5f 4296 /* Get position in output buffer to write new message to. */
sPymbed 17:ff9d1e86ad5f 4297 output = ssl->buffers.outputBuffer.buffer +
sPymbed 17:ff9d1e86ad5f 4298 ssl->buffers.outputBuffer.length;
sPymbed 17:ff9d1e86ad5f 4299
sPymbed 17:ff9d1e86ad5f 4300 /* Put the record and handshake headers on. */
sPymbed 17:ff9d1e86ad5f 4301 AddTls13Headers(output, length, encrypted_extensions, ssl);
sPymbed 17:ff9d1e86ad5f 4302
sPymbed 17:ff9d1e86ad5f 4303 ret = TLSX_WriteResponse(ssl, output + idx, encrypted_extensions, NULL);
sPymbed 17:ff9d1e86ad5f 4304 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 4305 return ret;
sPymbed 17:ff9d1e86ad5f 4306 idx += length;
sPymbed 17:ff9d1e86ad5f 4307
sPymbed 17:ff9d1e86ad5f 4308 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 4309 if (ssl->hsInfoOn)
sPymbed 17:ff9d1e86ad5f 4310 AddPacketName(ssl, "EncryptedExtensions");
sPymbed 17:ff9d1e86ad5f 4311 if (ssl->toInfoOn) {
sPymbed 17:ff9d1e86ad5f 4312 AddPacketInfo(ssl, "EncryptedExtensions", handshake, output,
sPymbed 17:ff9d1e86ad5f 4313 sendSz, WRITE_PROTO, ssl->heap);
sPymbed 17:ff9d1e86ad5f 4314 }
sPymbed 17:ff9d1e86ad5f 4315 #endif
sPymbed 17:ff9d1e86ad5f 4316
sPymbed 17:ff9d1e86ad5f 4317 /* This handshake message is always encrypted. */
sPymbed 17:ff9d1e86ad5f 4318 sendSz = BuildTls13Message(ssl, output, sendSz, output + RECORD_HEADER_SZ,
sPymbed 17:ff9d1e86ad5f 4319 idx - RECORD_HEADER_SZ, handshake, 1, 0, 0);
sPymbed 17:ff9d1e86ad5f 4320 if (sendSz < 0)
sPymbed 17:ff9d1e86ad5f 4321 return sendSz;
sPymbed 17:ff9d1e86ad5f 4322
sPymbed 17:ff9d1e86ad5f 4323 ssl->buffers.outputBuffer.length += sendSz;
sPymbed 17:ff9d1e86ad5f 4324
sPymbed 17:ff9d1e86ad5f 4325 ssl->options.serverState = SERVER_ENCRYPTED_EXTENSIONS_COMPLETE;
sPymbed 17:ff9d1e86ad5f 4326
sPymbed 17:ff9d1e86ad5f 4327 if (!ssl->options.groupMessages)
sPymbed 17:ff9d1e86ad5f 4328 ret = SendBuffered(ssl);
sPymbed 17:ff9d1e86ad5f 4329
sPymbed 17:ff9d1e86ad5f 4330 WOLFSSL_LEAVE("SendTls13EncryptedExtensions", ret);
sPymbed 17:ff9d1e86ad5f 4331 WOLFSSL_END(WC_FUNC_ENCRYPTED_EXTENSIONS_SEND);
sPymbed 17:ff9d1e86ad5f 4332
sPymbed 17:ff9d1e86ad5f 4333 return ret;
sPymbed 17:ff9d1e86ad5f 4334 }
sPymbed 17:ff9d1e86ad5f 4335
sPymbed 17:ff9d1e86ad5f 4336 #ifndef NO_CERTS
sPymbed 17:ff9d1e86ad5f 4337 /* handle generation TLS v1.3 certificate_request (13) */
sPymbed 17:ff9d1e86ad5f 4338 /* Send the TLS v1.3 CertificateRequest message.
sPymbed 17:ff9d1e86ad5f 4339 * This message is always encrypted in TLS v1.3.
sPymbed 17:ff9d1e86ad5f 4340 * Only a server will send this message.
sPymbed 17:ff9d1e86ad5f 4341 *
sPymbed 17:ff9d1e86ad5f 4342 * ssl SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 4343 * reqCtx Request context.
sPymbed 17:ff9d1e86ad5f 4344 * reqCtxLen Length of context. 0 when sending as part of handshake.
sPymbed 17:ff9d1e86ad5f 4345 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 4346 */
sPymbed 17:ff9d1e86ad5f 4347 static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
sPymbed 17:ff9d1e86ad5f 4348 int reqCtxLen)
sPymbed 17:ff9d1e86ad5f 4349 {
sPymbed 17:ff9d1e86ad5f 4350 byte* output;
sPymbed 17:ff9d1e86ad5f 4351 int ret;
sPymbed 17:ff9d1e86ad5f 4352 int sendSz;
sPymbed 17:ff9d1e86ad5f 4353 word32 i;
sPymbed 17:ff9d1e86ad5f 4354 word16 reqSz;
sPymbed 17:ff9d1e86ad5f 4355 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 4356 TLSX* ext;
sPymbed 17:ff9d1e86ad5f 4357 #endif
sPymbed 17:ff9d1e86ad5f 4358
sPymbed 17:ff9d1e86ad5f 4359 WOLFSSL_START(WC_FUNC_CERTIFICATE_REQUEST_SEND);
sPymbed 17:ff9d1e86ad5f 4360 WOLFSSL_ENTER("SendTls13CertificateRequest");
sPymbed 17:ff9d1e86ad5f 4361
sPymbed 17:ff9d1e86ad5f 4362 if (ssl->options.side == WOLFSSL_SERVER_END)
sPymbed 17:ff9d1e86ad5f 4363 InitSuitesHashSigAlgo(ssl->suites, 1, 1, 0, 1, ssl->buffers.keySz);
sPymbed 17:ff9d1e86ad5f 4364
sPymbed 17:ff9d1e86ad5f 4365 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 4366 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4367 reqSz = OPAQUE8_LEN + reqCtxLen + REQ_HEADER_SZ + REQ_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4368 reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz;
sPymbed 17:ff9d1e86ad5f 4369
sPymbed 17:ff9d1e86ad5f 4370 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
sPymbed 17:ff9d1e86ad5f 4371 /* Always encrypted and make room for padding. */
sPymbed 17:ff9d1e86ad5f 4372 sendSz += MAX_MSG_EXTRA;
sPymbed 17:ff9d1e86ad5f 4373
sPymbed 17:ff9d1e86ad5f 4374 /* Check buffers are big enough and grow if needed. */
sPymbed 17:ff9d1e86ad5f 4375 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
sPymbed 17:ff9d1e86ad5f 4376 return ret;
sPymbed 17:ff9d1e86ad5f 4377
sPymbed 17:ff9d1e86ad5f 4378 /* Get position in output buffer to write new message to. */
sPymbed 17:ff9d1e86ad5f 4379 output = ssl->buffers.outputBuffer.buffer +
sPymbed 17:ff9d1e86ad5f 4380 ssl->buffers.outputBuffer.length;
sPymbed 17:ff9d1e86ad5f 4381
sPymbed 17:ff9d1e86ad5f 4382 /* Put the record and handshake headers on. */
sPymbed 17:ff9d1e86ad5f 4383 AddTls13Headers(output, reqSz, certificate_request, ssl);
sPymbed 17:ff9d1e86ad5f 4384
sPymbed 17:ff9d1e86ad5f 4385 /* Certificate request context. */
sPymbed 17:ff9d1e86ad5f 4386 output[i++] = reqCtxLen;
sPymbed 17:ff9d1e86ad5f 4387 if (reqCtxLen != 0) {
sPymbed 17:ff9d1e86ad5f 4388 XMEMCPY(output + i, reqCtx, reqCtxLen);
sPymbed 17:ff9d1e86ad5f 4389 i += reqCtxLen;
sPymbed 17:ff9d1e86ad5f 4390 }
sPymbed 17:ff9d1e86ad5f 4391
sPymbed 17:ff9d1e86ad5f 4392 /* supported hash/sig */
sPymbed 17:ff9d1e86ad5f 4393 c16toa(ssl->suites->hashSigAlgoSz, &output[i]);
sPymbed 17:ff9d1e86ad5f 4394 i += LENGTH_SZ;
sPymbed 17:ff9d1e86ad5f 4395
sPymbed 17:ff9d1e86ad5f 4396 XMEMCPY(&output[i], ssl->suites->hashSigAlgo, ssl->suites->hashSigAlgoSz);
sPymbed 17:ff9d1e86ad5f 4397 i += ssl->suites->hashSigAlgoSz;
sPymbed 17:ff9d1e86ad5f 4398
sPymbed 17:ff9d1e86ad5f 4399 /* Certificate authorities not supported yet - empty buffer. */
sPymbed 17:ff9d1e86ad5f 4400 c16toa(0, &output[i]);
sPymbed 17:ff9d1e86ad5f 4401 i += REQ_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4402
sPymbed 17:ff9d1e86ad5f 4403 /* Certificate extensions. */
sPymbed 17:ff9d1e86ad5f 4404 c16toa(0, &output[i]); /* auth's */
sPymbed 17:ff9d1e86ad5f 4405 i += REQ_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4406 #else
sPymbed 17:ff9d1e86ad5f 4407 ext = TLSX_Find(ssl->extensions, TLSX_SIGNATURE_ALGORITHMS);
sPymbed 17:ff9d1e86ad5f 4408 if (ext == NULL)
sPymbed 17:ff9d1e86ad5f 4409 return EXT_MISSING;
sPymbed 17:ff9d1e86ad5f 4410 ext->resp = 0;
sPymbed 17:ff9d1e86ad5f 4411
sPymbed 17:ff9d1e86ad5f 4412 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4413 reqSz = (word16)(OPAQUE8_LEN + reqCtxLen);
sPymbed 17:ff9d1e86ad5f 4414 ret = TLSX_GetRequestSize(ssl, certificate_request, &reqSz);
sPymbed 17:ff9d1e86ad5f 4415 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 4416 return ret;
sPymbed 17:ff9d1e86ad5f 4417
sPymbed 17:ff9d1e86ad5f 4418 sendSz = i + reqSz;
sPymbed 17:ff9d1e86ad5f 4419 /* Always encrypted and make room for padding. */
sPymbed 17:ff9d1e86ad5f 4420 sendSz += MAX_MSG_EXTRA;
sPymbed 17:ff9d1e86ad5f 4421
sPymbed 17:ff9d1e86ad5f 4422 /* Check buffers are big enough and grow if needed. */
sPymbed 17:ff9d1e86ad5f 4423 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
sPymbed 17:ff9d1e86ad5f 4424 return ret;
sPymbed 17:ff9d1e86ad5f 4425
sPymbed 17:ff9d1e86ad5f 4426 /* Get position in output buffer to write new message to. */
sPymbed 17:ff9d1e86ad5f 4427 output = ssl->buffers.outputBuffer.buffer +
sPymbed 17:ff9d1e86ad5f 4428 ssl->buffers.outputBuffer.length;
sPymbed 17:ff9d1e86ad5f 4429
sPymbed 17:ff9d1e86ad5f 4430 /* Put the record and handshake headers on. */
sPymbed 17:ff9d1e86ad5f 4431 AddTls13Headers(output, reqSz, certificate_request, ssl);
sPymbed 17:ff9d1e86ad5f 4432
sPymbed 17:ff9d1e86ad5f 4433 /* Certificate request context. */
sPymbed 17:ff9d1e86ad5f 4434 output[i++] = (byte)reqCtxLen;
sPymbed 17:ff9d1e86ad5f 4435 if (reqCtxLen != 0) {
sPymbed 17:ff9d1e86ad5f 4436 XMEMCPY(output + i, reqCtx, reqCtxLen);
sPymbed 17:ff9d1e86ad5f 4437 i += reqCtxLen;
sPymbed 17:ff9d1e86ad5f 4438 }
sPymbed 17:ff9d1e86ad5f 4439
sPymbed 17:ff9d1e86ad5f 4440 /* Certificate extensions. */
sPymbed 17:ff9d1e86ad5f 4441 reqSz = 0;
sPymbed 17:ff9d1e86ad5f 4442 ret = TLSX_WriteRequest(ssl, output + i, certificate_request, &reqSz);
sPymbed 17:ff9d1e86ad5f 4443 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 4444 return ret;
sPymbed 17:ff9d1e86ad5f 4445 i += reqSz;
sPymbed 17:ff9d1e86ad5f 4446 #endif
sPymbed 17:ff9d1e86ad5f 4447
sPymbed 17:ff9d1e86ad5f 4448 /* Always encrypted. */
sPymbed 17:ff9d1e86ad5f 4449 sendSz = BuildTls13Message(ssl, output, sendSz, output + RECORD_HEADER_SZ,
sPymbed 17:ff9d1e86ad5f 4450 i - RECORD_HEADER_SZ, handshake, 1, 0, 0);
sPymbed 17:ff9d1e86ad5f 4451 if (sendSz < 0)
sPymbed 17:ff9d1e86ad5f 4452 return sendSz;
sPymbed 17:ff9d1e86ad5f 4453
sPymbed 17:ff9d1e86ad5f 4454 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 4455 if (ssl->hsInfoOn)
sPymbed 17:ff9d1e86ad5f 4456 AddPacketName(ssl, "CertificateRequest");
sPymbed 17:ff9d1e86ad5f 4457 if (ssl->toInfoOn) {
sPymbed 17:ff9d1e86ad5f 4458 AddPacketInfo(ssl, "CertificateRequest", handshake, output,
sPymbed 17:ff9d1e86ad5f 4459 sendSz, WRITE_PROTO, ssl->heap);
sPymbed 17:ff9d1e86ad5f 4460 }
sPymbed 17:ff9d1e86ad5f 4461 #endif
sPymbed 17:ff9d1e86ad5f 4462
sPymbed 17:ff9d1e86ad5f 4463 ssl->buffers.outputBuffer.length += sendSz;
sPymbed 17:ff9d1e86ad5f 4464 if (!ssl->options.groupMessages)
sPymbed 17:ff9d1e86ad5f 4465 ret = SendBuffered(ssl);
sPymbed 17:ff9d1e86ad5f 4466
sPymbed 17:ff9d1e86ad5f 4467 WOLFSSL_LEAVE("SendTls13CertificateRequest", ret);
sPymbed 17:ff9d1e86ad5f 4468 WOLFSSL_END(WC_FUNC_CERTIFICATE_REQUEST_SEND);
sPymbed 17:ff9d1e86ad5f 4469
sPymbed 17:ff9d1e86ad5f 4470 return ret;
sPymbed 17:ff9d1e86ad5f 4471 }
sPymbed 17:ff9d1e86ad5f 4472 #endif /* NO_CERTS */
sPymbed 17:ff9d1e86ad5f 4473 #endif /* NO_WOLFSSL_SERVER */
sPymbed 17:ff9d1e86ad5f 4474
sPymbed 17:ff9d1e86ad5f 4475 #ifndef NO_CERTS
sPymbed 17:ff9d1e86ad5f 4476 #if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)
sPymbed 17:ff9d1e86ad5f 4477 /* Encode the signature algorithm into buffer.
sPymbed 17:ff9d1e86ad5f 4478 *
sPymbed 17:ff9d1e86ad5f 4479 * hashalgo The hash algorithm.
sPymbed 17:ff9d1e86ad5f 4480 * hsType The signature type.
sPymbed 17:ff9d1e86ad5f 4481 * output The buffer to encode into.
sPymbed 17:ff9d1e86ad5f 4482 */
sPymbed 17:ff9d1e86ad5f 4483 static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
sPymbed 17:ff9d1e86ad5f 4484 {
sPymbed 17:ff9d1e86ad5f 4485 switch (hsType) {
sPymbed 17:ff9d1e86ad5f 4486 #ifdef HAVE_ECC
sPymbed 17:ff9d1e86ad5f 4487 case ecc_dsa_sa_algo:
sPymbed 17:ff9d1e86ad5f 4488 output[0] = hashAlgo;
sPymbed 17:ff9d1e86ad5f 4489 output[1] = ecc_dsa_sa_algo;
sPymbed 17:ff9d1e86ad5f 4490 break;
sPymbed 17:ff9d1e86ad5f 4491 #endif
sPymbed 17:ff9d1e86ad5f 4492 #ifdef HAVE_ED25519
sPymbed 17:ff9d1e86ad5f 4493 /* ED25519: 0x0807 */
sPymbed 17:ff9d1e86ad5f 4494 case ed25519_sa_algo:
sPymbed 17:ff9d1e86ad5f 4495 output[0] = ED25519_SA_MAJOR;
sPymbed 17:ff9d1e86ad5f 4496 output[1] = ED25519_SA_MINOR;
sPymbed 17:ff9d1e86ad5f 4497 (void)hashAlgo;
sPymbed 17:ff9d1e86ad5f 4498 break;
sPymbed 17:ff9d1e86ad5f 4499 #endif
sPymbed 17:ff9d1e86ad5f 4500 #ifndef NO_RSA
sPymbed 17:ff9d1e86ad5f 4501 /* PSS signatures: 0x080[4-6] */
sPymbed 17:ff9d1e86ad5f 4502 case rsa_pss_sa_algo:
sPymbed 17:ff9d1e86ad5f 4503 output[0] = rsa_pss_sa_algo;
sPymbed 17:ff9d1e86ad5f 4504 output[1] = hashAlgo;
sPymbed 17:ff9d1e86ad5f 4505 break;
sPymbed 17:ff9d1e86ad5f 4506 #endif
sPymbed 17:ff9d1e86ad5f 4507 /* ED448: 0x0808 */
sPymbed 17:ff9d1e86ad5f 4508 }
sPymbed 17:ff9d1e86ad5f 4509 }
sPymbed 17:ff9d1e86ad5f 4510
sPymbed 17:ff9d1e86ad5f 4511 /* Decode the signature algorithm.
sPymbed 17:ff9d1e86ad5f 4512 *
sPymbed 17:ff9d1e86ad5f 4513 * input The encoded signature algorithm.
sPymbed 17:ff9d1e86ad5f 4514 * hashalgo The hash algorithm.
sPymbed 17:ff9d1e86ad5f 4515 * hsType The signature type.
sPymbed 17:ff9d1e86ad5f 4516 */
sPymbed 17:ff9d1e86ad5f 4517 static WC_INLINE void DecodeSigAlg(byte* input, byte* hashAlgo, byte* hsType)
sPymbed 17:ff9d1e86ad5f 4518 {
sPymbed 17:ff9d1e86ad5f 4519 switch (input[0]) {
sPymbed 17:ff9d1e86ad5f 4520 case NEW_SA_MAJOR:
sPymbed 17:ff9d1e86ad5f 4521 /* PSS signatures: 0x080[4-6] */
sPymbed 17:ff9d1e86ad5f 4522 if (input[1] <= sha512_mac) {
sPymbed 17:ff9d1e86ad5f 4523 *hsType = input[0];
sPymbed 17:ff9d1e86ad5f 4524 *hashAlgo = input[1];
sPymbed 17:ff9d1e86ad5f 4525 }
sPymbed 17:ff9d1e86ad5f 4526 #ifdef HAVE_ED25519
sPymbed 17:ff9d1e86ad5f 4527 /* ED25519: 0x0807 */
sPymbed 17:ff9d1e86ad5f 4528 if (input[1] == ED25519_SA_MINOR) {
sPymbed 17:ff9d1e86ad5f 4529 *hsType = ed25519_sa_algo;
sPymbed 17:ff9d1e86ad5f 4530 /* Hash performed as part of sign/verify operation. */
sPymbed 17:ff9d1e86ad5f 4531 *hashAlgo = sha512_mac;
sPymbed 17:ff9d1e86ad5f 4532 }
sPymbed 17:ff9d1e86ad5f 4533 #endif
sPymbed 17:ff9d1e86ad5f 4534 /* ED448: 0x0808 */
sPymbed 17:ff9d1e86ad5f 4535 break;
sPymbed 17:ff9d1e86ad5f 4536 default:
sPymbed 17:ff9d1e86ad5f 4537 *hashAlgo = input[0];
sPymbed 17:ff9d1e86ad5f 4538 *hsType = input[1];
sPymbed 17:ff9d1e86ad5f 4539 break;
sPymbed 17:ff9d1e86ad5f 4540 }
sPymbed 17:ff9d1e86ad5f 4541 }
sPymbed 17:ff9d1e86ad5f 4542
sPymbed 17:ff9d1e86ad5f 4543 /* Get the hash of the messages so far.
sPymbed 17:ff9d1e86ad5f 4544 *
sPymbed 17:ff9d1e86ad5f 4545 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 4546 * hash The buffer to write the hash to.
sPymbed 17:ff9d1e86ad5f 4547 * returns the length of the hash.
sPymbed 17:ff9d1e86ad5f 4548 */
sPymbed 17:ff9d1e86ad5f 4549 static WC_INLINE int GetMsgHash(WOLFSSL* ssl, byte* hash)
sPymbed 17:ff9d1e86ad5f 4550 {
sPymbed 17:ff9d1e86ad5f 4551 int ret = 0;
sPymbed 17:ff9d1e86ad5f 4552 switch (ssl->specs.mac_algorithm) {
sPymbed 17:ff9d1e86ad5f 4553 #ifndef NO_SHA256
sPymbed 17:ff9d1e86ad5f 4554 case sha256_mac:
sPymbed 17:ff9d1e86ad5f 4555 ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash);
sPymbed 17:ff9d1e86ad5f 4556 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 4557 ret = WC_SHA256_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 4558 break;
sPymbed 17:ff9d1e86ad5f 4559 #endif /* !NO_SHA256 */
sPymbed 17:ff9d1e86ad5f 4560 #ifdef WOLFSSL_SHA384
sPymbed 17:ff9d1e86ad5f 4561 case sha384_mac:
sPymbed 17:ff9d1e86ad5f 4562 ret = wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash);
sPymbed 17:ff9d1e86ad5f 4563 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 4564 ret = WC_SHA384_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 4565 break;
sPymbed 17:ff9d1e86ad5f 4566 #endif /* WOLFSSL_SHA384 */
sPymbed 17:ff9d1e86ad5f 4567 #ifdef WOLFSSL_TLS13_SHA512
sPymbed 17:ff9d1e86ad5f 4568 case sha512_mac:
sPymbed 17:ff9d1e86ad5f 4569 ret = wc_Sha512GetHash(&ssl->hsHashes->hashSha512, hash);
sPymbed 17:ff9d1e86ad5f 4570 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 4571 ret = WC_SHA512_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 4572 break;
sPymbed 17:ff9d1e86ad5f 4573 #endif /* WOLFSSL_TLS13_SHA512 */
sPymbed 17:ff9d1e86ad5f 4574 }
sPymbed 17:ff9d1e86ad5f 4575 return ret;
sPymbed 17:ff9d1e86ad5f 4576 }
sPymbed 17:ff9d1e86ad5f 4577
sPymbed 17:ff9d1e86ad5f 4578 /* The length of the certificate verification label - client and server. */
sPymbed 17:ff9d1e86ad5f 4579 #define CERT_VFY_LABEL_SZ 34
sPymbed 17:ff9d1e86ad5f 4580 /* The server certificate verification label. */
sPymbed 17:ff9d1e86ad5f 4581 static const byte serverCertVfyLabel[CERT_VFY_LABEL_SZ] =
sPymbed 17:ff9d1e86ad5f 4582 "TLS 1.3, server CertificateVerify";
sPymbed 17:ff9d1e86ad5f 4583 /* The client certificate verification label. */
sPymbed 17:ff9d1e86ad5f 4584 static const byte clientCertVfyLabel[CERT_VFY_LABEL_SZ] =
sPymbed 17:ff9d1e86ad5f 4585 "TLS 1.3, client CertificateVerify";
sPymbed 17:ff9d1e86ad5f 4586
sPymbed 17:ff9d1e86ad5f 4587 /* The number of prefix bytes for signature data. */
sPymbed 17:ff9d1e86ad5f 4588 #define SIGNING_DATA_PREFIX_SZ 64
sPymbed 17:ff9d1e86ad5f 4589 /* The prefix byte in the signature data. */
sPymbed 17:ff9d1e86ad5f 4590 #define SIGNING_DATA_PREFIX_BYTE 0x20
sPymbed 17:ff9d1e86ad5f 4591 /* Maximum length of the signature data. */
sPymbed 17:ff9d1e86ad5f 4592 #define MAX_SIG_DATA_SZ (SIGNING_DATA_PREFIX_SZ + \
sPymbed 17:ff9d1e86ad5f 4593 CERT_VFY_LABEL_SZ + \
sPymbed 17:ff9d1e86ad5f 4594 WC_MAX_DIGEST_SIZE)
sPymbed 17:ff9d1e86ad5f 4595
sPymbed 17:ff9d1e86ad5f 4596 /* Create the signature data for TLS v1.3 certificate verification.
sPymbed 17:ff9d1e86ad5f 4597 *
sPymbed 17:ff9d1e86ad5f 4598 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 4599 * sigData The signature data.
sPymbed 17:ff9d1e86ad5f 4600 * sigDataSz The length of the signature data.
sPymbed 17:ff9d1e86ad5f 4601 * check Indicates this is a check not create.
sPymbed 17:ff9d1e86ad5f 4602 */
sPymbed 17:ff9d1e86ad5f 4603 static int CreateSigData(WOLFSSL* ssl, byte* sigData, word16* sigDataSz,
sPymbed 17:ff9d1e86ad5f 4604 int check)
sPymbed 17:ff9d1e86ad5f 4605 {
sPymbed 17:ff9d1e86ad5f 4606 word16 idx;
sPymbed 17:ff9d1e86ad5f 4607 int side = ssl->options.side;
sPymbed 17:ff9d1e86ad5f 4608 int ret;
sPymbed 17:ff9d1e86ad5f 4609
sPymbed 17:ff9d1e86ad5f 4610 /* Signature Data = Prefix | Label | Handshake Hash */
sPymbed 17:ff9d1e86ad5f 4611 XMEMSET(sigData, SIGNING_DATA_PREFIX_BYTE, SIGNING_DATA_PREFIX_SZ);
sPymbed 17:ff9d1e86ad5f 4612 idx = SIGNING_DATA_PREFIX_SZ;
sPymbed 17:ff9d1e86ad5f 4613
sPymbed 17:ff9d1e86ad5f 4614 if ((side == WOLFSSL_SERVER_END && check) ||
sPymbed 17:ff9d1e86ad5f 4615 (side == WOLFSSL_CLIENT_END && !check)) {
sPymbed 17:ff9d1e86ad5f 4616 XMEMCPY(&sigData[idx], clientCertVfyLabel, CERT_VFY_LABEL_SZ);
sPymbed 17:ff9d1e86ad5f 4617 }
sPymbed 17:ff9d1e86ad5f 4618 if ((side == WOLFSSL_CLIENT_END && check) ||
sPymbed 17:ff9d1e86ad5f 4619 (side == WOLFSSL_SERVER_END && !check)) {
sPymbed 17:ff9d1e86ad5f 4620 XMEMCPY(&sigData[idx], serverCertVfyLabel, CERT_VFY_LABEL_SZ);
sPymbed 17:ff9d1e86ad5f 4621 }
sPymbed 17:ff9d1e86ad5f 4622 idx += CERT_VFY_LABEL_SZ;
sPymbed 17:ff9d1e86ad5f 4623
sPymbed 17:ff9d1e86ad5f 4624 ret = GetMsgHash(ssl, &sigData[idx]);
sPymbed 17:ff9d1e86ad5f 4625 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 4626 return ret;
sPymbed 17:ff9d1e86ad5f 4627
sPymbed 17:ff9d1e86ad5f 4628 *sigDataSz = (word16)(idx + ret);
sPymbed 17:ff9d1e86ad5f 4629 ret = 0;
sPymbed 17:ff9d1e86ad5f 4630
sPymbed 17:ff9d1e86ad5f 4631 return ret;
sPymbed 17:ff9d1e86ad5f 4632 }
sPymbed 17:ff9d1e86ad5f 4633
sPymbed 17:ff9d1e86ad5f 4634 #ifndef NO_RSA
sPymbed 17:ff9d1e86ad5f 4635 /* Encode the PKCS #1.5 RSA signature.
sPymbed 17:ff9d1e86ad5f 4636 *
sPymbed 17:ff9d1e86ad5f 4637 * sig The buffer to place the encoded signature into.
sPymbed 17:ff9d1e86ad5f 4638 * sigData The data to be signed.
sPymbed 17:ff9d1e86ad5f 4639 * sigDataSz The size of the data to be signed.
sPymbed 17:ff9d1e86ad5f 4640 * hashAlgo The hash algorithm to use when signing.
sPymbed 17:ff9d1e86ad5f 4641 * returns the length of the encoded signature or negative on error.
sPymbed 17:ff9d1e86ad5f 4642 */
sPymbed 17:ff9d1e86ad5f 4643 static int CreateRSAEncodedSig(byte* sig, byte* sigData, int sigDataSz,
sPymbed 17:ff9d1e86ad5f 4644 int sigAlgo, int hashAlgo)
sPymbed 17:ff9d1e86ad5f 4645 {
sPymbed 17:ff9d1e86ad5f 4646 Digest digest;
sPymbed 17:ff9d1e86ad5f 4647 int hashSz = 0;
sPymbed 17:ff9d1e86ad5f 4648 int ret = BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 4649 byte* hash;
sPymbed 17:ff9d1e86ad5f 4650
sPymbed 17:ff9d1e86ad5f 4651 (void)sigAlgo;
sPymbed 17:ff9d1e86ad5f 4652
sPymbed 17:ff9d1e86ad5f 4653 hash = sig;
sPymbed 17:ff9d1e86ad5f 4654
sPymbed 17:ff9d1e86ad5f 4655 /* Digest the signature data. */
sPymbed 17:ff9d1e86ad5f 4656 switch (hashAlgo) {
sPymbed 17:ff9d1e86ad5f 4657 #ifndef NO_WOLFSSL_SHA256
sPymbed 17:ff9d1e86ad5f 4658 case sha256_mac:
sPymbed 17:ff9d1e86ad5f 4659 ret = wc_InitSha256(&digest.sha256);
sPymbed 17:ff9d1e86ad5f 4660 if (ret == 0) {
sPymbed 17:ff9d1e86ad5f 4661 ret = wc_Sha256Update(&digest.sha256, sigData, sigDataSz);
sPymbed 17:ff9d1e86ad5f 4662 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 4663 ret = wc_Sha256Final(&digest.sha256, hash);
sPymbed 17:ff9d1e86ad5f 4664 wc_Sha256Free(&digest.sha256);
sPymbed 17:ff9d1e86ad5f 4665 }
sPymbed 17:ff9d1e86ad5f 4666 hashSz = WC_SHA256_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 4667 break;
sPymbed 17:ff9d1e86ad5f 4668 #endif
sPymbed 17:ff9d1e86ad5f 4669 #ifdef WOLFSSL_SHA384
sPymbed 17:ff9d1e86ad5f 4670 case sha384_mac:
sPymbed 17:ff9d1e86ad5f 4671 ret = wc_InitSha384(&digest.sha384);
sPymbed 17:ff9d1e86ad5f 4672 if (ret == 0) {
sPymbed 17:ff9d1e86ad5f 4673 ret = wc_Sha384Update(&digest.sha384, sigData, sigDataSz);
sPymbed 17:ff9d1e86ad5f 4674 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 4675 ret = wc_Sha384Final(&digest.sha384, hash);
sPymbed 17:ff9d1e86ad5f 4676 wc_Sha384Free(&digest.sha384);
sPymbed 17:ff9d1e86ad5f 4677 }
sPymbed 17:ff9d1e86ad5f 4678 hashSz = WC_SHA384_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 4679 break;
sPymbed 17:ff9d1e86ad5f 4680 #endif
sPymbed 17:ff9d1e86ad5f 4681 #ifdef WOLFSSL_SHA512
sPymbed 17:ff9d1e86ad5f 4682 case sha512_mac:
sPymbed 17:ff9d1e86ad5f 4683 ret = wc_InitSha512(&digest.sha512);
sPymbed 17:ff9d1e86ad5f 4684 if (ret == 0) {
sPymbed 17:ff9d1e86ad5f 4685 ret = wc_Sha512Update(&digest.sha512, sigData, sigDataSz);
sPymbed 17:ff9d1e86ad5f 4686 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 4687 ret = wc_Sha512Final(&digest.sha512, hash);
sPymbed 17:ff9d1e86ad5f 4688 wc_Sha512Free(&digest.sha512);
sPymbed 17:ff9d1e86ad5f 4689 }
sPymbed 17:ff9d1e86ad5f 4690 hashSz = WC_SHA512_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 4691 break;
sPymbed 17:ff9d1e86ad5f 4692 #endif
sPymbed 17:ff9d1e86ad5f 4693 }
sPymbed 17:ff9d1e86ad5f 4694
sPymbed 17:ff9d1e86ad5f 4695 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 4696 return ret;
sPymbed 17:ff9d1e86ad5f 4697
sPymbed 17:ff9d1e86ad5f 4698 return hashSz;
sPymbed 17:ff9d1e86ad5f 4699 }
sPymbed 17:ff9d1e86ad5f 4700 #endif /* !NO_RSA */
sPymbed 17:ff9d1e86ad5f 4701
sPymbed 17:ff9d1e86ad5f 4702 #ifdef HAVE_ECC
sPymbed 17:ff9d1e86ad5f 4703 /* Encode the ECC signature.
sPymbed 17:ff9d1e86ad5f 4704 *
sPymbed 17:ff9d1e86ad5f 4705 * sigData The data to be signed.
sPymbed 17:ff9d1e86ad5f 4706 * sigDataSz The size of the data to be signed.
sPymbed 17:ff9d1e86ad5f 4707 * hashAlgo The hash algorithm to use when signing.
sPymbed 17:ff9d1e86ad5f 4708 * returns the length of the encoded signature or negative on error.
sPymbed 17:ff9d1e86ad5f 4709 */
sPymbed 17:ff9d1e86ad5f 4710 static int CreateECCEncodedSig(byte* sigData, int sigDataSz, int hashAlgo)
sPymbed 17:ff9d1e86ad5f 4711 {
sPymbed 17:ff9d1e86ad5f 4712 Digest digest;
sPymbed 17:ff9d1e86ad5f 4713 int hashSz = 0;
sPymbed 17:ff9d1e86ad5f 4714 int ret = BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 4715
sPymbed 17:ff9d1e86ad5f 4716 /* Digest the signature data. */
sPymbed 17:ff9d1e86ad5f 4717 switch (hashAlgo) {
sPymbed 17:ff9d1e86ad5f 4718 #ifndef NO_WOLFSSL_SHA256
sPymbed 17:ff9d1e86ad5f 4719 case sha256_mac:
sPymbed 17:ff9d1e86ad5f 4720 ret = wc_InitSha256(&digest.sha256);
sPymbed 17:ff9d1e86ad5f 4721 if (ret == 0) {
sPymbed 17:ff9d1e86ad5f 4722 ret = wc_Sha256Update(&digest.sha256, sigData, sigDataSz);
sPymbed 17:ff9d1e86ad5f 4723 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 4724 ret = wc_Sha256Final(&digest.sha256, sigData);
sPymbed 17:ff9d1e86ad5f 4725 wc_Sha256Free(&digest.sha256);
sPymbed 17:ff9d1e86ad5f 4726 }
sPymbed 17:ff9d1e86ad5f 4727 hashSz = WC_SHA256_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 4728 break;
sPymbed 17:ff9d1e86ad5f 4729 #endif
sPymbed 17:ff9d1e86ad5f 4730 #ifdef WOLFSSL_SHA384
sPymbed 17:ff9d1e86ad5f 4731 case sha384_mac:
sPymbed 17:ff9d1e86ad5f 4732 ret = wc_InitSha384(&digest.sha384);
sPymbed 17:ff9d1e86ad5f 4733 if (ret == 0) {
sPymbed 17:ff9d1e86ad5f 4734 ret = wc_Sha384Update(&digest.sha384, sigData, sigDataSz);
sPymbed 17:ff9d1e86ad5f 4735 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 4736 ret = wc_Sha384Final(&digest.sha384, sigData);
sPymbed 17:ff9d1e86ad5f 4737 wc_Sha384Free(&digest.sha384);
sPymbed 17:ff9d1e86ad5f 4738 }
sPymbed 17:ff9d1e86ad5f 4739 hashSz = WC_SHA384_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 4740 break;
sPymbed 17:ff9d1e86ad5f 4741 #endif
sPymbed 17:ff9d1e86ad5f 4742 #ifdef WOLFSSL_SHA512
sPymbed 17:ff9d1e86ad5f 4743 case sha512_mac:
sPymbed 17:ff9d1e86ad5f 4744 ret = wc_InitSha512(&digest.sha512);
sPymbed 17:ff9d1e86ad5f 4745 if (ret == 0) {
sPymbed 17:ff9d1e86ad5f 4746 ret = wc_Sha512Update(&digest.sha512, sigData, sigDataSz);
sPymbed 17:ff9d1e86ad5f 4747 if (ret == 0)
sPymbed 17:ff9d1e86ad5f 4748 ret = wc_Sha512Final(&digest.sha512, sigData);
sPymbed 17:ff9d1e86ad5f 4749 wc_Sha512Free(&digest.sha512);
sPymbed 17:ff9d1e86ad5f 4750 }
sPymbed 17:ff9d1e86ad5f 4751 hashSz = WC_SHA512_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 4752 break;
sPymbed 17:ff9d1e86ad5f 4753 #endif
sPymbed 17:ff9d1e86ad5f 4754 }
sPymbed 17:ff9d1e86ad5f 4755
sPymbed 17:ff9d1e86ad5f 4756 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 4757 return ret;
sPymbed 17:ff9d1e86ad5f 4758
sPymbed 17:ff9d1e86ad5f 4759 return hashSz;
sPymbed 17:ff9d1e86ad5f 4760 }
sPymbed 17:ff9d1e86ad5f 4761 #endif /* HAVE_ECC */
sPymbed 17:ff9d1e86ad5f 4762
sPymbed 17:ff9d1e86ad5f 4763 #ifndef NO_RSA
sPymbed 17:ff9d1e86ad5f 4764 /* Check that the decrypted signature matches the encoded signature
sPymbed 17:ff9d1e86ad5f 4765 * based on the digest of the signature data.
sPymbed 17:ff9d1e86ad5f 4766 *
sPymbed 17:ff9d1e86ad5f 4767 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 4768 * sigAlgo The signature algorithm used to generate signature.
sPymbed 17:ff9d1e86ad5f 4769 * hashAlgo The hash algorithm used to generate signature.
sPymbed 17:ff9d1e86ad5f 4770 * decSig The decrypted signature.
sPymbed 17:ff9d1e86ad5f 4771 * decSigSz The size of the decrypted signature.
sPymbed 17:ff9d1e86ad5f 4772 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 4773 */
sPymbed 17:ff9d1e86ad5f 4774 static int CheckRSASignature(WOLFSSL* ssl, int sigAlgo, int hashAlgo,
sPymbed 17:ff9d1e86ad5f 4775 byte* decSig, word32 decSigSz)
sPymbed 17:ff9d1e86ad5f 4776 {
sPymbed 17:ff9d1e86ad5f 4777 int ret = 0;
sPymbed 17:ff9d1e86ad5f 4778 byte sigData[MAX_SIG_DATA_SZ];
sPymbed 17:ff9d1e86ad5f 4779 word16 sigDataSz;
sPymbed 17:ff9d1e86ad5f 4780 word32 sigSz;
sPymbed 17:ff9d1e86ad5f 4781
sPymbed 17:ff9d1e86ad5f 4782 ret = CreateSigData(ssl, sigData, &sigDataSz, 1);
sPymbed 17:ff9d1e86ad5f 4783 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 4784 return ret;
sPymbed 17:ff9d1e86ad5f 4785
sPymbed 17:ff9d1e86ad5f 4786 if (sigAlgo == rsa_pss_sa_algo) {
sPymbed 17:ff9d1e86ad5f 4787 enum wc_HashType hashType = WC_HASH_TYPE_NONE;
sPymbed 17:ff9d1e86ad5f 4788
sPymbed 17:ff9d1e86ad5f 4789 ret = ConvertHashPss(hashAlgo, &hashType, NULL);
sPymbed 17:ff9d1e86ad5f 4790 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 4791 return ret;
sPymbed 17:ff9d1e86ad5f 4792
sPymbed 17:ff9d1e86ad5f 4793 /* PSS signature can be done in-place */
sPymbed 17:ff9d1e86ad5f 4794 ret = CreateRSAEncodedSig(sigData, sigData, sigDataSz,
sPymbed 17:ff9d1e86ad5f 4795 sigAlgo, hashAlgo);
sPymbed 17:ff9d1e86ad5f 4796 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 4797 return ret;
sPymbed 17:ff9d1e86ad5f 4798 sigSz = ret;
sPymbed 17:ff9d1e86ad5f 4799
sPymbed 17:ff9d1e86ad5f 4800 ret = wc_RsaPSS_CheckPadding(sigData, sigSz, decSig, decSigSz,
sPymbed 17:ff9d1e86ad5f 4801 hashType);
sPymbed 17:ff9d1e86ad5f 4802 }
sPymbed 17:ff9d1e86ad5f 4803
sPymbed 17:ff9d1e86ad5f 4804 return ret;
sPymbed 17:ff9d1e86ad5f 4805 }
sPymbed 17:ff9d1e86ad5f 4806 #endif /* !NO_RSA */
sPymbed 17:ff9d1e86ad5f 4807 #endif /* !NO_RSA || HAVE_ECC */
sPymbed 17:ff9d1e86ad5f 4808
sPymbed 17:ff9d1e86ad5f 4809 /* Get the next certificate from the list for writing into the TLS v1.3
sPymbed 17:ff9d1e86ad5f 4810 * Certificate message.
sPymbed 17:ff9d1e86ad5f 4811 *
sPymbed 17:ff9d1e86ad5f 4812 * data The certificate list.
sPymbed 17:ff9d1e86ad5f 4813 * length The length of the certificate data in the list.
sPymbed 17:ff9d1e86ad5f 4814 * idx The index of the next certificate.
sPymbed 17:ff9d1e86ad5f 4815 * returns the length of the certificate data. 0 indicates no more certificates
sPymbed 17:ff9d1e86ad5f 4816 * in the list.
sPymbed 17:ff9d1e86ad5f 4817 */
sPymbed 17:ff9d1e86ad5f 4818 static word32 NextCert(byte* data, word32 length, word32* idx)
sPymbed 17:ff9d1e86ad5f 4819 {
sPymbed 17:ff9d1e86ad5f 4820 word32 len;
sPymbed 17:ff9d1e86ad5f 4821
sPymbed 17:ff9d1e86ad5f 4822 /* Is index at end of list. */
sPymbed 17:ff9d1e86ad5f 4823 if (*idx == length)
sPymbed 17:ff9d1e86ad5f 4824 return 0;
sPymbed 17:ff9d1e86ad5f 4825
sPymbed 17:ff9d1e86ad5f 4826 /* Length of the current ASN.1 encoded certificate. */
sPymbed 17:ff9d1e86ad5f 4827 c24to32(data + *idx, &len);
sPymbed 17:ff9d1e86ad5f 4828 /* Include the length field. */
sPymbed 17:ff9d1e86ad5f 4829 len += 3;
sPymbed 17:ff9d1e86ad5f 4830
sPymbed 17:ff9d1e86ad5f 4831 /* Move index to next certificate and return the current certificate's
sPymbed 17:ff9d1e86ad5f 4832 * length.
sPymbed 17:ff9d1e86ad5f 4833 */
sPymbed 17:ff9d1e86ad5f 4834 *idx += len;
sPymbed 17:ff9d1e86ad5f 4835 return len;
sPymbed 17:ff9d1e86ad5f 4836 }
sPymbed 17:ff9d1e86ad5f 4837
sPymbed 17:ff9d1e86ad5f 4838 /* Add certificate data and empty extension to output up to the fragment size.
sPymbed 17:ff9d1e86ad5f 4839 *
sPymbed 17:ff9d1e86ad5f 4840 * ssl SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 4841 * cert The certificate data to write out.
sPymbed 17:ff9d1e86ad5f 4842 * len The length of the certificate data.
sPymbed 17:ff9d1e86ad5f 4843 * extSz Length of the extension data with the certificate.
sPymbed 17:ff9d1e86ad5f 4844 * idx The start of the certificate data to write out.
sPymbed 17:ff9d1e86ad5f 4845 * fragSz The maximum size of this fragment.
sPymbed 17:ff9d1e86ad5f 4846 * output The buffer to write to.
sPymbed 17:ff9d1e86ad5f 4847 * returns the number of bytes written.
sPymbed 17:ff9d1e86ad5f 4848 */
sPymbed 17:ff9d1e86ad5f 4849 static word32 AddCertExt(WOLFSSL* ssl, byte* cert, word32 len, word16 extSz,
sPymbed 17:ff9d1e86ad5f 4850 word32 idx, word32 fragSz, byte* output)
sPymbed 17:ff9d1e86ad5f 4851 {
sPymbed 17:ff9d1e86ad5f 4852 word32 i = 0;
sPymbed 17:ff9d1e86ad5f 4853 word32 copySz = min(len - idx, fragSz);
sPymbed 17:ff9d1e86ad5f 4854
sPymbed 17:ff9d1e86ad5f 4855 if (idx < len) {
sPymbed 17:ff9d1e86ad5f 4856 XMEMCPY(output, cert + idx, copySz);
sPymbed 17:ff9d1e86ad5f 4857 i = copySz;
sPymbed 17:ff9d1e86ad5f 4858 if (copySz == fragSz)
sPymbed 17:ff9d1e86ad5f 4859 return i;
sPymbed 17:ff9d1e86ad5f 4860 }
sPymbed 17:ff9d1e86ad5f 4861 copySz = len + extSz - idx - i;
sPymbed 17:ff9d1e86ad5f 4862
sPymbed 17:ff9d1e86ad5f 4863 if (extSz == OPAQUE16_LEN) {
sPymbed 17:ff9d1e86ad5f 4864 if (copySz <= fragSz) {
sPymbed 17:ff9d1e86ad5f 4865 /* Empty extension */
sPymbed 17:ff9d1e86ad5f 4866 output[i++] = 0;
sPymbed 17:ff9d1e86ad5f 4867 output[i++] = 0;
sPymbed 17:ff9d1e86ad5f 4868 }
sPymbed 17:ff9d1e86ad5f 4869 }
sPymbed 17:ff9d1e86ad5f 4870 else {
sPymbed 17:ff9d1e86ad5f 4871 byte* certExts = ssl->buffers.certExts->buffer + idx + i - len;
sPymbed 17:ff9d1e86ad5f 4872 /* Put out as much of the extensions' data as will fit in fragment. */
sPymbed 17:ff9d1e86ad5f 4873 if (copySz > fragSz - i)
sPymbed 17:ff9d1e86ad5f 4874 copySz = fragSz - i;
sPymbed 17:ff9d1e86ad5f 4875 XMEMCPY(output + i, certExts, copySz);
sPymbed 17:ff9d1e86ad5f 4876 i += copySz;
sPymbed 17:ff9d1e86ad5f 4877 }
sPymbed 17:ff9d1e86ad5f 4878
sPymbed 17:ff9d1e86ad5f 4879 return i;
sPymbed 17:ff9d1e86ad5f 4880 }
sPymbed 17:ff9d1e86ad5f 4881
sPymbed 17:ff9d1e86ad5f 4882 /* handle generation TLS v1.3 certificate (11) */
sPymbed 17:ff9d1e86ad5f 4883 /* Send the certificate for this end and any CAs that help with validation.
sPymbed 17:ff9d1e86ad5f 4884 * This message is always encrypted in TLS v1.3.
sPymbed 17:ff9d1e86ad5f 4885 *
sPymbed 17:ff9d1e86ad5f 4886 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 4887 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 4888 */
sPymbed 17:ff9d1e86ad5f 4889 static int SendTls13Certificate(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 4890 {
sPymbed 17:ff9d1e86ad5f 4891 int ret = 0;
sPymbed 17:ff9d1e86ad5f 4892 word32 certSz, certChainSz, headerSz, listSz, payloadSz;
sPymbed 17:ff9d1e86ad5f 4893 word16 extSz = 0;
sPymbed 17:ff9d1e86ad5f 4894 word32 length, maxFragment;
sPymbed 17:ff9d1e86ad5f 4895 word32 len = 0;
sPymbed 17:ff9d1e86ad5f 4896 word32 idx = 0;
sPymbed 17:ff9d1e86ad5f 4897 word32 offset = OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 4898 byte* p = NULL;
sPymbed 17:ff9d1e86ad5f 4899 byte certReqCtxLen = 0;
sPymbed 17:ff9d1e86ad5f 4900 byte* certReqCtx = NULL;
sPymbed 17:ff9d1e86ad5f 4901
sPymbed 17:ff9d1e86ad5f 4902 WOLFSSL_START(WC_FUNC_CERTIFICATE_SEND);
sPymbed 17:ff9d1e86ad5f 4903 WOLFSSL_ENTER("SendTls13Certificate");
sPymbed 17:ff9d1e86ad5f 4904
sPymbed 17:ff9d1e86ad5f 4905 #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
sPymbed 17:ff9d1e86ad5f 4906 if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->certReqCtx != NULL) {
sPymbed 17:ff9d1e86ad5f 4907 certReqCtxLen = ssl->certReqCtx->len;
sPymbed 17:ff9d1e86ad5f 4908 certReqCtx = &ssl->certReqCtx->ctx;
sPymbed 17:ff9d1e86ad5f 4909 }
sPymbed 17:ff9d1e86ad5f 4910 #endif
sPymbed 17:ff9d1e86ad5f 4911
sPymbed 17:ff9d1e86ad5f 4912 if (ssl->options.sendVerify == SEND_BLANK_CERT) {
sPymbed 17:ff9d1e86ad5f 4913 certSz = 0;
sPymbed 17:ff9d1e86ad5f 4914 certChainSz = 0;
sPymbed 17:ff9d1e86ad5f 4915 headerSz = OPAQUE8_LEN + certReqCtxLen + CERT_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4916 length = headerSz;
sPymbed 17:ff9d1e86ad5f 4917 listSz = 0;
sPymbed 17:ff9d1e86ad5f 4918 }
sPymbed 17:ff9d1e86ad5f 4919 else {
sPymbed 17:ff9d1e86ad5f 4920 if (!ssl->buffers.certificate) {
sPymbed 17:ff9d1e86ad5f 4921 WOLFSSL_MSG("Send Cert missing certificate buffer");
sPymbed 17:ff9d1e86ad5f 4922 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 4923 }
sPymbed 17:ff9d1e86ad5f 4924 /* Certificate Data */
sPymbed 17:ff9d1e86ad5f 4925 certSz = ssl->buffers.certificate->length;
sPymbed 17:ff9d1e86ad5f 4926 /* Cert Req Ctx Len | Cert Req Ctx | Cert List Len | Cert Data Len */
sPymbed 17:ff9d1e86ad5f 4927 headerSz = OPAQUE8_LEN + certReqCtxLen + CERT_HEADER_SZ +
sPymbed 17:ff9d1e86ad5f 4928 CERT_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4929
sPymbed 17:ff9d1e86ad5f 4930 ret = TLSX_GetResponseSize(ssl, certificate, &extSz);
sPymbed 17:ff9d1e86ad5f 4931 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 4932 return ret;
sPymbed 17:ff9d1e86ad5f 4933
sPymbed 17:ff9d1e86ad5f 4934 /* Create extensions' data if none already present. */
sPymbed 17:ff9d1e86ad5f 4935 if (extSz > OPAQUE16_LEN && ssl->buffers.certExts == NULL) {
sPymbed 17:ff9d1e86ad5f 4936 ret = AllocDer(&ssl->buffers.certExts, extSz, CERT_TYPE, ssl->heap);
sPymbed 17:ff9d1e86ad5f 4937 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 4938 return ret;
sPymbed 17:ff9d1e86ad5f 4939
sPymbed 17:ff9d1e86ad5f 4940 ret = TLSX_WriteResponse(ssl, ssl->buffers.certExts->buffer,
sPymbed 17:ff9d1e86ad5f 4941 certificate, &extSz);
sPymbed 17:ff9d1e86ad5f 4942 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 4943 return ret;
sPymbed 17:ff9d1e86ad5f 4944 }
sPymbed 17:ff9d1e86ad5f 4945
sPymbed 17:ff9d1e86ad5f 4946 /* Length of message data with one certificate and extensions. */
sPymbed 17:ff9d1e86ad5f 4947 length = headerSz + certSz + extSz;
sPymbed 17:ff9d1e86ad5f 4948 /* Length of list data with one certificate and extensions. */
sPymbed 17:ff9d1e86ad5f 4949 listSz = CERT_HEADER_SZ + certSz + extSz;
sPymbed 17:ff9d1e86ad5f 4950
sPymbed 17:ff9d1e86ad5f 4951 /* Send rest of chain if sending cert (chain has leading size/s). */
sPymbed 17:ff9d1e86ad5f 4952 if (certSz > 0 && ssl->buffers.certChainCnt > 0) {
sPymbed 17:ff9d1e86ad5f 4953 p = ssl->buffers.certChain->buffer;
sPymbed 17:ff9d1e86ad5f 4954 /* Chain length including extensions. */
sPymbed 17:ff9d1e86ad5f 4955 certChainSz = ssl->buffers.certChain->length +
sPymbed 17:ff9d1e86ad5f 4956 OPAQUE16_LEN * ssl->buffers.certChainCnt;
sPymbed 17:ff9d1e86ad5f 4957 length += certChainSz;
sPymbed 17:ff9d1e86ad5f 4958 listSz += certChainSz;
sPymbed 17:ff9d1e86ad5f 4959 }
sPymbed 17:ff9d1e86ad5f 4960 else
sPymbed 17:ff9d1e86ad5f 4961 certChainSz = 0;
sPymbed 17:ff9d1e86ad5f 4962 }
sPymbed 17:ff9d1e86ad5f 4963
sPymbed 17:ff9d1e86ad5f 4964 payloadSz = length;
sPymbed 17:ff9d1e86ad5f 4965
sPymbed 17:ff9d1e86ad5f 4966 if (ssl->fragOffset != 0)
sPymbed 17:ff9d1e86ad5f 4967 length -= (ssl->fragOffset + headerSz);
sPymbed 17:ff9d1e86ad5f 4968
sPymbed 17:ff9d1e86ad5f 4969 maxFragment = wolfSSL_GetMaxRecordSize(ssl, MAX_RECORD_SIZE);
sPymbed 17:ff9d1e86ad5f 4970
sPymbed 17:ff9d1e86ad5f 4971 while (length > 0 && ret == 0) {
sPymbed 17:ff9d1e86ad5f 4972 byte* output = NULL;
sPymbed 17:ff9d1e86ad5f 4973 word32 fragSz = 0;
sPymbed 17:ff9d1e86ad5f 4974 word32 i = RECORD_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4975 int sendSz = RECORD_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4976
sPymbed 17:ff9d1e86ad5f 4977 if (ssl->fragOffset == 0) {
sPymbed 17:ff9d1e86ad5f 4978 if (headerSz + certSz + extSz + certChainSz <=
sPymbed 17:ff9d1e86ad5f 4979 maxFragment - HANDSHAKE_HEADER_SZ) {
sPymbed 17:ff9d1e86ad5f 4980 fragSz = headerSz + certSz + extSz + certChainSz;
sPymbed 17:ff9d1e86ad5f 4981 }
sPymbed 17:ff9d1e86ad5f 4982 else
sPymbed 17:ff9d1e86ad5f 4983 fragSz = maxFragment - HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4984
sPymbed 17:ff9d1e86ad5f 4985 sendSz += fragSz + HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4986 i += HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 4987 }
sPymbed 17:ff9d1e86ad5f 4988 else {
sPymbed 17:ff9d1e86ad5f 4989 fragSz = min(length, maxFragment);
sPymbed 17:ff9d1e86ad5f 4990 sendSz += fragSz;
sPymbed 17:ff9d1e86ad5f 4991 }
sPymbed 17:ff9d1e86ad5f 4992
sPymbed 17:ff9d1e86ad5f 4993 sendSz += MAX_MSG_EXTRA;
sPymbed 17:ff9d1e86ad5f 4994
sPymbed 17:ff9d1e86ad5f 4995 /* Check buffers are big enough and grow if needed. */
sPymbed 17:ff9d1e86ad5f 4996 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
sPymbed 17:ff9d1e86ad5f 4997 return ret;
sPymbed 17:ff9d1e86ad5f 4998
sPymbed 17:ff9d1e86ad5f 4999 /* Get position in output buffer to write new message to. */
sPymbed 17:ff9d1e86ad5f 5000 output = ssl->buffers.outputBuffer.buffer +
sPymbed 17:ff9d1e86ad5f 5001 ssl->buffers.outputBuffer.length;
sPymbed 17:ff9d1e86ad5f 5002
sPymbed 17:ff9d1e86ad5f 5003 if (ssl->fragOffset == 0) {
sPymbed 17:ff9d1e86ad5f 5004 AddTls13FragHeaders(output, fragSz, 0, payloadSz, certificate, ssl);
sPymbed 17:ff9d1e86ad5f 5005
sPymbed 17:ff9d1e86ad5f 5006 /* Request context. */
sPymbed 17:ff9d1e86ad5f 5007 output[i++] = certReqCtxLen;
sPymbed 17:ff9d1e86ad5f 5008 if (certReqCtxLen > 0) {
sPymbed 17:ff9d1e86ad5f 5009 XMEMCPY(output + i, certReqCtx, certReqCtxLen);
sPymbed 17:ff9d1e86ad5f 5010 i += certReqCtxLen;
sPymbed 17:ff9d1e86ad5f 5011 }
sPymbed 17:ff9d1e86ad5f 5012 length -= OPAQUE8_LEN + certReqCtxLen;
sPymbed 17:ff9d1e86ad5f 5013 fragSz -= OPAQUE8_LEN + certReqCtxLen;
sPymbed 17:ff9d1e86ad5f 5014 /* Certificate list length. */
sPymbed 17:ff9d1e86ad5f 5015 c32to24(listSz, output + i);
sPymbed 17:ff9d1e86ad5f 5016 i += CERT_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 5017 length -= CERT_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 5018 fragSz -= CERT_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 5019 /* Leaf certificate data length. */
sPymbed 17:ff9d1e86ad5f 5020 if (certSz > 0) {
sPymbed 17:ff9d1e86ad5f 5021 c32to24(certSz, output + i);
sPymbed 17:ff9d1e86ad5f 5022 i += CERT_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 5023 length -= CERT_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 5024 fragSz -= CERT_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 5025 }
sPymbed 17:ff9d1e86ad5f 5026 }
sPymbed 17:ff9d1e86ad5f 5027 else
sPymbed 17:ff9d1e86ad5f 5028 AddTls13RecordHeader(output, fragSz, handshake, ssl);
sPymbed 17:ff9d1e86ad5f 5029
sPymbed 17:ff9d1e86ad5f 5030 if (certSz > 0 && ssl->fragOffset < certSz + extSz) {
sPymbed 17:ff9d1e86ad5f 5031 /* Put in the leaf certificate with extensions. */
sPymbed 17:ff9d1e86ad5f 5032 word32 copySz = AddCertExt(ssl, ssl->buffers.certificate->buffer,
sPymbed 17:ff9d1e86ad5f 5033 certSz, extSz, ssl->fragOffset, fragSz, output + i);
sPymbed 17:ff9d1e86ad5f 5034 i += copySz;
sPymbed 17:ff9d1e86ad5f 5035 ssl->fragOffset += copySz;
sPymbed 17:ff9d1e86ad5f 5036 length -= copySz;
sPymbed 17:ff9d1e86ad5f 5037 fragSz -= copySz;
sPymbed 17:ff9d1e86ad5f 5038 if (ssl->fragOffset == certSz + extSz)
sPymbed 17:ff9d1e86ad5f 5039 FreeDer(&ssl->buffers.certExts);
sPymbed 17:ff9d1e86ad5f 5040 }
sPymbed 17:ff9d1e86ad5f 5041 if (certChainSz > 0 && fragSz > 0) {
sPymbed 17:ff9d1e86ad5f 5042 /* Put in the CA certificates with empty extensions. */
sPymbed 17:ff9d1e86ad5f 5043 while (fragSz > 0) {
sPymbed 17:ff9d1e86ad5f 5044 word32 l;
sPymbed 17:ff9d1e86ad5f 5045
sPymbed 17:ff9d1e86ad5f 5046 if (offset == len + OPAQUE16_LEN) {
sPymbed 17:ff9d1e86ad5f 5047 /* Find next CA certificate to write out. */
sPymbed 17:ff9d1e86ad5f 5048 offset = 0;
sPymbed 17:ff9d1e86ad5f 5049 /* Point to the start of current cert in chain buffer. */
sPymbed 17:ff9d1e86ad5f 5050 p = ssl->buffers.certChain->buffer + idx;
sPymbed 17:ff9d1e86ad5f 5051 len = NextCert(ssl->buffers.certChain->buffer,
sPymbed 17:ff9d1e86ad5f 5052 ssl->buffers.certChain->length, &idx);
sPymbed 17:ff9d1e86ad5f 5053 if (len == 0)
sPymbed 17:ff9d1e86ad5f 5054 break;
sPymbed 17:ff9d1e86ad5f 5055 }
sPymbed 17:ff9d1e86ad5f 5056
sPymbed 17:ff9d1e86ad5f 5057 /* Write out certificate and empty extension. */
sPymbed 17:ff9d1e86ad5f 5058 l = AddCertExt(ssl, p, len, OPAQUE16_LEN, offset, fragSz,
sPymbed 17:ff9d1e86ad5f 5059 output + i);
sPymbed 17:ff9d1e86ad5f 5060 i += l;
sPymbed 17:ff9d1e86ad5f 5061 ssl->fragOffset += l;
sPymbed 17:ff9d1e86ad5f 5062 length -= l;
sPymbed 17:ff9d1e86ad5f 5063 fragSz -= l;
sPymbed 17:ff9d1e86ad5f 5064 offset += l;
sPymbed 17:ff9d1e86ad5f 5065 }
sPymbed 17:ff9d1e86ad5f 5066 }
sPymbed 17:ff9d1e86ad5f 5067
sPymbed 17:ff9d1e86ad5f 5068 if ((int)i - RECORD_HEADER_SZ < 0) {
sPymbed 17:ff9d1e86ad5f 5069 WOLFSSL_MSG("Send Cert bad inputSz");
sPymbed 17:ff9d1e86ad5f 5070 return BUFFER_E;
sPymbed 17:ff9d1e86ad5f 5071 }
sPymbed 17:ff9d1e86ad5f 5072
sPymbed 17:ff9d1e86ad5f 5073 /* This message is always encrypted. */
sPymbed 17:ff9d1e86ad5f 5074 sendSz = BuildTls13Message(ssl, output, sendSz,
sPymbed 17:ff9d1e86ad5f 5075 output + RECORD_HEADER_SZ,
sPymbed 17:ff9d1e86ad5f 5076 i - RECORD_HEADER_SZ, handshake, 1, 0, 0);
sPymbed 17:ff9d1e86ad5f 5077 if (sendSz < 0)
sPymbed 17:ff9d1e86ad5f 5078 return sendSz;
sPymbed 17:ff9d1e86ad5f 5079
sPymbed 17:ff9d1e86ad5f 5080 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 5081 if (ssl->hsInfoOn)
sPymbed 17:ff9d1e86ad5f 5082 AddPacketName(ssl, "Certificate");
sPymbed 17:ff9d1e86ad5f 5083 if (ssl->toInfoOn) {
sPymbed 17:ff9d1e86ad5f 5084 AddPacketInfo(ssl, "Certificate", handshake, output,
sPymbed 17:ff9d1e86ad5f 5085 sendSz, WRITE_PROTO, ssl->heap);
sPymbed 17:ff9d1e86ad5f 5086 }
sPymbed 17:ff9d1e86ad5f 5087 #endif
sPymbed 17:ff9d1e86ad5f 5088
sPymbed 17:ff9d1e86ad5f 5089 ssl->buffers.outputBuffer.length += sendSz;
sPymbed 17:ff9d1e86ad5f 5090 if (!ssl->options.groupMessages)
sPymbed 17:ff9d1e86ad5f 5091 ret = SendBuffered(ssl);
sPymbed 17:ff9d1e86ad5f 5092 }
sPymbed 17:ff9d1e86ad5f 5093
sPymbed 17:ff9d1e86ad5f 5094 if (ret != WANT_WRITE) {
sPymbed 17:ff9d1e86ad5f 5095 /* Clean up the fragment offset. */
sPymbed 17:ff9d1e86ad5f 5096 ssl->fragOffset = 0;
sPymbed 17:ff9d1e86ad5f 5097 if (ssl->options.side == WOLFSSL_SERVER_END)
sPymbed 17:ff9d1e86ad5f 5098 ssl->options.serverState = SERVER_CERT_COMPLETE;
sPymbed 17:ff9d1e86ad5f 5099 }
sPymbed 17:ff9d1e86ad5f 5100
sPymbed 17:ff9d1e86ad5f 5101 #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
sPymbed 17:ff9d1e86ad5f 5102 if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->certReqCtx != NULL) {
sPymbed 17:ff9d1e86ad5f 5103 CertReqCtx* ctx = ssl->certReqCtx;
sPymbed 17:ff9d1e86ad5f 5104 ssl->certReqCtx = ssl->certReqCtx->next;
sPymbed 17:ff9d1e86ad5f 5105 XFREE(ctx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 17:ff9d1e86ad5f 5106 }
sPymbed 17:ff9d1e86ad5f 5107 #endif
sPymbed 17:ff9d1e86ad5f 5108
sPymbed 17:ff9d1e86ad5f 5109 WOLFSSL_LEAVE("SendTls13Certificate", ret);
sPymbed 17:ff9d1e86ad5f 5110 WOLFSSL_END(WC_FUNC_CERTIFICATE_SEND);
sPymbed 17:ff9d1e86ad5f 5111
sPymbed 17:ff9d1e86ad5f 5112 return ret;
sPymbed 17:ff9d1e86ad5f 5113 }
sPymbed 17:ff9d1e86ad5f 5114
sPymbed 17:ff9d1e86ad5f 5115 typedef struct Scv13Args {
sPymbed 17:ff9d1e86ad5f 5116 byte* output; /* not allocated */
sPymbed 17:ff9d1e86ad5f 5117 #ifndef NO_RSA
sPymbed 17:ff9d1e86ad5f 5118 byte* verifySig;
sPymbed 17:ff9d1e86ad5f 5119 #endif
sPymbed 17:ff9d1e86ad5f 5120 byte* verify; /* not allocated */
sPymbed 17:ff9d1e86ad5f 5121 word32 idx;
sPymbed 17:ff9d1e86ad5f 5122 word32 sigLen;
sPymbed 17:ff9d1e86ad5f 5123 int sendSz;
sPymbed 17:ff9d1e86ad5f 5124 word16 length;
sPymbed 17:ff9d1e86ad5f 5125
sPymbed 17:ff9d1e86ad5f 5126 byte sigAlgo;
sPymbed 17:ff9d1e86ad5f 5127 byte* sigData;
sPymbed 17:ff9d1e86ad5f 5128 word16 sigDataSz;
sPymbed 17:ff9d1e86ad5f 5129 } Scv13Args;
sPymbed 17:ff9d1e86ad5f 5130
sPymbed 17:ff9d1e86ad5f 5131 static void FreeScv13Args(WOLFSSL* ssl, void* pArgs)
sPymbed 17:ff9d1e86ad5f 5132 {
sPymbed 17:ff9d1e86ad5f 5133 Scv13Args* args = (Scv13Args*)pArgs;
sPymbed 17:ff9d1e86ad5f 5134
sPymbed 17:ff9d1e86ad5f 5135 (void)ssl;
sPymbed 17:ff9d1e86ad5f 5136
sPymbed 17:ff9d1e86ad5f 5137 #ifndef NO_RSA
sPymbed 17:ff9d1e86ad5f 5138 if (args->verifySig) {
sPymbed 17:ff9d1e86ad5f 5139 XFREE(args->verifySig, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
sPymbed 17:ff9d1e86ad5f 5140 args->verifySig = NULL;
sPymbed 17:ff9d1e86ad5f 5141 }
sPymbed 17:ff9d1e86ad5f 5142 #endif
sPymbed 17:ff9d1e86ad5f 5143 if (args->sigData) {
sPymbed 17:ff9d1e86ad5f 5144 XFREE(args->sigData, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
sPymbed 17:ff9d1e86ad5f 5145 args->sigData = NULL;
sPymbed 17:ff9d1e86ad5f 5146 }
sPymbed 17:ff9d1e86ad5f 5147 }
sPymbed 17:ff9d1e86ad5f 5148
sPymbed 17:ff9d1e86ad5f 5149 /* handle generation TLS v1.3 certificate_verify (15) */
sPymbed 17:ff9d1e86ad5f 5150 /* Send the TLS v1.3 CertificateVerify message.
sPymbed 17:ff9d1e86ad5f 5151 * A hash of all the message so far is used.
sPymbed 17:ff9d1e86ad5f 5152 * The signed data is:
sPymbed 17:ff9d1e86ad5f 5153 * 0x20 * 64 | context string | 0x00 | hash of messages
sPymbed 17:ff9d1e86ad5f 5154 * This message is always encrypted in TLS v1.3.
sPymbed 17:ff9d1e86ad5f 5155 *
sPymbed 17:ff9d1e86ad5f 5156 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 5157 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 5158 */
sPymbed 17:ff9d1e86ad5f 5159 static int SendTls13CertificateVerify(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 5160 {
sPymbed 17:ff9d1e86ad5f 5161 int ret = 0;
sPymbed 17:ff9d1e86ad5f 5162 buffer* sig = &ssl->buffers.sig;
sPymbed 17:ff9d1e86ad5f 5163 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 5164 Scv13Args* args = (Scv13Args*)ssl->async.args;
sPymbed 17:ff9d1e86ad5f 5165 typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
sPymbed 17:ff9d1e86ad5f 5166 (void)sizeof(args_test);
sPymbed 17:ff9d1e86ad5f 5167 #else
sPymbed 17:ff9d1e86ad5f 5168 Scv13Args args[1];
sPymbed 17:ff9d1e86ad5f 5169 #endif
sPymbed 17:ff9d1e86ad5f 5170
sPymbed 17:ff9d1e86ad5f 5171 WOLFSSL_START(WC_FUNC_CERTIFICATE_VERIFY_SEND);
sPymbed 17:ff9d1e86ad5f 5172 WOLFSSL_ENTER("SendTls13CertificateVerify");
sPymbed 17:ff9d1e86ad5f 5173
sPymbed 17:ff9d1e86ad5f 5174 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 5175 ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
sPymbed 17:ff9d1e86ad5f 5176 if (ret != WC_NOT_PENDING_E) {
sPymbed 17:ff9d1e86ad5f 5177 /* Check for error */
sPymbed 17:ff9d1e86ad5f 5178 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 5179 goto exit_scv;
sPymbed 17:ff9d1e86ad5f 5180 }
sPymbed 17:ff9d1e86ad5f 5181 else
sPymbed 17:ff9d1e86ad5f 5182 #endif
sPymbed 17:ff9d1e86ad5f 5183 {
sPymbed 17:ff9d1e86ad5f 5184 /* Reset state */
sPymbed 17:ff9d1e86ad5f 5185 ret = 0;
sPymbed 17:ff9d1e86ad5f 5186 ssl->options.asyncState = TLS_ASYNC_BEGIN;
sPymbed 17:ff9d1e86ad5f 5187 XMEMSET(args, 0, sizeof(Scv13Args));
sPymbed 17:ff9d1e86ad5f 5188 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 5189 ssl->async.freeArgs = FreeScv13Args;
sPymbed 17:ff9d1e86ad5f 5190 #endif
sPymbed 17:ff9d1e86ad5f 5191 }
sPymbed 17:ff9d1e86ad5f 5192
sPymbed 17:ff9d1e86ad5f 5193 switch(ssl->options.asyncState)
sPymbed 17:ff9d1e86ad5f 5194 {
sPymbed 17:ff9d1e86ad5f 5195 case TLS_ASYNC_BEGIN:
sPymbed 17:ff9d1e86ad5f 5196 {
sPymbed 17:ff9d1e86ad5f 5197 if (ssl->options.sendVerify == SEND_BLANK_CERT) {
sPymbed 17:ff9d1e86ad5f 5198 return 0; /* sent blank cert, can't verify */
sPymbed 17:ff9d1e86ad5f 5199 }
sPymbed 17:ff9d1e86ad5f 5200
sPymbed 17:ff9d1e86ad5f 5201 args->sendSz = MAX_CERT_VERIFY_SZ;
sPymbed 17:ff9d1e86ad5f 5202 /* Always encrypted. */
sPymbed 17:ff9d1e86ad5f 5203 args->sendSz += MAX_MSG_EXTRA;
sPymbed 17:ff9d1e86ad5f 5204
sPymbed 17:ff9d1e86ad5f 5205 /* check for available size */
sPymbed 17:ff9d1e86ad5f 5206 if ((ret = CheckAvailableSize(ssl, args->sendSz)) != 0) {
sPymbed 17:ff9d1e86ad5f 5207 goto exit_scv;
sPymbed 17:ff9d1e86ad5f 5208 }
sPymbed 17:ff9d1e86ad5f 5209
sPymbed 17:ff9d1e86ad5f 5210 /* get output buffer */
sPymbed 17:ff9d1e86ad5f 5211 args->output = ssl->buffers.outputBuffer.buffer +
sPymbed 17:ff9d1e86ad5f 5212 ssl->buffers.outputBuffer.length;
sPymbed 17:ff9d1e86ad5f 5213
sPymbed 17:ff9d1e86ad5f 5214 /* Advance state and proceed */
sPymbed 17:ff9d1e86ad5f 5215 ssl->options.asyncState = TLS_ASYNC_BUILD;
sPymbed 17:ff9d1e86ad5f 5216 } /* case TLS_ASYNC_BEGIN */
sPymbed 17:ff9d1e86ad5f 5217 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 5218
sPymbed 17:ff9d1e86ad5f 5219 case TLS_ASYNC_BUILD:
sPymbed 17:ff9d1e86ad5f 5220 {
sPymbed 17:ff9d1e86ad5f 5221 /* idx is used to track verify pointer offset to output */
sPymbed 17:ff9d1e86ad5f 5222 args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 5223 args->verify =
sPymbed 17:ff9d1e86ad5f 5224 &args->output[RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ];
sPymbed 17:ff9d1e86ad5f 5225
sPymbed 17:ff9d1e86ad5f 5226 if (ssl->buffers.key == NULL) {
sPymbed 17:ff9d1e86ad5f 5227 #ifdef HAVE_PK_CALLBACKS
sPymbed 17:ff9d1e86ad5f 5228 if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx))
sPymbed 17:ff9d1e86ad5f 5229 args->length = GetPrivateKeySigSize(ssl);
sPymbed 17:ff9d1e86ad5f 5230 else
sPymbed 17:ff9d1e86ad5f 5231 #endif
sPymbed 17:ff9d1e86ad5f 5232 ERROR_OUT(NO_PRIVATE_KEY, exit_scv);
sPymbed 17:ff9d1e86ad5f 5233 }
sPymbed 17:ff9d1e86ad5f 5234 else {
sPymbed 17:ff9d1e86ad5f 5235 ret = DecodePrivateKey(ssl, &args->length);
sPymbed 17:ff9d1e86ad5f 5236 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 5237 goto exit_scv;
sPymbed 17:ff9d1e86ad5f 5238 }
sPymbed 17:ff9d1e86ad5f 5239
sPymbed 17:ff9d1e86ad5f 5240 if (args->length <= 0) {
sPymbed 17:ff9d1e86ad5f 5241 ERROR_OUT(NO_PRIVATE_KEY, exit_scv);
sPymbed 17:ff9d1e86ad5f 5242 }
sPymbed 17:ff9d1e86ad5f 5243
sPymbed 17:ff9d1e86ad5f 5244 /* Add signature algorithm. */
sPymbed 17:ff9d1e86ad5f 5245 if (ssl->hsType == DYNAMIC_TYPE_RSA)
sPymbed 17:ff9d1e86ad5f 5246 args->sigAlgo = rsa_pss_sa_algo;
sPymbed 17:ff9d1e86ad5f 5247 else if (ssl->hsType == DYNAMIC_TYPE_ECC)
sPymbed 17:ff9d1e86ad5f 5248 args->sigAlgo = ecc_dsa_sa_algo;
sPymbed 17:ff9d1e86ad5f 5249 #ifdef HAVE_ED25519
sPymbed 17:ff9d1e86ad5f 5250 else if (ssl->hsType == DYNAMIC_TYPE_ED25519)
sPymbed 17:ff9d1e86ad5f 5251 args->sigAlgo = ed25519_sa_algo;
sPymbed 17:ff9d1e86ad5f 5252 #endif
sPymbed 17:ff9d1e86ad5f 5253 EncodeSigAlg(ssl->suites->hashAlgo, args->sigAlgo, args->verify);
sPymbed 17:ff9d1e86ad5f 5254
sPymbed 17:ff9d1e86ad5f 5255 /* Create the data to be signed. */
sPymbed 17:ff9d1e86ad5f 5256 args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap,
sPymbed 17:ff9d1e86ad5f 5257 DYNAMIC_TYPE_SIGNATURE);
sPymbed 17:ff9d1e86ad5f 5258 if (args->sigData == NULL) {
sPymbed 17:ff9d1e86ad5f 5259 ERROR_OUT(MEMORY_E, exit_scv);
sPymbed 17:ff9d1e86ad5f 5260 }
sPymbed 17:ff9d1e86ad5f 5261
sPymbed 17:ff9d1e86ad5f 5262 ret = CreateSigData(ssl, args->sigData, &args->sigDataSz, 0);
sPymbed 17:ff9d1e86ad5f 5263 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 5264 goto exit_scv;
sPymbed 17:ff9d1e86ad5f 5265
sPymbed 17:ff9d1e86ad5f 5266 #ifndef NO_RSA
sPymbed 17:ff9d1e86ad5f 5267 if (ssl->hsType == DYNAMIC_TYPE_RSA) {
sPymbed 17:ff9d1e86ad5f 5268 /* build encoded signature buffer */
sPymbed 17:ff9d1e86ad5f 5269 sig->length = MAX_ENCODED_SIG_SZ;
sPymbed 17:ff9d1e86ad5f 5270 sig->buffer = (byte*)XMALLOC(sig->length, ssl->heap,
sPymbed 17:ff9d1e86ad5f 5271 DYNAMIC_TYPE_SIGNATURE);
sPymbed 17:ff9d1e86ad5f 5272 if (sig->buffer == NULL) {
sPymbed 17:ff9d1e86ad5f 5273 ERROR_OUT(MEMORY_E, exit_scv);
sPymbed 17:ff9d1e86ad5f 5274 }
sPymbed 17:ff9d1e86ad5f 5275
sPymbed 17:ff9d1e86ad5f 5276 ret = CreateRSAEncodedSig(sig->buffer, args->sigData,
sPymbed 17:ff9d1e86ad5f 5277 args->sigDataSz, args->sigAlgo, ssl->suites->hashAlgo);
sPymbed 17:ff9d1e86ad5f 5278 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 5279 goto exit_scv;
sPymbed 17:ff9d1e86ad5f 5280 sig->length = ret;
sPymbed 17:ff9d1e86ad5f 5281 ret = 0;
sPymbed 17:ff9d1e86ad5f 5282
sPymbed 17:ff9d1e86ad5f 5283 /* Maximum size of RSA Signature. */
sPymbed 17:ff9d1e86ad5f 5284 args->sigLen = args->length;
sPymbed 17:ff9d1e86ad5f 5285 }
sPymbed 17:ff9d1e86ad5f 5286 #endif /* !NO_RSA */
sPymbed 17:ff9d1e86ad5f 5287 #ifdef HAVE_ECC
sPymbed 17:ff9d1e86ad5f 5288 if (ssl->hsType == DYNAMIC_TYPE_ECC) {
sPymbed 17:ff9d1e86ad5f 5289 sig->length = args->sendSz - args->idx - HASH_SIG_SIZE -
sPymbed 17:ff9d1e86ad5f 5290 VERIFY_HEADER;
sPymbed 17:ff9d1e86ad5f 5291 ret = CreateECCEncodedSig(args->sigData,
sPymbed 17:ff9d1e86ad5f 5292 args->sigDataSz, ssl->suites->hashAlgo);
sPymbed 17:ff9d1e86ad5f 5293 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 5294 goto exit_scv;
sPymbed 17:ff9d1e86ad5f 5295 args->sigDataSz = (word16)ret;
sPymbed 17:ff9d1e86ad5f 5296 ret = 0;
sPymbed 17:ff9d1e86ad5f 5297 }
sPymbed 17:ff9d1e86ad5f 5298 #endif /* HAVE_ECC */
sPymbed 17:ff9d1e86ad5f 5299 #ifdef HAVE_ED25519
sPymbed 17:ff9d1e86ad5f 5300 if (ssl->hsType == DYNAMIC_TYPE_ED25519) {
sPymbed 17:ff9d1e86ad5f 5301 ret = Ed25519CheckPubKey(ssl);
sPymbed 17:ff9d1e86ad5f 5302 if (ret < 0) {
sPymbed 17:ff9d1e86ad5f 5303 ERROR_OUT(ret, exit_scv);
sPymbed 17:ff9d1e86ad5f 5304 }
sPymbed 17:ff9d1e86ad5f 5305 sig->length = ED25519_SIG_SIZE;
sPymbed 17:ff9d1e86ad5f 5306 }
sPymbed 17:ff9d1e86ad5f 5307 #endif /* HAVE_ECC */
sPymbed 17:ff9d1e86ad5f 5308
sPymbed 17:ff9d1e86ad5f 5309 /* Advance state and proceed */
sPymbed 17:ff9d1e86ad5f 5310 ssl->options.asyncState = TLS_ASYNC_DO;
sPymbed 17:ff9d1e86ad5f 5311 } /* case TLS_ASYNC_BUILD */
sPymbed 17:ff9d1e86ad5f 5312 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 5313
sPymbed 17:ff9d1e86ad5f 5314 case TLS_ASYNC_DO:
sPymbed 17:ff9d1e86ad5f 5315 {
sPymbed 17:ff9d1e86ad5f 5316 #ifdef HAVE_ECC
sPymbed 17:ff9d1e86ad5f 5317 if (ssl->hsType == DYNAMIC_TYPE_ECC) {
sPymbed 17:ff9d1e86ad5f 5318 ret = EccSign(ssl, args->sigData, args->sigDataSz,
sPymbed 17:ff9d1e86ad5f 5319 args->verify + HASH_SIG_SIZE + VERIFY_HEADER,
sPymbed 17:ff9d1e86ad5f 5320 &sig->length, (ecc_key*)ssl->hsKey,
sPymbed 17:ff9d1e86ad5f 5321 #ifdef HAVE_PK_CALLBACKS
sPymbed 17:ff9d1e86ad5f 5322 ssl->buffers.key
sPymbed 17:ff9d1e86ad5f 5323 #else
sPymbed 17:ff9d1e86ad5f 5324 NULL
sPymbed 17:ff9d1e86ad5f 5325 #endif
sPymbed 17:ff9d1e86ad5f 5326 );
sPymbed 17:ff9d1e86ad5f 5327 args->length = (word16)sig->length;
sPymbed 17:ff9d1e86ad5f 5328 }
sPymbed 17:ff9d1e86ad5f 5329 #endif /* HAVE_ECC */
sPymbed 17:ff9d1e86ad5f 5330 #ifdef HAVE_ED25519
sPymbed 17:ff9d1e86ad5f 5331 if (ssl->hsType == DYNAMIC_TYPE_ED25519) {
sPymbed 17:ff9d1e86ad5f 5332 ret = Ed25519Sign(ssl, args->sigData, args->sigDataSz,
sPymbed 17:ff9d1e86ad5f 5333 args->verify + HASH_SIG_SIZE + VERIFY_HEADER,
sPymbed 17:ff9d1e86ad5f 5334 &sig->length, (ed25519_key*)ssl->hsKey,
sPymbed 17:ff9d1e86ad5f 5335 #ifdef HAVE_PK_CALLBACKS
sPymbed 17:ff9d1e86ad5f 5336 ssl->buffers.key
sPymbed 17:ff9d1e86ad5f 5337 #else
sPymbed 17:ff9d1e86ad5f 5338 NULL
sPymbed 17:ff9d1e86ad5f 5339 #endif
sPymbed 17:ff9d1e86ad5f 5340 );
sPymbed 17:ff9d1e86ad5f 5341 args->length = sig->length;
sPymbed 17:ff9d1e86ad5f 5342 }
sPymbed 17:ff9d1e86ad5f 5343 #endif
sPymbed 17:ff9d1e86ad5f 5344 #ifndef NO_RSA
sPymbed 17:ff9d1e86ad5f 5345 if (ssl->hsType == DYNAMIC_TYPE_RSA) {
sPymbed 17:ff9d1e86ad5f 5346
sPymbed 17:ff9d1e86ad5f 5347 ret = RsaSign(ssl, sig->buffer, sig->length,
sPymbed 17:ff9d1e86ad5f 5348 args->verify + HASH_SIG_SIZE + VERIFY_HEADER, &args->sigLen,
sPymbed 17:ff9d1e86ad5f 5349 args->sigAlgo, ssl->suites->hashAlgo,
sPymbed 17:ff9d1e86ad5f 5350 (RsaKey*)ssl->hsKey,
sPymbed 17:ff9d1e86ad5f 5351 ssl->buffers.key
sPymbed 17:ff9d1e86ad5f 5352 );
sPymbed 17:ff9d1e86ad5f 5353 args->length = (word16)args->sigLen;
sPymbed 17:ff9d1e86ad5f 5354 }
sPymbed 17:ff9d1e86ad5f 5355 #endif /* !NO_RSA */
sPymbed 17:ff9d1e86ad5f 5356
sPymbed 17:ff9d1e86ad5f 5357 /* Check for error */
sPymbed 17:ff9d1e86ad5f 5358 if (ret != 0) {
sPymbed 17:ff9d1e86ad5f 5359 goto exit_scv;
sPymbed 17:ff9d1e86ad5f 5360 }
sPymbed 17:ff9d1e86ad5f 5361
sPymbed 17:ff9d1e86ad5f 5362 /* Add signature length. */
sPymbed 17:ff9d1e86ad5f 5363 c16toa(args->length, args->verify + HASH_SIG_SIZE);
sPymbed 17:ff9d1e86ad5f 5364
sPymbed 17:ff9d1e86ad5f 5365 /* Advance state and proceed */
sPymbed 17:ff9d1e86ad5f 5366 ssl->options.asyncState = TLS_ASYNC_VERIFY;
sPymbed 17:ff9d1e86ad5f 5367 } /* case TLS_ASYNC_DO */
sPymbed 17:ff9d1e86ad5f 5368 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 5369
sPymbed 17:ff9d1e86ad5f 5370 case TLS_ASYNC_VERIFY:
sPymbed 17:ff9d1e86ad5f 5371 {
sPymbed 17:ff9d1e86ad5f 5372 #ifndef NO_RSA
sPymbed 17:ff9d1e86ad5f 5373 if (ssl->hsType == DYNAMIC_TYPE_RSA) {
sPymbed 17:ff9d1e86ad5f 5374 if (args->verifySig == NULL) {
sPymbed 17:ff9d1e86ad5f 5375 args->verifySig = (byte*)XMALLOC(args->sigLen, ssl->heap,
sPymbed 17:ff9d1e86ad5f 5376 DYNAMIC_TYPE_SIGNATURE);
sPymbed 17:ff9d1e86ad5f 5377 if (args->verifySig == NULL) {
sPymbed 17:ff9d1e86ad5f 5378 ERROR_OUT(MEMORY_E, exit_scv);
sPymbed 17:ff9d1e86ad5f 5379 }
sPymbed 17:ff9d1e86ad5f 5380 XMEMCPY(args->verifySig,
sPymbed 17:ff9d1e86ad5f 5381 args->verify + HASH_SIG_SIZE + VERIFY_HEADER,
sPymbed 17:ff9d1e86ad5f 5382 args->sigLen);
sPymbed 17:ff9d1e86ad5f 5383 }
sPymbed 17:ff9d1e86ad5f 5384
sPymbed 17:ff9d1e86ad5f 5385 /* check for signature faults */
sPymbed 17:ff9d1e86ad5f 5386 ret = VerifyRsaSign(ssl, args->verifySig, args->sigLen,
sPymbed 17:ff9d1e86ad5f 5387 sig->buffer, sig->length, args->sigAlgo,
sPymbed 17:ff9d1e86ad5f 5388 ssl->suites->hashAlgo, (RsaKey*)ssl->hsKey,
sPymbed 17:ff9d1e86ad5f 5389 ssl->buffers.key
sPymbed 17:ff9d1e86ad5f 5390 );
sPymbed 17:ff9d1e86ad5f 5391 }
sPymbed 17:ff9d1e86ad5f 5392 #endif /* !NO_RSA */
sPymbed 17:ff9d1e86ad5f 5393
sPymbed 17:ff9d1e86ad5f 5394 /* Check for error */
sPymbed 17:ff9d1e86ad5f 5395 if (ret != 0) {
sPymbed 17:ff9d1e86ad5f 5396 goto exit_scv;
sPymbed 17:ff9d1e86ad5f 5397 }
sPymbed 17:ff9d1e86ad5f 5398
sPymbed 17:ff9d1e86ad5f 5399 /* Advance state and proceed */
sPymbed 17:ff9d1e86ad5f 5400 ssl->options.asyncState = TLS_ASYNC_FINALIZE;
sPymbed 17:ff9d1e86ad5f 5401 } /* case TLS_ASYNC_VERIFY */
sPymbed 17:ff9d1e86ad5f 5402 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 5403
sPymbed 17:ff9d1e86ad5f 5404 case TLS_ASYNC_FINALIZE:
sPymbed 17:ff9d1e86ad5f 5405 {
sPymbed 17:ff9d1e86ad5f 5406 /* Put the record and handshake headers on. */
sPymbed 17:ff9d1e86ad5f 5407 AddTls13Headers(args->output, args->length + HASH_SIG_SIZE +
sPymbed 17:ff9d1e86ad5f 5408 VERIFY_HEADER, certificate_verify, ssl);
sPymbed 17:ff9d1e86ad5f 5409
sPymbed 17:ff9d1e86ad5f 5410 args->sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ +
sPymbed 17:ff9d1e86ad5f 5411 args->length + HASH_SIG_SIZE + VERIFY_HEADER;
sPymbed 17:ff9d1e86ad5f 5412
sPymbed 17:ff9d1e86ad5f 5413 /* Advance state and proceed */
sPymbed 17:ff9d1e86ad5f 5414 ssl->options.asyncState = TLS_ASYNC_END;
sPymbed 17:ff9d1e86ad5f 5415 } /* case TLS_ASYNC_FINALIZE */
sPymbed 17:ff9d1e86ad5f 5416 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 5417
sPymbed 17:ff9d1e86ad5f 5418 case TLS_ASYNC_END:
sPymbed 17:ff9d1e86ad5f 5419 {
sPymbed 17:ff9d1e86ad5f 5420 /* This message is always encrypted. */
sPymbed 17:ff9d1e86ad5f 5421 ret = BuildTls13Message(ssl, args->output,
sPymbed 17:ff9d1e86ad5f 5422 MAX_CERT_VERIFY_SZ + MAX_MSG_EXTRA,
sPymbed 17:ff9d1e86ad5f 5423 args->output + RECORD_HEADER_SZ,
sPymbed 17:ff9d1e86ad5f 5424 args->sendSz - RECORD_HEADER_SZ, handshake,
sPymbed 17:ff9d1e86ad5f 5425 1, 0, 0);
sPymbed 17:ff9d1e86ad5f 5426
sPymbed 17:ff9d1e86ad5f 5427 if (ret < 0) {
sPymbed 17:ff9d1e86ad5f 5428 goto exit_scv;
sPymbed 17:ff9d1e86ad5f 5429 }
sPymbed 17:ff9d1e86ad5f 5430 else {
sPymbed 17:ff9d1e86ad5f 5431 args->sendSz = ret;
sPymbed 17:ff9d1e86ad5f 5432 ret = 0;
sPymbed 17:ff9d1e86ad5f 5433 }
sPymbed 17:ff9d1e86ad5f 5434
sPymbed 17:ff9d1e86ad5f 5435 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 5436 if (ssl->hsInfoOn)
sPymbed 17:ff9d1e86ad5f 5437 AddPacketName(ssl, "CertificateVerify");
sPymbed 17:ff9d1e86ad5f 5438 if (ssl->toInfoOn) {
sPymbed 17:ff9d1e86ad5f 5439 AddPacketInfo(ssl, "CertificateVerify", handshake,
sPymbed 17:ff9d1e86ad5f 5440 args->output, args->sendSz, WRITE_PROTO, ssl->heap);
sPymbed 17:ff9d1e86ad5f 5441 }
sPymbed 17:ff9d1e86ad5f 5442 #endif
sPymbed 17:ff9d1e86ad5f 5443
sPymbed 17:ff9d1e86ad5f 5444 ssl->buffers.outputBuffer.length += args->sendSz;
sPymbed 17:ff9d1e86ad5f 5445
sPymbed 17:ff9d1e86ad5f 5446 if (!ssl->options.groupMessages)
sPymbed 17:ff9d1e86ad5f 5447 ret = SendBuffered(ssl);
sPymbed 17:ff9d1e86ad5f 5448 break;
sPymbed 17:ff9d1e86ad5f 5449 }
sPymbed 17:ff9d1e86ad5f 5450 default:
sPymbed 17:ff9d1e86ad5f 5451 ret = INPUT_CASE_ERROR;
sPymbed 17:ff9d1e86ad5f 5452 } /* switch(ssl->options.asyncState) */
sPymbed 17:ff9d1e86ad5f 5453
sPymbed 17:ff9d1e86ad5f 5454 exit_scv:
sPymbed 17:ff9d1e86ad5f 5455
sPymbed 17:ff9d1e86ad5f 5456 WOLFSSL_LEAVE("SendTls13CertificateVerify", ret);
sPymbed 17:ff9d1e86ad5f 5457 WOLFSSL_END(WC_FUNC_CERTIFICATE_VERIFY_SEND);
sPymbed 17:ff9d1e86ad5f 5458
sPymbed 17:ff9d1e86ad5f 5459 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 5460 /* Handle async operation */
sPymbed 17:ff9d1e86ad5f 5461 if (ret == WC_PENDING_E) {
sPymbed 17:ff9d1e86ad5f 5462 return ret;
sPymbed 17:ff9d1e86ad5f 5463 }
sPymbed 17:ff9d1e86ad5f 5464 #endif /* WOLFSSL_ASYNC_CRYPT */
sPymbed 17:ff9d1e86ad5f 5465
sPymbed 17:ff9d1e86ad5f 5466 /* Final cleanup */
sPymbed 17:ff9d1e86ad5f 5467 FreeScv13Args(ssl, args);
sPymbed 17:ff9d1e86ad5f 5468 FreeKeyExchange(ssl);
sPymbed 17:ff9d1e86ad5f 5469
sPymbed 17:ff9d1e86ad5f 5470 return ret;
sPymbed 17:ff9d1e86ad5f 5471 }
sPymbed 17:ff9d1e86ad5f 5472
sPymbed 17:ff9d1e86ad5f 5473 /* handle processing TLS v1.3 certificate (11) */
sPymbed 17:ff9d1e86ad5f 5474 /* Parse and handle a TLS v1.3 Certificate message.
sPymbed 17:ff9d1e86ad5f 5475 *
sPymbed 17:ff9d1e86ad5f 5476 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 5477 * input The message buffer.
sPymbed 17:ff9d1e86ad5f 5478 * inOutIdx On entry, the index into the message buffer of Certificate.
sPymbed 17:ff9d1e86ad5f 5479 * On exit, the index of byte after the Certificate message.
sPymbed 17:ff9d1e86ad5f 5480 * totalSz The length of the current handshake message.
sPymbed 17:ff9d1e86ad5f 5481 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 5482 */
sPymbed 17:ff9d1e86ad5f 5483 static int DoTls13Certificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
sPymbed 17:ff9d1e86ad5f 5484 word32 totalSz)
sPymbed 17:ff9d1e86ad5f 5485 {
sPymbed 17:ff9d1e86ad5f 5486 int ret;
sPymbed 17:ff9d1e86ad5f 5487
sPymbed 17:ff9d1e86ad5f 5488 WOLFSSL_START(WC_FUNC_CERTIFICATE_DO);
sPymbed 17:ff9d1e86ad5f 5489 WOLFSSL_ENTER("DoTls13Certificate");
sPymbed 17:ff9d1e86ad5f 5490
sPymbed 17:ff9d1e86ad5f 5491 ret = ProcessPeerCerts(ssl, input, inOutIdx, totalSz);
sPymbed 17:ff9d1e86ad5f 5492 if (ret == 0) {
sPymbed 17:ff9d1e86ad5f 5493 #if !defined(NO_WOLFSSL_CLIENT)
sPymbed 17:ff9d1e86ad5f 5494 if (ssl->options.side == WOLFSSL_CLIENT_END)
sPymbed 17:ff9d1e86ad5f 5495 ssl->options.serverState = SERVER_CERT_COMPLETE;
sPymbed 17:ff9d1e86ad5f 5496 #endif
sPymbed 17:ff9d1e86ad5f 5497 #if !defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
sPymbed 17:ff9d1e86ad5f 5498 if (ssl->options.side == WOLFSSL_SERVER_END &&
sPymbed 17:ff9d1e86ad5f 5499 ssl->options.handShakeState == HANDSHAKE_DONE) {
sPymbed 17:ff9d1e86ad5f 5500 /* reset handshake states */
sPymbed 17:ff9d1e86ad5f 5501 ssl->options.serverState = SERVER_FINISHED_COMPLETE;
sPymbed 17:ff9d1e86ad5f 5502 ssl->options.acceptState = TICKET_SENT;
sPymbed 17:ff9d1e86ad5f 5503 ssl->options.handShakeState = SERVER_FINISHED_COMPLETE;
sPymbed 17:ff9d1e86ad5f 5504 }
sPymbed 17:ff9d1e86ad5f 5505 #endif
sPymbed 17:ff9d1e86ad5f 5506 }
sPymbed 17:ff9d1e86ad5f 5507
sPymbed 17:ff9d1e86ad5f 5508 WOLFSSL_LEAVE("DoTls13Certificate", ret);
sPymbed 17:ff9d1e86ad5f 5509 WOLFSSL_END(WC_FUNC_CERTIFICATE_DO);
sPymbed 17:ff9d1e86ad5f 5510
sPymbed 17:ff9d1e86ad5f 5511 return ret;
sPymbed 17:ff9d1e86ad5f 5512 }
sPymbed 17:ff9d1e86ad5f 5513
sPymbed 17:ff9d1e86ad5f 5514 #if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)
sPymbed 17:ff9d1e86ad5f 5515
sPymbed 17:ff9d1e86ad5f 5516 typedef struct Dcv13Args {
sPymbed 17:ff9d1e86ad5f 5517 byte* output; /* not allocated */
sPymbed 17:ff9d1e86ad5f 5518 word32 sendSz;
sPymbed 17:ff9d1e86ad5f 5519 word16 sz;
sPymbed 17:ff9d1e86ad5f 5520 word32 sigSz;
sPymbed 17:ff9d1e86ad5f 5521 word32 idx;
sPymbed 17:ff9d1e86ad5f 5522 word32 begin;
sPymbed 17:ff9d1e86ad5f 5523 byte hashAlgo;
sPymbed 17:ff9d1e86ad5f 5524 byte sigAlgo;
sPymbed 17:ff9d1e86ad5f 5525
sPymbed 17:ff9d1e86ad5f 5526 byte* sigData;
sPymbed 17:ff9d1e86ad5f 5527 word16 sigDataSz;
sPymbed 17:ff9d1e86ad5f 5528 } Dcv13Args;
sPymbed 17:ff9d1e86ad5f 5529
sPymbed 17:ff9d1e86ad5f 5530 static void FreeDcv13Args(WOLFSSL* ssl, void* pArgs)
sPymbed 17:ff9d1e86ad5f 5531 {
sPymbed 17:ff9d1e86ad5f 5532 Dcv13Args* args = (Dcv13Args*)pArgs;
sPymbed 17:ff9d1e86ad5f 5533
sPymbed 17:ff9d1e86ad5f 5534 if (args->sigData != NULL) {
sPymbed 17:ff9d1e86ad5f 5535 XFREE(args->sigData, ssl->heap, DYNAMIC_TYPE_SIGNATURE);
sPymbed 17:ff9d1e86ad5f 5536 args->sigData = NULL;
sPymbed 17:ff9d1e86ad5f 5537 }
sPymbed 17:ff9d1e86ad5f 5538
sPymbed 17:ff9d1e86ad5f 5539 (void)ssl;
sPymbed 17:ff9d1e86ad5f 5540 }
sPymbed 17:ff9d1e86ad5f 5541
sPymbed 17:ff9d1e86ad5f 5542 /* handle processing TLS v1.3 certificate_verify (15) */
sPymbed 17:ff9d1e86ad5f 5543 /* Parse and handle a TLS v1.3 CertificateVerify message.
sPymbed 17:ff9d1e86ad5f 5544 *
sPymbed 17:ff9d1e86ad5f 5545 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 5546 * input The message buffer.
sPymbed 17:ff9d1e86ad5f 5547 * inOutIdx On entry, the index into the message buffer of
sPymbed 17:ff9d1e86ad5f 5548 * CertificateVerify.
sPymbed 17:ff9d1e86ad5f 5549 * On exit, the index of byte after the CertificateVerify message.
sPymbed 17:ff9d1e86ad5f 5550 * totalSz The length of the current handshake message.
sPymbed 17:ff9d1e86ad5f 5551 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 5552 */
sPymbed 17:ff9d1e86ad5f 5553 static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
sPymbed 17:ff9d1e86ad5f 5554 word32* inOutIdx, word32 totalSz)
sPymbed 17:ff9d1e86ad5f 5555 {
sPymbed 17:ff9d1e86ad5f 5556 int ret = 0;
sPymbed 17:ff9d1e86ad5f 5557 buffer* sig = &ssl->buffers.sig;
sPymbed 17:ff9d1e86ad5f 5558 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 5559 Dcv13Args* args = (Dcv13Args*)ssl->async.args;
sPymbed 17:ff9d1e86ad5f 5560 typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
sPymbed 17:ff9d1e86ad5f 5561 (void)sizeof(args_test);
sPymbed 17:ff9d1e86ad5f 5562 #else
sPymbed 17:ff9d1e86ad5f 5563 Dcv13Args args[1];
sPymbed 17:ff9d1e86ad5f 5564 #endif
sPymbed 17:ff9d1e86ad5f 5565
sPymbed 17:ff9d1e86ad5f 5566 WOLFSSL_START(WC_FUNC_CERTIFICATE_VERIFY_DO);
sPymbed 17:ff9d1e86ad5f 5567 WOLFSSL_ENTER("DoTls13CertificateVerify");
sPymbed 17:ff9d1e86ad5f 5568
sPymbed 17:ff9d1e86ad5f 5569 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 5570 ret = wolfSSL_AsyncPop(ssl, &ssl->options.asyncState);
sPymbed 17:ff9d1e86ad5f 5571 if (ret != WC_NOT_PENDING_E) {
sPymbed 17:ff9d1e86ad5f 5572 /* Check for error */
sPymbed 17:ff9d1e86ad5f 5573 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 5574 goto exit_dcv;
sPymbed 17:ff9d1e86ad5f 5575 }
sPymbed 17:ff9d1e86ad5f 5576 else
sPymbed 17:ff9d1e86ad5f 5577 #endif
sPymbed 17:ff9d1e86ad5f 5578 {
sPymbed 17:ff9d1e86ad5f 5579 /* Reset state */
sPymbed 17:ff9d1e86ad5f 5580 ret = 0;
sPymbed 17:ff9d1e86ad5f 5581 ssl->options.asyncState = TLS_ASYNC_BEGIN;
sPymbed 17:ff9d1e86ad5f 5582 XMEMSET(args, 0, sizeof(Dcv13Args));
sPymbed 17:ff9d1e86ad5f 5583 args->hashAlgo = sha_mac;
sPymbed 17:ff9d1e86ad5f 5584 args->sigAlgo = anonymous_sa_algo;
sPymbed 17:ff9d1e86ad5f 5585 args->idx = *inOutIdx;
sPymbed 17:ff9d1e86ad5f 5586 args->begin = *inOutIdx;
sPymbed 17:ff9d1e86ad5f 5587 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 5588 ssl->async.freeArgs = FreeDcv13Args;
sPymbed 17:ff9d1e86ad5f 5589 #endif
sPymbed 17:ff9d1e86ad5f 5590 }
sPymbed 17:ff9d1e86ad5f 5591
sPymbed 17:ff9d1e86ad5f 5592 switch(ssl->options.asyncState)
sPymbed 17:ff9d1e86ad5f 5593 {
sPymbed 17:ff9d1e86ad5f 5594 case TLS_ASYNC_BEGIN:
sPymbed 17:ff9d1e86ad5f 5595 {
sPymbed 17:ff9d1e86ad5f 5596 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 5597 if (ssl->hsInfoOn) AddPacketName(ssl, "CertificateVerify");
sPymbed 17:ff9d1e86ad5f 5598 if (ssl->toInfoOn) AddLateName("CertificateVerify",
sPymbed 17:ff9d1e86ad5f 5599 &ssl->timeoutInfo);
sPymbed 17:ff9d1e86ad5f 5600 #endif
sPymbed 17:ff9d1e86ad5f 5601
sPymbed 17:ff9d1e86ad5f 5602 /* Advance state and proceed */
sPymbed 17:ff9d1e86ad5f 5603 ssl->options.asyncState = TLS_ASYNC_BUILD;
sPymbed 17:ff9d1e86ad5f 5604 } /* case TLS_ASYNC_BEGIN */
sPymbed 17:ff9d1e86ad5f 5605 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 5606
sPymbed 17:ff9d1e86ad5f 5607 case TLS_ASYNC_BUILD:
sPymbed 17:ff9d1e86ad5f 5608 {
sPymbed 17:ff9d1e86ad5f 5609 /* Signature algorithm. */
sPymbed 17:ff9d1e86ad5f 5610 if ((args->idx - args->begin) + ENUM_LEN + ENUM_LEN > totalSz) {
sPymbed 17:ff9d1e86ad5f 5611 ERROR_OUT(BUFFER_ERROR, exit_dcv);
sPymbed 17:ff9d1e86ad5f 5612 }
sPymbed 17:ff9d1e86ad5f 5613 DecodeSigAlg(input + args->idx, &args->hashAlgo, &args->sigAlgo);
sPymbed 17:ff9d1e86ad5f 5614 args->idx += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 5615
sPymbed 17:ff9d1e86ad5f 5616 /* Signature length. */
sPymbed 17:ff9d1e86ad5f 5617 if ((args->idx - args->begin) + OPAQUE16_LEN > totalSz) {
sPymbed 17:ff9d1e86ad5f 5618 ERROR_OUT(BUFFER_ERROR, exit_dcv);
sPymbed 17:ff9d1e86ad5f 5619 }
sPymbed 17:ff9d1e86ad5f 5620 ato16(input + args->idx, &args->sz);
sPymbed 17:ff9d1e86ad5f 5621 args->idx += OPAQUE16_LEN;
sPymbed 17:ff9d1e86ad5f 5622
sPymbed 17:ff9d1e86ad5f 5623 /* Signature data. */
sPymbed 17:ff9d1e86ad5f 5624 if ((args->idx - args->begin) + args->sz > totalSz ||
sPymbed 17:ff9d1e86ad5f 5625 args->sz > ENCRYPT_LEN) {
sPymbed 17:ff9d1e86ad5f 5626 ERROR_OUT(BUFFER_ERROR, exit_dcv);
sPymbed 17:ff9d1e86ad5f 5627 }
sPymbed 17:ff9d1e86ad5f 5628
sPymbed 17:ff9d1e86ad5f 5629 /* Check for public key of required type. */
sPymbed 17:ff9d1e86ad5f 5630 #ifdef HAVE_ED25519
sPymbed 17:ff9d1e86ad5f 5631 if (args->sigAlgo == ed25519_sa_algo &&
sPymbed 17:ff9d1e86ad5f 5632 !ssl->peerEd25519KeyPresent) {
sPymbed 17:ff9d1e86ad5f 5633 WOLFSSL_MSG("Oops, peer sent ED25519 key but not in verify");
sPymbed 17:ff9d1e86ad5f 5634 }
sPymbed 17:ff9d1e86ad5f 5635 #endif
sPymbed 17:ff9d1e86ad5f 5636 #ifdef HAVE_ECC
sPymbed 17:ff9d1e86ad5f 5637 if (args->sigAlgo == ecc_dsa_sa_algo &&
sPymbed 17:ff9d1e86ad5f 5638 !ssl->peerEccDsaKeyPresent) {
sPymbed 17:ff9d1e86ad5f 5639 WOLFSSL_MSG("Oops, peer sent ECC key but not in verify");
sPymbed 17:ff9d1e86ad5f 5640 }
sPymbed 17:ff9d1e86ad5f 5641 #endif
sPymbed 17:ff9d1e86ad5f 5642 #ifndef NO_RSA
sPymbed 17:ff9d1e86ad5f 5643 if ((args->sigAlgo == rsa_sa_algo ||
sPymbed 17:ff9d1e86ad5f 5644 args->sigAlgo == rsa_pss_sa_algo) &&
sPymbed 17:ff9d1e86ad5f 5645 (ssl->peerRsaKey == NULL || !ssl->peerRsaKeyPresent)) {
sPymbed 17:ff9d1e86ad5f 5646 WOLFSSL_MSG("Oops, peer sent RSA key but not in verify");
sPymbed 17:ff9d1e86ad5f 5647 }
sPymbed 17:ff9d1e86ad5f 5648 #endif
sPymbed 17:ff9d1e86ad5f 5649
sPymbed 17:ff9d1e86ad5f 5650 sig->buffer = (byte*)XMALLOC(args->sz, ssl->heap,
sPymbed 17:ff9d1e86ad5f 5651 DYNAMIC_TYPE_SIGNATURE);
sPymbed 17:ff9d1e86ad5f 5652 if (sig->buffer == NULL) {
sPymbed 17:ff9d1e86ad5f 5653 ERROR_OUT(MEMORY_E, exit_dcv);
sPymbed 17:ff9d1e86ad5f 5654 }
sPymbed 17:ff9d1e86ad5f 5655 sig->length = args->sz;
sPymbed 17:ff9d1e86ad5f 5656 XMEMCPY(sig->buffer, input + args->idx, args->sz);
sPymbed 17:ff9d1e86ad5f 5657
sPymbed 17:ff9d1e86ad5f 5658 #ifdef HAVE_ECC
sPymbed 17:ff9d1e86ad5f 5659 if (ssl->peerEccDsaKeyPresent) {
sPymbed 17:ff9d1e86ad5f 5660 WOLFSSL_MSG("Doing ECC peer cert verify");
sPymbed 17:ff9d1e86ad5f 5661
sPymbed 17:ff9d1e86ad5f 5662 args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap,
sPymbed 17:ff9d1e86ad5f 5663 DYNAMIC_TYPE_SIGNATURE);
sPymbed 17:ff9d1e86ad5f 5664 if (args->sigData == NULL) {
sPymbed 17:ff9d1e86ad5f 5665 ERROR_OUT(MEMORY_E, exit_dcv);
sPymbed 17:ff9d1e86ad5f 5666 }
sPymbed 17:ff9d1e86ad5f 5667
sPymbed 17:ff9d1e86ad5f 5668 ret = CreateSigData(ssl, args->sigData, &args->sigDataSz, 1);
sPymbed 17:ff9d1e86ad5f 5669 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 5670 goto exit_dcv;
sPymbed 17:ff9d1e86ad5f 5671 ret = CreateECCEncodedSig(args->sigData,
sPymbed 17:ff9d1e86ad5f 5672 args->sigDataSz, args->hashAlgo);
sPymbed 17:ff9d1e86ad5f 5673 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 5674 goto exit_dcv;
sPymbed 17:ff9d1e86ad5f 5675 args->sigDataSz = (word16)ret;
sPymbed 17:ff9d1e86ad5f 5676 ret = 0;
sPymbed 17:ff9d1e86ad5f 5677 }
sPymbed 17:ff9d1e86ad5f 5678 #endif
sPymbed 17:ff9d1e86ad5f 5679 #ifdef HAVE_ED25519
sPymbed 17:ff9d1e86ad5f 5680 if (ssl->peerEd25519KeyPresent) {
sPymbed 17:ff9d1e86ad5f 5681 WOLFSSL_MSG("Doing ED25519 peer cert verify");
sPymbed 17:ff9d1e86ad5f 5682
sPymbed 17:ff9d1e86ad5f 5683 args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap,
sPymbed 17:ff9d1e86ad5f 5684 DYNAMIC_TYPE_SIGNATURE);
sPymbed 17:ff9d1e86ad5f 5685 if (args->sigData == NULL) {
sPymbed 17:ff9d1e86ad5f 5686 ERROR_OUT(MEMORY_E, exit_dcv);
sPymbed 17:ff9d1e86ad5f 5687 }
sPymbed 17:ff9d1e86ad5f 5688
sPymbed 17:ff9d1e86ad5f 5689 CreateSigData(ssl, args->sigData, &args->sigDataSz, 1);
sPymbed 17:ff9d1e86ad5f 5690 ret = 0;
sPymbed 17:ff9d1e86ad5f 5691 }
sPymbed 17:ff9d1e86ad5f 5692 #endif
sPymbed 17:ff9d1e86ad5f 5693
sPymbed 17:ff9d1e86ad5f 5694 /* Advance state and proceed */
sPymbed 17:ff9d1e86ad5f 5695 ssl->options.asyncState = TLS_ASYNC_DO;
sPymbed 17:ff9d1e86ad5f 5696 } /* case TLS_ASYNC_BUILD */
sPymbed 17:ff9d1e86ad5f 5697 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 5698
sPymbed 17:ff9d1e86ad5f 5699 case TLS_ASYNC_DO:
sPymbed 17:ff9d1e86ad5f 5700 {
sPymbed 17:ff9d1e86ad5f 5701 #ifndef NO_RSA
sPymbed 17:ff9d1e86ad5f 5702 if (args->sigAlgo == rsa_sa_algo ||
sPymbed 17:ff9d1e86ad5f 5703 args->sigAlgo == rsa_pss_sa_algo) {
sPymbed 17:ff9d1e86ad5f 5704 WOLFSSL_MSG("Doing RSA peer cert verify");
sPymbed 17:ff9d1e86ad5f 5705
sPymbed 17:ff9d1e86ad5f 5706 ret = RsaVerify(ssl, sig->buffer, sig->length, &args->output,
sPymbed 17:ff9d1e86ad5f 5707 args->sigAlgo, args->hashAlgo, ssl->peerRsaKey,
sPymbed 17:ff9d1e86ad5f 5708 #ifdef HAVE_PK_CALLBACKS
sPymbed 17:ff9d1e86ad5f 5709 &ssl->buffers.peerRsaKey
sPymbed 17:ff9d1e86ad5f 5710 #else
sPymbed 17:ff9d1e86ad5f 5711 NULL
sPymbed 17:ff9d1e86ad5f 5712 #endif
sPymbed 17:ff9d1e86ad5f 5713 );
sPymbed 17:ff9d1e86ad5f 5714 if (ret >= 0) {
sPymbed 17:ff9d1e86ad5f 5715 args->sendSz = ret;
sPymbed 17:ff9d1e86ad5f 5716 ret = 0;
sPymbed 17:ff9d1e86ad5f 5717 }
sPymbed 17:ff9d1e86ad5f 5718 }
sPymbed 17:ff9d1e86ad5f 5719 #endif /* !NO_RSA */
sPymbed 17:ff9d1e86ad5f 5720 #ifdef HAVE_ECC
sPymbed 17:ff9d1e86ad5f 5721 if (ssl->peerEccDsaKeyPresent) {
sPymbed 17:ff9d1e86ad5f 5722 WOLFSSL_MSG("Doing ECC peer cert verify");
sPymbed 17:ff9d1e86ad5f 5723
sPymbed 17:ff9d1e86ad5f 5724 ret = EccVerify(ssl, input + args->idx, args->sz,
sPymbed 17:ff9d1e86ad5f 5725 args->sigData, args->sigDataSz,
sPymbed 17:ff9d1e86ad5f 5726 ssl->peerEccDsaKey,
sPymbed 17:ff9d1e86ad5f 5727 #ifdef HAVE_PK_CALLBACKS
sPymbed 17:ff9d1e86ad5f 5728 &ssl->buffers.peerEccDsaKey
sPymbed 17:ff9d1e86ad5f 5729 #else
sPymbed 17:ff9d1e86ad5f 5730 NULL
sPymbed 17:ff9d1e86ad5f 5731 #endif
sPymbed 17:ff9d1e86ad5f 5732 );
sPymbed 17:ff9d1e86ad5f 5733 }
sPymbed 17:ff9d1e86ad5f 5734 #endif /* HAVE_ECC */
sPymbed 17:ff9d1e86ad5f 5735 #ifdef HAVE_ED25519
sPymbed 17:ff9d1e86ad5f 5736 if (ssl->peerEd25519KeyPresent) {
sPymbed 17:ff9d1e86ad5f 5737 WOLFSSL_MSG("Doing ED25519 peer cert verify");
sPymbed 17:ff9d1e86ad5f 5738
sPymbed 17:ff9d1e86ad5f 5739 ret = Ed25519Verify(ssl, input + args->idx, args->sz,
sPymbed 17:ff9d1e86ad5f 5740 args->sigData, args->sigDataSz,
sPymbed 17:ff9d1e86ad5f 5741 ssl->peerEd25519Key,
sPymbed 17:ff9d1e86ad5f 5742 #ifdef HAVE_PK_CALLBACKS
sPymbed 17:ff9d1e86ad5f 5743 &ssl->buffers.peerEd25519Key
sPymbed 17:ff9d1e86ad5f 5744 #else
sPymbed 17:ff9d1e86ad5f 5745 NULL
sPymbed 17:ff9d1e86ad5f 5746 #endif
sPymbed 17:ff9d1e86ad5f 5747 );
sPymbed 17:ff9d1e86ad5f 5748 }
sPymbed 17:ff9d1e86ad5f 5749 #endif
sPymbed 17:ff9d1e86ad5f 5750
sPymbed 17:ff9d1e86ad5f 5751 /* Check for error */
sPymbed 17:ff9d1e86ad5f 5752 if (ret != 0) {
sPymbed 17:ff9d1e86ad5f 5753 goto exit_dcv;
sPymbed 17:ff9d1e86ad5f 5754 }
sPymbed 17:ff9d1e86ad5f 5755
sPymbed 17:ff9d1e86ad5f 5756 /* Advance state and proceed */
sPymbed 17:ff9d1e86ad5f 5757 ssl->options.asyncState = TLS_ASYNC_VERIFY;
sPymbed 17:ff9d1e86ad5f 5758 } /* case TLS_ASYNC_DO */
sPymbed 17:ff9d1e86ad5f 5759 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 5760
sPymbed 17:ff9d1e86ad5f 5761 case TLS_ASYNC_VERIFY:
sPymbed 17:ff9d1e86ad5f 5762 {
sPymbed 17:ff9d1e86ad5f 5763 #ifndef NO_RSA
sPymbed 17:ff9d1e86ad5f 5764 if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) {
sPymbed 17:ff9d1e86ad5f 5765 ret = CheckRSASignature(ssl, args->sigAlgo, args->hashAlgo,
sPymbed 17:ff9d1e86ad5f 5766 args->output, args->sendSz);
sPymbed 17:ff9d1e86ad5f 5767 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 5768 goto exit_dcv;
sPymbed 17:ff9d1e86ad5f 5769 }
sPymbed 17:ff9d1e86ad5f 5770 #endif /* !NO_RSA */
sPymbed 17:ff9d1e86ad5f 5771
sPymbed 17:ff9d1e86ad5f 5772 /* Advance state and proceed */
sPymbed 17:ff9d1e86ad5f 5773 ssl->options.asyncState = TLS_ASYNC_FINALIZE;
sPymbed 17:ff9d1e86ad5f 5774 } /* case TLS_ASYNC_VERIFY */
sPymbed 17:ff9d1e86ad5f 5775 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 5776
sPymbed 17:ff9d1e86ad5f 5777 case TLS_ASYNC_FINALIZE:
sPymbed 17:ff9d1e86ad5f 5778 {
sPymbed 17:ff9d1e86ad5f 5779 ssl->options.havePeerVerify = 1;
sPymbed 17:ff9d1e86ad5f 5780
sPymbed 17:ff9d1e86ad5f 5781 /* Set final index */
sPymbed 17:ff9d1e86ad5f 5782 args->idx += args->sz;
sPymbed 17:ff9d1e86ad5f 5783 *inOutIdx = args->idx;
sPymbed 17:ff9d1e86ad5f 5784
sPymbed 17:ff9d1e86ad5f 5785 /* Encryption is always on: add padding */
sPymbed 17:ff9d1e86ad5f 5786 *inOutIdx += ssl->keys.padSz;
sPymbed 17:ff9d1e86ad5f 5787
sPymbed 17:ff9d1e86ad5f 5788 /* Advance state and proceed */
sPymbed 17:ff9d1e86ad5f 5789 ssl->options.asyncState = TLS_ASYNC_END;
sPymbed 17:ff9d1e86ad5f 5790 } /* case TLS_ASYNC_FINALIZE */
sPymbed 17:ff9d1e86ad5f 5791
sPymbed 17:ff9d1e86ad5f 5792 case TLS_ASYNC_END:
sPymbed 17:ff9d1e86ad5f 5793 {
sPymbed 17:ff9d1e86ad5f 5794 break;
sPymbed 17:ff9d1e86ad5f 5795 }
sPymbed 17:ff9d1e86ad5f 5796 default:
sPymbed 17:ff9d1e86ad5f 5797 ret = INPUT_CASE_ERROR;
sPymbed 17:ff9d1e86ad5f 5798 } /* switch(ssl->options.asyncState) */
sPymbed 17:ff9d1e86ad5f 5799
sPymbed 17:ff9d1e86ad5f 5800 exit_dcv:
sPymbed 17:ff9d1e86ad5f 5801
sPymbed 17:ff9d1e86ad5f 5802 WOLFSSL_LEAVE("DoTls13CertificateVerify", ret);
sPymbed 17:ff9d1e86ad5f 5803 WOLFSSL_END(WC_FUNC_CERTIFICATE_VERIFY_DO);
sPymbed 17:ff9d1e86ad5f 5804
sPymbed 17:ff9d1e86ad5f 5805 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 5806 /* Handle async operation */
sPymbed 17:ff9d1e86ad5f 5807 if (ret == WC_PENDING_E) {
sPymbed 17:ff9d1e86ad5f 5808 /* Mark message as not recevied so it can process again */
sPymbed 17:ff9d1e86ad5f 5809 ssl->msgsReceived.got_certificate_verify = 0;
sPymbed 17:ff9d1e86ad5f 5810
sPymbed 17:ff9d1e86ad5f 5811 return ret;
sPymbed 17:ff9d1e86ad5f 5812 }
sPymbed 17:ff9d1e86ad5f 5813 else
sPymbed 17:ff9d1e86ad5f 5814 #endif /* WOLFSSL_ASYNC_CRYPT */
sPymbed 17:ff9d1e86ad5f 5815 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 5816 SendAlert(ssl, alert_fatal, decrypt_error);
sPymbed 17:ff9d1e86ad5f 5817
sPymbed 17:ff9d1e86ad5f 5818 /* Final cleanup */
sPymbed 17:ff9d1e86ad5f 5819 FreeDcv13Args(ssl, args);
sPymbed 17:ff9d1e86ad5f 5820 FreeKeyExchange(ssl);
sPymbed 17:ff9d1e86ad5f 5821
sPymbed 17:ff9d1e86ad5f 5822 return ret;
sPymbed 17:ff9d1e86ad5f 5823 }
sPymbed 17:ff9d1e86ad5f 5824 #endif /* !NO_RSA || HAVE_ECC */
sPymbed 17:ff9d1e86ad5f 5825
sPymbed 17:ff9d1e86ad5f 5826 /* Parse and handle a TLS v1.3 Finished message.
sPymbed 17:ff9d1e86ad5f 5827 *
sPymbed 17:ff9d1e86ad5f 5828 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 5829 * input The message buffer.
sPymbed 17:ff9d1e86ad5f 5830 * inOutIdx On entry, the index into the message buffer of Finished.
sPymbed 17:ff9d1e86ad5f 5831 * On exit, the index of byte after the Finished message and padding.
sPymbed 17:ff9d1e86ad5f 5832 * size Length of message data.
sPymbed 17:ff9d1e86ad5f 5833 * totalSz Length of remaining data in the message buffer.
sPymbed 17:ff9d1e86ad5f 5834 * sniff Indicates whether we are sniffing packets.
sPymbed 17:ff9d1e86ad5f 5835 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 5836 */
sPymbed 17:ff9d1e86ad5f 5837 static int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
sPymbed 17:ff9d1e86ad5f 5838 word32 size, word32 totalSz, int sniff)
sPymbed 17:ff9d1e86ad5f 5839 {
sPymbed 17:ff9d1e86ad5f 5840 int ret;
sPymbed 17:ff9d1e86ad5f 5841 word32 finishedSz = 0;
sPymbed 17:ff9d1e86ad5f 5842 byte* secret;
sPymbed 17:ff9d1e86ad5f 5843 byte mac[WC_MAX_DIGEST_SIZE];
sPymbed 17:ff9d1e86ad5f 5844
sPymbed 17:ff9d1e86ad5f 5845 WOLFSSL_START(WC_FUNC_FINISHED_DO);
sPymbed 17:ff9d1e86ad5f 5846 WOLFSSL_ENTER("DoTls13Finished");
sPymbed 17:ff9d1e86ad5f 5847
sPymbed 17:ff9d1e86ad5f 5848 /* check against totalSz */
sPymbed 17:ff9d1e86ad5f 5849 if (*inOutIdx + size + ssl->keys.padSz > totalSz)
sPymbed 17:ff9d1e86ad5f 5850 return BUFFER_E;
sPymbed 17:ff9d1e86ad5f 5851
sPymbed 17:ff9d1e86ad5f 5852 if (ssl->options.handShakeDone) {
sPymbed 17:ff9d1e86ad5f 5853 ret = DeriveFinishedSecret(ssl, ssl->arrays->clientSecret,
sPymbed 17:ff9d1e86ad5f 5854 ssl->keys.client_write_MAC_secret);
sPymbed 17:ff9d1e86ad5f 5855 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 5856 return ret;
sPymbed 17:ff9d1e86ad5f 5857
sPymbed 17:ff9d1e86ad5f 5858 secret = ssl->keys.client_write_MAC_secret;
sPymbed 17:ff9d1e86ad5f 5859 }
sPymbed 17:ff9d1e86ad5f 5860 else if (ssl->options.side == WOLFSSL_CLIENT_END) {
sPymbed 17:ff9d1e86ad5f 5861 /* All the handshake messages have been received to calculate
sPymbed 17:ff9d1e86ad5f 5862 * client and server finished keys.
sPymbed 17:ff9d1e86ad5f 5863 */
sPymbed 17:ff9d1e86ad5f 5864 ret = DeriveFinishedSecret(ssl, ssl->arrays->clientSecret,
sPymbed 17:ff9d1e86ad5f 5865 ssl->keys.client_write_MAC_secret);
sPymbed 17:ff9d1e86ad5f 5866 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 5867 return ret;
sPymbed 17:ff9d1e86ad5f 5868
sPymbed 17:ff9d1e86ad5f 5869 ret = DeriveFinishedSecret(ssl, ssl->arrays->serverSecret,
sPymbed 17:ff9d1e86ad5f 5870 ssl->keys.server_write_MAC_secret);
sPymbed 17:ff9d1e86ad5f 5871 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 5872 return ret;
sPymbed 17:ff9d1e86ad5f 5873
sPymbed 17:ff9d1e86ad5f 5874 secret = ssl->keys.server_write_MAC_secret;
sPymbed 17:ff9d1e86ad5f 5875 }
sPymbed 17:ff9d1e86ad5f 5876 else
sPymbed 17:ff9d1e86ad5f 5877 secret = ssl->keys.client_write_MAC_secret;
sPymbed 17:ff9d1e86ad5f 5878
sPymbed 17:ff9d1e86ad5f 5879 ret = BuildTls13HandshakeHmac(ssl, secret, mac, &finishedSz);
sPymbed 17:ff9d1e86ad5f 5880 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 5881 return ret;
sPymbed 17:ff9d1e86ad5f 5882 if (size != finishedSz)
sPymbed 17:ff9d1e86ad5f 5883 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 5884
sPymbed 17:ff9d1e86ad5f 5885 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 5886 if (ssl->hsInfoOn) AddPacketName(ssl, "Finished");
sPymbed 17:ff9d1e86ad5f 5887 if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
sPymbed 17:ff9d1e86ad5f 5888 #endif
sPymbed 17:ff9d1e86ad5f 5889
sPymbed 17:ff9d1e86ad5f 5890 if (sniff == NO_SNIFF) {
sPymbed 17:ff9d1e86ad5f 5891 /* Actually check verify data. */
sPymbed 17:ff9d1e86ad5f 5892 if (XMEMCMP(input + *inOutIdx, mac, size) != 0){
sPymbed 17:ff9d1e86ad5f 5893 WOLFSSL_MSG("Verify finished error on hashes");
sPymbed 17:ff9d1e86ad5f 5894 SendAlert(ssl, alert_fatal, decrypt_error);
sPymbed 17:ff9d1e86ad5f 5895 return VERIFY_FINISHED_ERROR;
sPymbed 17:ff9d1e86ad5f 5896 }
sPymbed 17:ff9d1e86ad5f 5897 }
sPymbed 17:ff9d1e86ad5f 5898
sPymbed 17:ff9d1e86ad5f 5899 /* Force input exhaustion at ProcessReply by consuming padSz. */
sPymbed 17:ff9d1e86ad5f 5900 *inOutIdx += size + ssl->keys.padSz;
sPymbed 17:ff9d1e86ad5f 5901
sPymbed 17:ff9d1e86ad5f 5902 if (ssl->options.side == WOLFSSL_SERVER_END &&
sPymbed 17:ff9d1e86ad5f 5903 !ssl->options.handShakeDone) {
sPymbed 17:ff9d1e86ad5f 5904 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 5905 if (ssl->earlyData != no_early_data) {
sPymbed 17:ff9d1e86ad5f 5906 if ((ret = DeriveTls13Keys(ssl, no_key, DECRYPT_SIDE_ONLY, 1)) != 0)
sPymbed 17:ff9d1e86ad5f 5907 return ret;
sPymbed 17:ff9d1e86ad5f 5908 }
sPymbed 17:ff9d1e86ad5f 5909 #endif
sPymbed 17:ff9d1e86ad5f 5910 /* Setup keys for application data messages from client. */
sPymbed 17:ff9d1e86ad5f 5911 if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
sPymbed 17:ff9d1e86ad5f 5912 return ret;
sPymbed 17:ff9d1e86ad5f 5913 }
sPymbed 17:ff9d1e86ad5f 5914
sPymbed 17:ff9d1e86ad5f 5915 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 5916 if (ssl->options.side == WOLFSSL_CLIENT_END)
sPymbed 17:ff9d1e86ad5f 5917 ssl->options.serverState = SERVER_FINISHED_COMPLETE;
sPymbed 17:ff9d1e86ad5f 5918 #endif
sPymbed 17:ff9d1e86ad5f 5919 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 5920 if (ssl->options.side == WOLFSSL_SERVER_END) {
sPymbed 17:ff9d1e86ad5f 5921 ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
sPymbed 17:ff9d1e86ad5f 5922 ssl->options.handShakeState = HANDSHAKE_DONE;
sPymbed 17:ff9d1e86ad5f 5923 ssl->options.handShakeDone = 1;
sPymbed 17:ff9d1e86ad5f 5924 }
sPymbed 17:ff9d1e86ad5f 5925 #endif
sPymbed 17:ff9d1e86ad5f 5926
sPymbed 17:ff9d1e86ad5f 5927 WOLFSSL_LEAVE("DoTls13Finished", 0);
sPymbed 17:ff9d1e86ad5f 5928 WOLFSSL_END(WC_FUNC_FINISHED_DO);
sPymbed 17:ff9d1e86ad5f 5929
sPymbed 17:ff9d1e86ad5f 5930 return 0;
sPymbed 17:ff9d1e86ad5f 5931 }
sPymbed 17:ff9d1e86ad5f 5932 #endif /* NO_CERTS */
sPymbed 17:ff9d1e86ad5f 5933
sPymbed 17:ff9d1e86ad5f 5934 /* Send the TLS v1.3 Finished message.
sPymbed 17:ff9d1e86ad5f 5935 *
sPymbed 17:ff9d1e86ad5f 5936 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 5937 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 5938 */
sPymbed 17:ff9d1e86ad5f 5939 static int SendTls13Finished(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 5940 {
sPymbed 17:ff9d1e86ad5f 5941 int sendSz;
sPymbed 17:ff9d1e86ad5f 5942 int finishedSz = ssl->specs.hash_size;
sPymbed 17:ff9d1e86ad5f 5943 byte* input;
sPymbed 17:ff9d1e86ad5f 5944 byte* output;
sPymbed 17:ff9d1e86ad5f 5945 int ret;
sPymbed 17:ff9d1e86ad5f 5946 int headerSz = HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 5947 int outputSz;
sPymbed 17:ff9d1e86ad5f 5948 byte* secret;
sPymbed 17:ff9d1e86ad5f 5949
sPymbed 17:ff9d1e86ad5f 5950 WOLFSSL_START(WC_FUNC_FINISHED_SEND);
sPymbed 17:ff9d1e86ad5f 5951 WOLFSSL_ENTER("SendTls13Finished");
sPymbed 17:ff9d1e86ad5f 5952
sPymbed 17:ff9d1e86ad5f 5953 outputSz = WC_MAX_DIGEST_SIZE + DTLS_HANDSHAKE_HEADER_SZ + MAX_MSG_EXTRA;
sPymbed 17:ff9d1e86ad5f 5954 /* Check buffers are big enough and grow if needed. */
sPymbed 17:ff9d1e86ad5f 5955 if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
sPymbed 17:ff9d1e86ad5f 5956 return ret;
sPymbed 17:ff9d1e86ad5f 5957
sPymbed 17:ff9d1e86ad5f 5958 /* get output buffer */
sPymbed 17:ff9d1e86ad5f 5959 output = ssl->buffers.outputBuffer.buffer +
sPymbed 17:ff9d1e86ad5f 5960 ssl->buffers.outputBuffer.length;
sPymbed 17:ff9d1e86ad5f 5961 input = output + RECORD_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 5962
sPymbed 17:ff9d1e86ad5f 5963 AddTls13HandShakeHeader(input, finishedSz, 0, finishedSz, finished, ssl);
sPymbed 17:ff9d1e86ad5f 5964
sPymbed 17:ff9d1e86ad5f 5965 /* make finished hashes */
sPymbed 17:ff9d1e86ad5f 5966 if (ssl->options.handShakeDone) {
sPymbed 17:ff9d1e86ad5f 5967 ret = DeriveFinishedSecret(ssl, ssl->arrays->clientSecret,
sPymbed 17:ff9d1e86ad5f 5968 ssl->keys.client_write_MAC_secret);
sPymbed 17:ff9d1e86ad5f 5969 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 5970 return ret;
sPymbed 17:ff9d1e86ad5f 5971
sPymbed 17:ff9d1e86ad5f 5972 secret = ssl->keys.client_write_MAC_secret;
sPymbed 17:ff9d1e86ad5f 5973 }
sPymbed 17:ff9d1e86ad5f 5974 else if (ssl->options.side == WOLFSSL_CLIENT_END)
sPymbed 17:ff9d1e86ad5f 5975 secret = ssl->keys.client_write_MAC_secret;
sPymbed 17:ff9d1e86ad5f 5976 else {
sPymbed 17:ff9d1e86ad5f 5977 /* All the handshake messages have been done to calculate client and
sPymbed 17:ff9d1e86ad5f 5978 * server finished keys.
sPymbed 17:ff9d1e86ad5f 5979 */
sPymbed 17:ff9d1e86ad5f 5980 ret = DeriveFinishedSecret(ssl, ssl->arrays->clientSecret,
sPymbed 17:ff9d1e86ad5f 5981 ssl->keys.client_write_MAC_secret);
sPymbed 17:ff9d1e86ad5f 5982 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 5983 return ret;
sPymbed 17:ff9d1e86ad5f 5984
sPymbed 17:ff9d1e86ad5f 5985 ret = DeriveFinishedSecret(ssl, ssl->arrays->serverSecret,
sPymbed 17:ff9d1e86ad5f 5986 ssl->keys.server_write_MAC_secret);
sPymbed 17:ff9d1e86ad5f 5987 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 5988 return ret;
sPymbed 17:ff9d1e86ad5f 5989
sPymbed 17:ff9d1e86ad5f 5990 secret = ssl->keys.server_write_MAC_secret;
sPymbed 17:ff9d1e86ad5f 5991 }
sPymbed 17:ff9d1e86ad5f 5992 ret = BuildTls13HandshakeHmac(ssl, secret, &input[headerSz], NULL);
sPymbed 17:ff9d1e86ad5f 5993 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 5994 return ret;
sPymbed 17:ff9d1e86ad5f 5995
sPymbed 17:ff9d1e86ad5f 5996 /* This message is always encrypted. */
sPymbed 17:ff9d1e86ad5f 5997 sendSz = BuildTls13Message(ssl, output, outputSz, input,
sPymbed 17:ff9d1e86ad5f 5998 headerSz + finishedSz, handshake, 1, 0, 0);
sPymbed 17:ff9d1e86ad5f 5999 if (sendSz < 0)
sPymbed 17:ff9d1e86ad5f 6000 return BUILD_MSG_ERROR;
sPymbed 17:ff9d1e86ad5f 6001
sPymbed 17:ff9d1e86ad5f 6002 if (!ssl->options.resuming) {
sPymbed 17:ff9d1e86ad5f 6003 #ifndef NO_SESSION_CACHE
sPymbed 17:ff9d1e86ad5f 6004 AddSession(ssl); /* just try */
sPymbed 17:ff9d1e86ad5f 6005 #endif
sPymbed 17:ff9d1e86ad5f 6006 }
sPymbed 17:ff9d1e86ad5f 6007
sPymbed 17:ff9d1e86ad5f 6008 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 6009 if (ssl->hsInfoOn) AddPacketName(ssl, "Finished");
sPymbed 17:ff9d1e86ad5f 6010 if (ssl->toInfoOn) {
sPymbed 17:ff9d1e86ad5f 6011 AddPacketInfo(ssl, "Finished", handshake, output, sendSz,
sPymbed 17:ff9d1e86ad5f 6012 WRITE_PROTO, ssl->heap);
sPymbed 17:ff9d1e86ad5f 6013 }
sPymbed 17:ff9d1e86ad5f 6014 #endif
sPymbed 17:ff9d1e86ad5f 6015
sPymbed 17:ff9d1e86ad5f 6016 ssl->buffers.outputBuffer.length += sendSz;
sPymbed 17:ff9d1e86ad5f 6017
sPymbed 17:ff9d1e86ad5f 6018 if (ssl->options.side == WOLFSSL_SERVER_END) {
sPymbed 17:ff9d1e86ad5f 6019 /* Can send application data now. */
sPymbed 17:ff9d1e86ad5f 6020 if ((ret = DeriveMasterSecret(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 6021 return ret;
sPymbed 17:ff9d1e86ad5f 6022 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 6023 if ((ret = DeriveTls13Keys(ssl, traffic_key, ENCRYPT_SIDE_ONLY, 1))
sPymbed 17:ff9d1e86ad5f 6024 != 0) {
sPymbed 17:ff9d1e86ad5f 6025 return ret;
sPymbed 17:ff9d1e86ad5f 6026 }
sPymbed 17:ff9d1e86ad5f 6027 if ((ret = DeriveTls13Keys(ssl, traffic_key, DECRYPT_SIDE_ONLY,
sPymbed 17:ff9d1e86ad5f 6028 ssl->earlyData == no_early_data)) != 0) {
sPymbed 17:ff9d1e86ad5f 6029 return ret;
sPymbed 17:ff9d1e86ad5f 6030 }
sPymbed 17:ff9d1e86ad5f 6031 #else
sPymbed 17:ff9d1e86ad5f 6032 if ((ret = DeriveTls13Keys(ssl, traffic_key, ENCRYPT_AND_DECRYPT_SIDE,
sPymbed 17:ff9d1e86ad5f 6033 1)) != 0) {
sPymbed 17:ff9d1e86ad5f 6034 return ret;
sPymbed 17:ff9d1e86ad5f 6035 }
sPymbed 17:ff9d1e86ad5f 6036 #endif
sPymbed 17:ff9d1e86ad5f 6037 if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
sPymbed 17:ff9d1e86ad5f 6038 return ret;
sPymbed 17:ff9d1e86ad5f 6039 }
sPymbed 17:ff9d1e86ad5f 6040
sPymbed 17:ff9d1e86ad5f 6041 if (ssl->options.side == WOLFSSL_CLIENT_END &&
sPymbed 17:ff9d1e86ad5f 6042 !ssl->options.handShakeDone) {
sPymbed 17:ff9d1e86ad5f 6043 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 6044 if (ssl->earlyData != no_early_data) {
sPymbed 17:ff9d1e86ad5f 6045 if ((ret = DeriveTls13Keys(ssl, no_key, ENCRYPT_AND_DECRYPT_SIDE,
sPymbed 17:ff9d1e86ad5f 6046 1)) != 0) {
sPymbed 17:ff9d1e86ad5f 6047 return ret;
sPymbed 17:ff9d1e86ad5f 6048 }
sPymbed 17:ff9d1e86ad5f 6049 }
sPymbed 17:ff9d1e86ad5f 6050 #endif
sPymbed 17:ff9d1e86ad5f 6051 /* Setup keys for application data messages. */
sPymbed 17:ff9d1e86ad5f 6052 if ((ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE)) != 0)
sPymbed 17:ff9d1e86ad5f 6053 return ret;
sPymbed 17:ff9d1e86ad5f 6054
sPymbed 17:ff9d1e86ad5f 6055 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 6056 ret = DeriveResumptionSecret(ssl, ssl->session.masterSecret);
sPymbed 17:ff9d1e86ad5f 6057 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 6058 return ret;
sPymbed 17:ff9d1e86ad5f 6059 #endif
sPymbed 17:ff9d1e86ad5f 6060 }
sPymbed 17:ff9d1e86ad5f 6061
sPymbed 17:ff9d1e86ad5f 6062 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 6063 if (ssl->options.side == WOLFSSL_CLIENT_END) {
sPymbed 17:ff9d1e86ad5f 6064 ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
sPymbed 17:ff9d1e86ad5f 6065 ssl->options.handShakeState = HANDSHAKE_DONE;
sPymbed 17:ff9d1e86ad5f 6066 ssl->options.handShakeDone = 1;
sPymbed 17:ff9d1e86ad5f 6067 }
sPymbed 17:ff9d1e86ad5f 6068 #endif
sPymbed 17:ff9d1e86ad5f 6069 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 6070 if (ssl->options.side == WOLFSSL_SERVER_END) {
sPymbed 17:ff9d1e86ad5f 6071 ssl->options.serverState = SERVER_FINISHED_COMPLETE;
sPymbed 17:ff9d1e86ad5f 6072 }
sPymbed 17:ff9d1e86ad5f 6073 #endif
sPymbed 17:ff9d1e86ad5f 6074
sPymbed 17:ff9d1e86ad5f 6075 if ((ret = SendBuffered(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 6076 return ret;
sPymbed 17:ff9d1e86ad5f 6077
sPymbed 17:ff9d1e86ad5f 6078 WOLFSSL_LEAVE("SendTls13Finished", ret);
sPymbed 17:ff9d1e86ad5f 6079 WOLFSSL_END(WC_FUNC_FINISHED_SEND);
sPymbed 17:ff9d1e86ad5f 6080
sPymbed 17:ff9d1e86ad5f 6081 return ret;
sPymbed 17:ff9d1e86ad5f 6082 }
sPymbed 17:ff9d1e86ad5f 6083
sPymbed 17:ff9d1e86ad5f 6084 /* handle generation TLS v1.3 key_update (24) */
sPymbed 17:ff9d1e86ad5f 6085 /* Send the TLS v1.3 KeyUpdate message.
sPymbed 17:ff9d1e86ad5f 6086 *
sPymbed 17:ff9d1e86ad5f 6087 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 6088 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 6089 */
sPymbed 17:ff9d1e86ad5f 6090 static int SendTls13KeyUpdate(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 6091 {
sPymbed 17:ff9d1e86ad5f 6092 int sendSz;
sPymbed 17:ff9d1e86ad5f 6093 byte* input;
sPymbed 17:ff9d1e86ad5f 6094 byte* output;
sPymbed 17:ff9d1e86ad5f 6095 int ret;
sPymbed 17:ff9d1e86ad5f 6096 int headerSz = HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 6097 int outputSz;
sPymbed 17:ff9d1e86ad5f 6098 word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 6099
sPymbed 17:ff9d1e86ad5f 6100 WOLFSSL_START(WC_FUNC_KEY_UPDATE_SEND);
sPymbed 17:ff9d1e86ad5f 6101 WOLFSSL_ENTER("SendTls13KeyUpdate");
sPymbed 17:ff9d1e86ad5f 6102
sPymbed 17:ff9d1e86ad5f 6103 outputSz = OPAQUE8_LEN + MAX_MSG_EXTRA;
sPymbed 17:ff9d1e86ad5f 6104 /* Check buffers are big enough and grow if needed. */
sPymbed 17:ff9d1e86ad5f 6105 if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
sPymbed 17:ff9d1e86ad5f 6106 return ret;
sPymbed 17:ff9d1e86ad5f 6107
sPymbed 17:ff9d1e86ad5f 6108 /* get output buffer */
sPymbed 17:ff9d1e86ad5f 6109 output = ssl->buffers.outputBuffer.buffer +
sPymbed 17:ff9d1e86ad5f 6110 ssl->buffers.outputBuffer.length;
sPymbed 17:ff9d1e86ad5f 6111 input = output + RECORD_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 6112
sPymbed 17:ff9d1e86ad5f 6113 AddTls13Headers(output, OPAQUE8_LEN, key_update, ssl);
sPymbed 17:ff9d1e86ad5f 6114
sPymbed 17:ff9d1e86ad5f 6115 /* If:
sPymbed 17:ff9d1e86ad5f 6116 * 1. I haven't sent a KeyUpdate requesting a response and
sPymbed 17:ff9d1e86ad5f 6117 * 2. This isn't responding to peer KeyUpdate requiring a response then,
sPymbed 17:ff9d1e86ad5f 6118 * I want a response.
sPymbed 17:ff9d1e86ad5f 6119 */
sPymbed 17:ff9d1e86ad5f 6120 ssl->keys.updateResponseReq = output[i++] =
sPymbed 17:ff9d1e86ad5f 6121 !ssl->keys.updateResponseReq && !ssl->keys.keyUpdateRespond;
sPymbed 17:ff9d1e86ad5f 6122 /* Sent response, no longer need to respond. */
sPymbed 17:ff9d1e86ad5f 6123 ssl->keys.keyUpdateRespond = 0;
sPymbed 17:ff9d1e86ad5f 6124
sPymbed 17:ff9d1e86ad5f 6125 /* This message is always encrypted. */
sPymbed 17:ff9d1e86ad5f 6126 sendSz = BuildTls13Message(ssl, output, outputSz, input,
sPymbed 17:ff9d1e86ad5f 6127 headerSz + OPAQUE8_LEN, handshake, 0, 0, 0);
sPymbed 17:ff9d1e86ad5f 6128 if (sendSz < 0)
sPymbed 17:ff9d1e86ad5f 6129 return BUILD_MSG_ERROR;
sPymbed 17:ff9d1e86ad5f 6130
sPymbed 17:ff9d1e86ad5f 6131 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 6132 if (ssl->hsInfoOn) AddPacketName(ssl, "KeyUpdate");
sPymbed 17:ff9d1e86ad5f 6133 if (ssl->toInfoOn) {
sPymbed 17:ff9d1e86ad5f 6134 AddPacketInfo(ssl, "KeyUpdate", handshake, output, sendSz,
sPymbed 17:ff9d1e86ad5f 6135 WRITE_PROTO, ssl->heap);
sPymbed 17:ff9d1e86ad5f 6136 }
sPymbed 17:ff9d1e86ad5f 6137 #endif
sPymbed 17:ff9d1e86ad5f 6138
sPymbed 17:ff9d1e86ad5f 6139 ssl->buffers.outputBuffer.length += sendSz;
sPymbed 17:ff9d1e86ad5f 6140
sPymbed 17:ff9d1e86ad5f 6141 ret = SendBuffered(ssl);
sPymbed 17:ff9d1e86ad5f 6142 if (ret != 0 && ret != WANT_WRITE)
sPymbed 17:ff9d1e86ad5f 6143 return ret;
sPymbed 17:ff9d1e86ad5f 6144
sPymbed 17:ff9d1e86ad5f 6145 /* Future traffic uses new encryption keys. */
sPymbed 17:ff9d1e86ad5f 6146 if ((ret = DeriveTls13Keys(ssl, update_traffic_key, ENCRYPT_SIDE_ONLY, 1))
sPymbed 17:ff9d1e86ad5f 6147 != 0)
sPymbed 17:ff9d1e86ad5f 6148 return ret;
sPymbed 17:ff9d1e86ad5f 6149 if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
sPymbed 17:ff9d1e86ad5f 6150 return ret;
sPymbed 17:ff9d1e86ad5f 6151
sPymbed 17:ff9d1e86ad5f 6152 WOLFSSL_LEAVE("SendTls13KeyUpdate", ret);
sPymbed 17:ff9d1e86ad5f 6153 WOLFSSL_END(WC_FUNC_KEY_UPDATE_SEND);
sPymbed 17:ff9d1e86ad5f 6154
sPymbed 17:ff9d1e86ad5f 6155 return ret;
sPymbed 17:ff9d1e86ad5f 6156 }
sPymbed 17:ff9d1e86ad5f 6157
sPymbed 17:ff9d1e86ad5f 6158 /* handle processing TLS v1.3 key_update (24) */
sPymbed 17:ff9d1e86ad5f 6159 /* Parse and handle a TLS v1.3 KeyUpdate message.
sPymbed 17:ff9d1e86ad5f 6160 *
sPymbed 17:ff9d1e86ad5f 6161 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 6162 * input The message buffer.
sPymbed 17:ff9d1e86ad5f 6163 * inOutIdx On entry, the index into the message buffer of Finished.
sPymbed 17:ff9d1e86ad5f 6164 * On exit, the index of byte after the Finished message and padding.
sPymbed 17:ff9d1e86ad5f 6165 * totalSz The length of the current handshake message.
sPymbed 17:ff9d1e86ad5f 6166 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 6167 */
sPymbed 17:ff9d1e86ad5f 6168 static int DoTls13KeyUpdate(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
sPymbed 17:ff9d1e86ad5f 6169 word32 totalSz)
sPymbed 17:ff9d1e86ad5f 6170 {
sPymbed 17:ff9d1e86ad5f 6171 int ret;
sPymbed 17:ff9d1e86ad5f 6172 word32 i = *inOutIdx;
sPymbed 17:ff9d1e86ad5f 6173
sPymbed 17:ff9d1e86ad5f 6174 WOLFSSL_START(WC_FUNC_KEY_UPDATE_DO);
sPymbed 17:ff9d1e86ad5f 6175 WOLFSSL_ENTER("DoTls13KeyUpdate");
sPymbed 17:ff9d1e86ad5f 6176
sPymbed 17:ff9d1e86ad5f 6177 /* check against totalSz */
sPymbed 17:ff9d1e86ad5f 6178 if (OPAQUE8_LEN != totalSz)
sPymbed 17:ff9d1e86ad5f 6179 return BUFFER_E;
sPymbed 17:ff9d1e86ad5f 6180
sPymbed 17:ff9d1e86ad5f 6181 switch (input[i]) {
sPymbed 17:ff9d1e86ad5f 6182 case update_not_requested:
sPymbed 17:ff9d1e86ad5f 6183 /* This message in response to any oustanding request. */
sPymbed 17:ff9d1e86ad5f 6184 ssl->keys.keyUpdateRespond = 0;
sPymbed 17:ff9d1e86ad5f 6185 ssl->keys.updateResponseReq = 0;
sPymbed 17:ff9d1e86ad5f 6186 break;
sPymbed 17:ff9d1e86ad5f 6187 case update_requested:
sPymbed 17:ff9d1e86ad5f 6188 /* New key update requiring a response. */
sPymbed 17:ff9d1e86ad5f 6189 ssl->keys.keyUpdateRespond = 1;
sPymbed 17:ff9d1e86ad5f 6190 break;
sPymbed 17:ff9d1e86ad5f 6191 default:
sPymbed 17:ff9d1e86ad5f 6192 return INVALID_PARAMETER;
sPymbed 17:ff9d1e86ad5f 6193 break;
sPymbed 17:ff9d1e86ad5f 6194 }
sPymbed 17:ff9d1e86ad5f 6195
sPymbed 17:ff9d1e86ad5f 6196 /* Move index to byte after message. */
sPymbed 17:ff9d1e86ad5f 6197 *inOutIdx += totalSz;
sPymbed 17:ff9d1e86ad5f 6198 /* Always encrypted. */
sPymbed 17:ff9d1e86ad5f 6199 *inOutIdx += ssl->keys.padSz;
sPymbed 17:ff9d1e86ad5f 6200
sPymbed 17:ff9d1e86ad5f 6201 /* Future traffic uses new decryption keys. */
sPymbed 17:ff9d1e86ad5f 6202 if ((ret = DeriveTls13Keys(ssl, update_traffic_key, DECRYPT_SIDE_ONLY, 1))
sPymbed 17:ff9d1e86ad5f 6203 != 0) {
sPymbed 17:ff9d1e86ad5f 6204 return ret;
sPymbed 17:ff9d1e86ad5f 6205 }
sPymbed 17:ff9d1e86ad5f 6206 if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
sPymbed 17:ff9d1e86ad5f 6207 return ret;
sPymbed 17:ff9d1e86ad5f 6208
sPymbed 17:ff9d1e86ad5f 6209 if (ssl->keys.keyUpdateRespond)
sPymbed 17:ff9d1e86ad5f 6210 return SendTls13KeyUpdate(ssl);
sPymbed 17:ff9d1e86ad5f 6211
sPymbed 17:ff9d1e86ad5f 6212 WOLFSSL_LEAVE("DoTls13KeyUpdate", ret);
sPymbed 17:ff9d1e86ad5f 6213 WOLFSSL_END(WC_FUNC_KEY_UPDATE_DO);
sPymbed 17:ff9d1e86ad5f 6214
sPymbed 17:ff9d1e86ad5f 6215 return 0;
sPymbed 17:ff9d1e86ad5f 6216 }
sPymbed 17:ff9d1e86ad5f 6217
sPymbed 17:ff9d1e86ad5f 6218 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 6219 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 6220 /* Send the TLS v1.3 EndOfEarlyData message to indicate that there will be no
sPymbed 17:ff9d1e86ad5f 6221 * more early application data.
sPymbed 17:ff9d1e86ad5f 6222 * The encryption key now changes to the pre-calculated handshake key.
sPymbed 17:ff9d1e86ad5f 6223 *
sPymbed 17:ff9d1e86ad5f 6224 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 6225 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 6226 */
sPymbed 17:ff9d1e86ad5f 6227 static int SendTls13EndOfEarlyData(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 6228 {
sPymbed 17:ff9d1e86ad5f 6229 byte* output;
sPymbed 17:ff9d1e86ad5f 6230 int ret;
sPymbed 17:ff9d1e86ad5f 6231 int sendSz;
sPymbed 17:ff9d1e86ad5f 6232 word32 length;
sPymbed 17:ff9d1e86ad5f 6233 word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 6234
sPymbed 17:ff9d1e86ad5f 6235 WOLFSSL_START(WC_FUNC_END_OF_EARLY_DATA_SEND);
sPymbed 17:ff9d1e86ad5f 6236 WOLFSSL_ENTER("SendTls13EndOfEarlyData");
sPymbed 17:ff9d1e86ad5f 6237
sPymbed 17:ff9d1e86ad5f 6238 length = 0;
sPymbed 17:ff9d1e86ad5f 6239 sendSz = idx + length + MAX_MSG_EXTRA;
sPymbed 17:ff9d1e86ad5f 6240
sPymbed 17:ff9d1e86ad5f 6241 /* Check buffers are big enough and grow if needed. */
sPymbed 17:ff9d1e86ad5f 6242 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
sPymbed 17:ff9d1e86ad5f 6243 return ret;
sPymbed 17:ff9d1e86ad5f 6244
sPymbed 17:ff9d1e86ad5f 6245 /* Get position in output buffer to write new message to. */
sPymbed 17:ff9d1e86ad5f 6246 output = ssl->buffers.outputBuffer.buffer +
sPymbed 17:ff9d1e86ad5f 6247 ssl->buffers.outputBuffer.length;
sPymbed 17:ff9d1e86ad5f 6248
sPymbed 17:ff9d1e86ad5f 6249 /* Put the record and handshake headers on. */
sPymbed 17:ff9d1e86ad5f 6250 AddTls13Headers(output, length, end_of_early_data, ssl);
sPymbed 17:ff9d1e86ad5f 6251
sPymbed 17:ff9d1e86ad5f 6252 /* This message is always encrypted. */
sPymbed 17:ff9d1e86ad5f 6253 sendSz = BuildTls13Message(ssl, output, sendSz, output + RECORD_HEADER_SZ,
sPymbed 17:ff9d1e86ad5f 6254 idx - RECORD_HEADER_SZ, handshake, 1, 0, 0);
sPymbed 17:ff9d1e86ad5f 6255 if (sendSz < 0)
sPymbed 17:ff9d1e86ad5f 6256 return sendSz;
sPymbed 17:ff9d1e86ad5f 6257
sPymbed 17:ff9d1e86ad5f 6258 ssl->buffers.outputBuffer.length += sendSz;
sPymbed 17:ff9d1e86ad5f 6259
sPymbed 17:ff9d1e86ad5f 6260 if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
sPymbed 17:ff9d1e86ad5f 6261 return ret;
sPymbed 17:ff9d1e86ad5f 6262
sPymbed 17:ff9d1e86ad5f 6263 if (!ssl->options.groupMessages)
sPymbed 17:ff9d1e86ad5f 6264 ret = SendBuffered(ssl);
sPymbed 17:ff9d1e86ad5f 6265
sPymbed 17:ff9d1e86ad5f 6266 WOLFSSL_LEAVE("SendTls13EndOfEarlyData", ret);
sPymbed 17:ff9d1e86ad5f 6267 WOLFSSL_END(WC_FUNC_END_OF_EARLY_DATA_SEND);
sPymbed 17:ff9d1e86ad5f 6268
sPymbed 17:ff9d1e86ad5f 6269 return ret;
sPymbed 17:ff9d1e86ad5f 6270 }
sPymbed 17:ff9d1e86ad5f 6271 #endif /* !NO_WOLFSSL_CLIENT */
sPymbed 17:ff9d1e86ad5f 6272
sPymbed 17:ff9d1e86ad5f 6273 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 6274 /* handle processing of TLS 1.3 end_of_early_data (5) */
sPymbed 17:ff9d1e86ad5f 6275 /* Parse the TLS v1.3 EndOfEarlyData message that indicates that there will be
sPymbed 17:ff9d1e86ad5f 6276 * no more early application data.
sPymbed 17:ff9d1e86ad5f 6277 * The decryption key now changes to the pre-calculated handshake key.
sPymbed 17:ff9d1e86ad5f 6278 *
sPymbed 17:ff9d1e86ad5f 6279 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 6280 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 6281 */
sPymbed 17:ff9d1e86ad5f 6282 static int DoTls13EndOfEarlyData(WOLFSSL* ssl, const byte* input,
sPymbed 17:ff9d1e86ad5f 6283 word32* inOutIdx, word32 size)
sPymbed 17:ff9d1e86ad5f 6284 {
sPymbed 17:ff9d1e86ad5f 6285 int ret;
sPymbed 17:ff9d1e86ad5f 6286 word32 begin = *inOutIdx;
sPymbed 17:ff9d1e86ad5f 6287
sPymbed 17:ff9d1e86ad5f 6288 (void)input;
sPymbed 17:ff9d1e86ad5f 6289
sPymbed 17:ff9d1e86ad5f 6290 WOLFSSL_START(WC_FUNC_END_OF_EARLY_DATA_DO);
sPymbed 17:ff9d1e86ad5f 6291 WOLFSSL_ENTER("DoTls13EndOfEarlyData");
sPymbed 17:ff9d1e86ad5f 6292
sPymbed 17:ff9d1e86ad5f 6293 if ((*inOutIdx - begin) != size)
sPymbed 17:ff9d1e86ad5f 6294 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 6295
sPymbed 17:ff9d1e86ad5f 6296 if (ssl->earlyData == no_early_data) {
sPymbed 17:ff9d1e86ad5f 6297 WOLFSSL_MSG("EndOfEarlyData recieved unexpectedly");
sPymbed 17:ff9d1e86ad5f 6298 SendAlert(ssl, alert_fatal, unexpected_message);
sPymbed 17:ff9d1e86ad5f 6299 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6300 }
sPymbed 17:ff9d1e86ad5f 6301
sPymbed 17:ff9d1e86ad5f 6302 ssl->earlyData = done_early_data;
sPymbed 17:ff9d1e86ad5f 6303
sPymbed 17:ff9d1e86ad5f 6304 /* Always encrypted. */
sPymbed 17:ff9d1e86ad5f 6305 *inOutIdx += ssl->keys.padSz;
sPymbed 17:ff9d1e86ad5f 6306
sPymbed 17:ff9d1e86ad5f 6307 ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY);
sPymbed 17:ff9d1e86ad5f 6308
sPymbed 17:ff9d1e86ad5f 6309 WOLFSSL_LEAVE("DoTls13EndOfEarlyData", ret);
sPymbed 17:ff9d1e86ad5f 6310 WOLFSSL_END(WC_FUNC_END_OF_EARLY_DATA_DO);
sPymbed 17:ff9d1e86ad5f 6311
sPymbed 17:ff9d1e86ad5f 6312 return ret;
sPymbed 17:ff9d1e86ad5f 6313 }
sPymbed 17:ff9d1e86ad5f 6314 #endif /* !NO_WOLFSSL_SERVER */
sPymbed 17:ff9d1e86ad5f 6315 #endif /* WOLFSSL_EARLY_DATA */
sPymbed 17:ff9d1e86ad5f 6316
sPymbed 17:ff9d1e86ad5f 6317 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 6318 /* Handle a New Session Ticket handshake message.
sPymbed 17:ff9d1e86ad5f 6319 * Message contains the information required to perform resumption.
sPymbed 17:ff9d1e86ad5f 6320 *
sPymbed 17:ff9d1e86ad5f 6321 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 6322 * input The message buffer.
sPymbed 17:ff9d1e86ad5f 6323 * inOutIdx On entry, the index into the message buffer of Finished.
sPymbed 17:ff9d1e86ad5f 6324 * On exit, the index of byte after the Finished message and padding.
sPymbed 17:ff9d1e86ad5f 6325 * size The length of the current handshake message.
sPymbed 17:ff9d1e86ad5f 6326 * retuns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 6327 */
sPymbed 17:ff9d1e86ad5f 6328 static int DoTls13NewSessionTicket(WOLFSSL* ssl, const byte* input,
sPymbed 17:ff9d1e86ad5f 6329 word32* inOutIdx, word32 size)
sPymbed 17:ff9d1e86ad5f 6330 {
sPymbed 17:ff9d1e86ad5f 6331 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 6332 int ret;
sPymbed 17:ff9d1e86ad5f 6333 word32 begin = *inOutIdx;
sPymbed 17:ff9d1e86ad5f 6334 word32 lifetime;
sPymbed 17:ff9d1e86ad5f 6335 word32 ageAdd;
sPymbed 17:ff9d1e86ad5f 6336 word16 length;
sPymbed 17:ff9d1e86ad5f 6337 word32 now;
sPymbed 17:ff9d1e86ad5f 6338 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 6339 const byte* nonce;
sPymbed 17:ff9d1e86ad5f 6340 byte nonceLength;
sPymbed 17:ff9d1e86ad5f 6341 #endif
sPymbed 17:ff9d1e86ad5f 6342
sPymbed 17:ff9d1e86ad5f 6343 WOLFSSL_START(WC_FUNC_NEW_SESSION_TICKET_DO);
sPymbed 17:ff9d1e86ad5f 6344 WOLFSSL_ENTER("DoTls13NewSessionTicket");
sPymbed 17:ff9d1e86ad5f 6345
sPymbed 17:ff9d1e86ad5f 6346 /* Lifetime hint. */
sPymbed 17:ff9d1e86ad5f 6347 if ((*inOutIdx - begin) + SESSION_HINT_SZ > size)
sPymbed 17:ff9d1e86ad5f 6348 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 6349 ato32(input + *inOutIdx, &lifetime);
sPymbed 17:ff9d1e86ad5f 6350 *inOutIdx += SESSION_HINT_SZ;
sPymbed 17:ff9d1e86ad5f 6351 if (lifetime > MAX_LIFETIME)
sPymbed 17:ff9d1e86ad5f 6352 return SERVER_HINT_ERROR;
sPymbed 17:ff9d1e86ad5f 6353
sPymbed 17:ff9d1e86ad5f 6354 /* Age add. */
sPymbed 17:ff9d1e86ad5f 6355 if ((*inOutIdx - begin) + SESSION_ADD_SZ > size)
sPymbed 17:ff9d1e86ad5f 6356 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 6357 ato32(input + *inOutIdx, &ageAdd);
sPymbed 17:ff9d1e86ad5f 6358 *inOutIdx += SESSION_ADD_SZ;
sPymbed 17:ff9d1e86ad5f 6359
sPymbed 17:ff9d1e86ad5f 6360 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 6361 /* Ticket nonce. */
sPymbed 17:ff9d1e86ad5f 6362 if ((*inOutIdx - begin) + 1 > size)
sPymbed 17:ff9d1e86ad5f 6363 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 6364 nonceLength = input[*inOutIdx];
sPymbed 17:ff9d1e86ad5f 6365 if (nonceLength > MAX_TICKET_NONCE_SZ) {
sPymbed 17:ff9d1e86ad5f 6366 WOLFSSL_MSG("Nonce length not supported");
sPymbed 17:ff9d1e86ad5f 6367 return INVALID_PARAMETER;
sPymbed 17:ff9d1e86ad5f 6368 }
sPymbed 17:ff9d1e86ad5f 6369 *inOutIdx += 1;
sPymbed 17:ff9d1e86ad5f 6370 if ((*inOutIdx - begin) + nonceLength > size)
sPymbed 17:ff9d1e86ad5f 6371 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 6372 nonce = input + *inOutIdx;
sPymbed 17:ff9d1e86ad5f 6373 *inOutIdx += nonceLength;
sPymbed 17:ff9d1e86ad5f 6374 #endif
sPymbed 17:ff9d1e86ad5f 6375
sPymbed 17:ff9d1e86ad5f 6376 /* Ticket length. */
sPymbed 17:ff9d1e86ad5f 6377 if ((*inOutIdx - begin) + LENGTH_SZ > size)
sPymbed 17:ff9d1e86ad5f 6378 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 6379 ato16(input + *inOutIdx, &length);
sPymbed 17:ff9d1e86ad5f 6380 *inOutIdx += LENGTH_SZ;
sPymbed 17:ff9d1e86ad5f 6381 if ((*inOutIdx - begin) + length > size)
sPymbed 17:ff9d1e86ad5f 6382 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 6383
sPymbed 17:ff9d1e86ad5f 6384 if ((ret = SetTicket(ssl, input + *inOutIdx, length)) != 0)
sPymbed 17:ff9d1e86ad5f 6385 return ret;
sPymbed 17:ff9d1e86ad5f 6386 *inOutIdx += length;
sPymbed 17:ff9d1e86ad5f 6387
sPymbed 17:ff9d1e86ad5f 6388 now = TimeNowInMilliseconds();
sPymbed 17:ff9d1e86ad5f 6389 if (now == (word32)GETTIME_ERROR)
sPymbed 17:ff9d1e86ad5f 6390 return now;
sPymbed 17:ff9d1e86ad5f 6391 /* Copy in ticket data (server identity). */
sPymbed 17:ff9d1e86ad5f 6392 ssl->timeout = lifetime;
sPymbed 17:ff9d1e86ad5f 6393 ssl->session.timeout = lifetime;
sPymbed 17:ff9d1e86ad5f 6394 ssl->session.cipherSuite0 = ssl->options.cipherSuite0;
sPymbed 17:ff9d1e86ad5f 6395 ssl->session.cipherSuite = ssl->options.cipherSuite;
sPymbed 17:ff9d1e86ad5f 6396 ssl->session.ticketSeen = now;
sPymbed 17:ff9d1e86ad5f 6397 ssl->session.ticketAdd = ageAdd;
sPymbed 17:ff9d1e86ad5f 6398 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 6399 ssl->session.maxEarlyDataSz = ssl->options.maxEarlyDataSz;
sPymbed 17:ff9d1e86ad5f 6400 #endif
sPymbed 17:ff9d1e86ad5f 6401 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 6402 ssl->session.ticketNonce.len = nonceLength;
sPymbed 17:ff9d1e86ad5f 6403 if (nonceLength > 0)
sPymbed 17:ff9d1e86ad5f 6404 XMEMCPY(&ssl->session.ticketNonce.data, nonce, nonceLength);
sPymbed 17:ff9d1e86ad5f 6405 #endif
sPymbed 17:ff9d1e86ad5f 6406 ssl->session.namedGroup = ssl->namedGroup;
sPymbed 17:ff9d1e86ad5f 6407
sPymbed 17:ff9d1e86ad5f 6408 if ((*inOutIdx - begin) + EXTS_SZ > size)
sPymbed 17:ff9d1e86ad5f 6409 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 6410 ato16(input + *inOutIdx, &length);
sPymbed 17:ff9d1e86ad5f 6411 *inOutIdx += EXTS_SZ;
sPymbed 17:ff9d1e86ad5f 6412 if ((*inOutIdx - begin) + length != size)
sPymbed 17:ff9d1e86ad5f 6413 return BUFFER_ERROR;
sPymbed 17:ff9d1e86ad5f 6414 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 6415 ret = TLSX_Parse(ssl, (byte *)input + (*inOutIdx), length, session_ticket,
sPymbed 17:ff9d1e86ad5f 6416 NULL);
sPymbed 17:ff9d1e86ad5f 6417 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 6418 return ret;
sPymbed 17:ff9d1e86ad5f 6419 #endif
sPymbed 17:ff9d1e86ad5f 6420 *inOutIdx += length;
sPymbed 17:ff9d1e86ad5f 6421
sPymbed 17:ff9d1e86ad5f 6422 #ifndef NO_SESSION_CACHE
sPymbed 17:ff9d1e86ad5f 6423 AddSession(ssl);
sPymbed 17:ff9d1e86ad5f 6424 #endif
sPymbed 17:ff9d1e86ad5f 6425
sPymbed 17:ff9d1e86ad5f 6426 /* Always encrypted. */
sPymbed 17:ff9d1e86ad5f 6427 *inOutIdx += ssl->keys.padSz;
sPymbed 17:ff9d1e86ad5f 6428
sPymbed 17:ff9d1e86ad5f 6429 ssl->expect_session_ticket = 0;
sPymbed 17:ff9d1e86ad5f 6430 #else
sPymbed 17:ff9d1e86ad5f 6431 (void)ssl;
sPymbed 17:ff9d1e86ad5f 6432 (void)input;
sPymbed 17:ff9d1e86ad5f 6433
sPymbed 17:ff9d1e86ad5f 6434 WOLFSSL_ENTER("DoTls13NewSessionTicket");
sPymbed 17:ff9d1e86ad5f 6435
sPymbed 17:ff9d1e86ad5f 6436 *inOutIdx += size + ssl->keys.padSz;
sPymbed 17:ff9d1e86ad5f 6437 #endif /* HAVE_SESSION_TICKET */
sPymbed 17:ff9d1e86ad5f 6438
sPymbed 17:ff9d1e86ad5f 6439 WOLFSSL_LEAVE("DoTls13NewSessionTicket", 0);
sPymbed 17:ff9d1e86ad5f 6440 WOLFSSL_END(WC_FUNC_NEW_SESSION_TICKET_DO);
sPymbed 17:ff9d1e86ad5f 6441
sPymbed 17:ff9d1e86ad5f 6442 return 0;
sPymbed 17:ff9d1e86ad5f 6443 }
sPymbed 17:ff9d1e86ad5f 6444 #endif /* NO_WOLFSSL_CLIENT */
sPymbed 17:ff9d1e86ad5f 6445
sPymbed 17:ff9d1e86ad5f 6446 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 6447 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 6448
sPymbed 17:ff9d1e86ad5f 6449 #ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
sPymbed 17:ff9d1e86ad5f 6450 /* Offset of the MAC size in the finished message. */
sPymbed 17:ff9d1e86ad5f 6451 #define FINISHED_MSG_SIZE_OFFSET 3
sPymbed 17:ff9d1e86ad5f 6452
sPymbed 17:ff9d1e86ad5f 6453 /* Calculate the resumption secret which includes the unseen client finished
sPymbed 17:ff9d1e86ad5f 6454 * message.
sPymbed 17:ff9d1e86ad5f 6455 *
sPymbed 17:ff9d1e86ad5f 6456 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 6457 * retuns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 6458 */
sPymbed 17:ff9d1e86ad5f 6459 static int ExpectedResumptionSecret(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 6460 {
sPymbed 17:ff9d1e86ad5f 6461 int ret;
sPymbed 17:ff9d1e86ad5f 6462 word32 finishedSz = 0;
sPymbed 17:ff9d1e86ad5f 6463 byte mac[WC_MAX_DIGEST_SIZE];
sPymbed 17:ff9d1e86ad5f 6464 Digest digest;
sPymbed 17:ff9d1e86ad5f 6465 static byte header[] = { 0x14, 0x00, 0x00, 0x00 };
sPymbed 17:ff9d1e86ad5f 6466
sPymbed 17:ff9d1e86ad5f 6467 /* Copy the running hash so we cna restore it after. */
sPymbed 17:ff9d1e86ad5f 6468 switch (ssl->specs.mac_algorithm) {
sPymbed 17:ff9d1e86ad5f 6469 #ifndef NO_SHA256
sPymbed 17:ff9d1e86ad5f 6470 case sha256_mac:
sPymbed 17:ff9d1e86ad5f 6471 ret = wc_Sha256Copy(&ssl->hsHashes->hashSha256, &digest.sha256);
sPymbed 17:ff9d1e86ad5f 6472 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 6473 return ret;
sPymbed 17:ff9d1e86ad5f 6474 break;
sPymbed 17:ff9d1e86ad5f 6475 #endif
sPymbed 17:ff9d1e86ad5f 6476 #ifdef WOLFSSL_SHA384
sPymbed 17:ff9d1e86ad5f 6477 case sha384_mac:
sPymbed 17:ff9d1e86ad5f 6478 ret = wc_Sha384Copy(&ssl->hsHashes->hashSha384, &digest.sha384);
sPymbed 17:ff9d1e86ad5f 6479 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 6480 return ret;
sPymbed 17:ff9d1e86ad5f 6481 break;
sPymbed 17:ff9d1e86ad5f 6482 #endif
sPymbed 17:ff9d1e86ad5f 6483 #ifdef WOLFSSL_TLS13_SHA512
sPymbed 17:ff9d1e86ad5f 6484 case sha512_mac:
sPymbed 17:ff9d1e86ad5f 6485 ret = wc_Sha512Copy(&ssl->hsHashes->hashSha512, &digest.sha512);
sPymbed 17:ff9d1e86ad5f 6486 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 6487 return ret;
sPymbed 17:ff9d1e86ad5f 6488 break;
sPymbed 17:ff9d1e86ad5f 6489 #endif
sPymbed 17:ff9d1e86ad5f 6490 }
sPymbed 17:ff9d1e86ad5f 6491
sPymbed 17:ff9d1e86ad5f 6492 /* Generate the Client's Finished message and hash it. */
sPymbed 17:ff9d1e86ad5f 6493 ret = BuildTls13HandshakeHmac(ssl, ssl->keys.client_write_MAC_secret, mac,
sPymbed 17:ff9d1e86ad5f 6494 &finishedSz);
sPymbed 17:ff9d1e86ad5f 6495 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 6496 return ret;
sPymbed 17:ff9d1e86ad5f 6497 header[FINISHED_MSG_SIZE_OFFSET] = finishedSz;
sPymbed 17:ff9d1e86ad5f 6498 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 6499 if (ssl->earlyData != no_early_data) {
sPymbed 17:ff9d1e86ad5f 6500 static byte endOfEarlyData[] = { 0x05, 0x00, 0x00, 0x00 };
sPymbed 17:ff9d1e86ad5f 6501 ret = HashInputRaw(ssl, endOfEarlyData, sizeof(endOfEarlyData));
sPymbed 17:ff9d1e86ad5f 6502 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 6503 return ret;
sPymbed 17:ff9d1e86ad5f 6504 }
sPymbed 17:ff9d1e86ad5f 6505 #endif
sPymbed 17:ff9d1e86ad5f 6506 if ((ret = HashInputRaw(ssl, header, sizeof(header))) != 0)
sPymbed 17:ff9d1e86ad5f 6507 return ret;
sPymbed 17:ff9d1e86ad5f 6508 if ((ret = HashInputRaw(ssl, mac, finishedSz)) != 0)
sPymbed 17:ff9d1e86ad5f 6509 return ret;
sPymbed 17:ff9d1e86ad5f 6510
sPymbed 17:ff9d1e86ad5f 6511 if ((ret = DeriveResumptionSecret(ssl, ssl->session.masterSecret)) != 0)
sPymbed 17:ff9d1e86ad5f 6512 return ret;
sPymbed 17:ff9d1e86ad5f 6513
sPymbed 17:ff9d1e86ad5f 6514 /* Restore the hash inline with currently seen messages. */
sPymbed 17:ff9d1e86ad5f 6515 switch (ssl->specs.mac_algorithm) {
sPymbed 17:ff9d1e86ad5f 6516 #ifndef NO_SHA256
sPymbed 17:ff9d1e86ad5f 6517 case sha256_mac:
sPymbed 17:ff9d1e86ad5f 6518 ret = wc_Sha256Copy(&digest.sha256, &ssl->hsHashes->hashSha256);
sPymbed 17:ff9d1e86ad5f 6519 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 6520 return ret;
sPymbed 17:ff9d1e86ad5f 6521 break;
sPymbed 17:ff9d1e86ad5f 6522 #endif
sPymbed 17:ff9d1e86ad5f 6523 #ifdef WOLFSSL_SHA384
sPymbed 17:ff9d1e86ad5f 6524 case sha384_mac:
sPymbed 17:ff9d1e86ad5f 6525 ret = wc_Sha384Copy(&digest.sha384, &ssl->hsHashes->hashSha384);
sPymbed 17:ff9d1e86ad5f 6526 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 6527 return ret;
sPymbed 17:ff9d1e86ad5f 6528 break;
sPymbed 17:ff9d1e86ad5f 6529 #endif
sPymbed 17:ff9d1e86ad5f 6530 #ifdef WOLFSSL_TLS13_SHA512
sPymbed 17:ff9d1e86ad5f 6531 case sha512_mac:
sPymbed 17:ff9d1e86ad5f 6532 ret = wc_Sha512Copy(&digest.sha512, &ssl->hsHashes->hashSha384);
sPymbed 17:ff9d1e86ad5f 6533 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 6534 return ret;
sPymbed 17:ff9d1e86ad5f 6535 break;
sPymbed 17:ff9d1e86ad5f 6536 #endif
sPymbed 17:ff9d1e86ad5f 6537 }
sPymbed 17:ff9d1e86ad5f 6538
sPymbed 17:ff9d1e86ad5f 6539 return ret;
sPymbed 17:ff9d1e86ad5f 6540 }
sPymbed 17:ff9d1e86ad5f 6541 #endif
sPymbed 17:ff9d1e86ad5f 6542
sPymbed 17:ff9d1e86ad5f 6543 /* Send New Session Ticket handshake message.
sPymbed 17:ff9d1e86ad5f 6544 * Message contains the information required to perform resumption.
sPymbed 17:ff9d1e86ad5f 6545 *
sPymbed 17:ff9d1e86ad5f 6546 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 6547 * retuns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 6548 */
sPymbed 17:ff9d1e86ad5f 6549 static int SendTls13NewSessionTicket(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 6550 {
sPymbed 17:ff9d1e86ad5f 6551 byte* output;
sPymbed 17:ff9d1e86ad5f 6552 int ret;
sPymbed 17:ff9d1e86ad5f 6553 int sendSz;
sPymbed 17:ff9d1e86ad5f 6554 word16 extSz;
sPymbed 17:ff9d1e86ad5f 6555 word32 length;
sPymbed 17:ff9d1e86ad5f 6556 word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 6557
sPymbed 17:ff9d1e86ad5f 6558 WOLFSSL_START(WC_FUNC_NEW_SESSION_TICKET_SEND);
sPymbed 17:ff9d1e86ad5f 6559 WOLFSSL_ENTER("SendTls13NewSessionTicket");
sPymbed 17:ff9d1e86ad5f 6560
sPymbed 17:ff9d1e86ad5f 6561 #ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
sPymbed 17:ff9d1e86ad5f 6562 if (!ssl->msgsReceived.got_finished) {
sPymbed 17:ff9d1e86ad5f 6563 if ((ret = ExpectedResumptionSecret(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 6564 return ret;
sPymbed 17:ff9d1e86ad5f 6565 }
sPymbed 17:ff9d1e86ad5f 6566 #endif
sPymbed 17:ff9d1e86ad5f 6567
sPymbed 17:ff9d1e86ad5f 6568 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 6569 /* Start ticket nonce at 0 and go up to 255. */
sPymbed 17:ff9d1e86ad5f 6570 if (ssl->session.ticketNonce.len == 0) {
sPymbed 17:ff9d1e86ad5f 6571 ssl->session.ticketNonce.len = DEF_TICKET_NONCE_SZ;
sPymbed 17:ff9d1e86ad5f 6572 ssl->session.ticketNonce.data[0] = 0;
sPymbed 17:ff9d1e86ad5f 6573 }
sPymbed 17:ff9d1e86ad5f 6574 else
sPymbed 17:ff9d1e86ad5f 6575 ssl->session.ticketNonce.data[0]++;
sPymbed 17:ff9d1e86ad5f 6576 #endif
sPymbed 17:ff9d1e86ad5f 6577
sPymbed 17:ff9d1e86ad5f 6578 if (!ssl->options.noTicketTls13) {
sPymbed 17:ff9d1e86ad5f 6579 if ((ret = CreateTicket(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 6580 return ret;
sPymbed 17:ff9d1e86ad5f 6581 }
sPymbed 17:ff9d1e86ad5f 6582
sPymbed 17:ff9d1e86ad5f 6583 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 6584 ssl->session.maxEarlyDataSz = ssl->options.maxEarlyDataSz;
sPymbed 17:ff9d1e86ad5f 6585 if (ssl->session.maxEarlyDataSz > 0)
sPymbed 17:ff9d1e86ad5f 6586 TLSX_EarlyData_Use(ssl, ssl->session.maxEarlyDataSz);
sPymbed 17:ff9d1e86ad5f 6587 extSz = 0;
sPymbed 17:ff9d1e86ad5f 6588 ret = TLSX_GetResponseSize(ssl, session_ticket, &extSz);
sPymbed 17:ff9d1e86ad5f 6589 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 6590 return ret;
sPymbed 17:ff9d1e86ad5f 6591 #else
sPymbed 17:ff9d1e86ad5f 6592 extSz = EXTS_SZ;
sPymbed 17:ff9d1e86ad5f 6593 #endif
sPymbed 17:ff9d1e86ad5f 6594
sPymbed 17:ff9d1e86ad5f 6595 /* Lifetime | Age Add | Ticket | Extensions */
sPymbed 17:ff9d1e86ad5f 6596 length = SESSION_HINT_SZ + SESSION_ADD_SZ + LENGTH_SZ +
sPymbed 17:ff9d1e86ad5f 6597 ssl->session.ticketLen + extSz;
sPymbed 17:ff9d1e86ad5f 6598 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 6599 /* Nonce */
sPymbed 17:ff9d1e86ad5f 6600 length += TICKET_NONCE_LEN_SZ + DEF_TICKET_NONCE_SZ;
sPymbed 17:ff9d1e86ad5f 6601 #endif
sPymbed 17:ff9d1e86ad5f 6602 sendSz = idx + length + MAX_MSG_EXTRA;
sPymbed 17:ff9d1e86ad5f 6603
sPymbed 17:ff9d1e86ad5f 6604 /* Check buffers are big enough and grow if needed. */
sPymbed 17:ff9d1e86ad5f 6605 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
sPymbed 17:ff9d1e86ad5f 6606 return ret;
sPymbed 17:ff9d1e86ad5f 6607
sPymbed 17:ff9d1e86ad5f 6608 /* Get position in output buffer to write new message to. */
sPymbed 17:ff9d1e86ad5f 6609 output = ssl->buffers.outputBuffer.buffer +
sPymbed 17:ff9d1e86ad5f 6610 ssl->buffers.outputBuffer.length;
sPymbed 17:ff9d1e86ad5f 6611
sPymbed 17:ff9d1e86ad5f 6612 /* Put the record and handshake headers on. */
sPymbed 17:ff9d1e86ad5f 6613 AddTls13Headers(output, length, session_ticket, ssl);
sPymbed 17:ff9d1e86ad5f 6614
sPymbed 17:ff9d1e86ad5f 6615 /* Lifetime hint */
sPymbed 17:ff9d1e86ad5f 6616 c32toa(ssl->ctx->ticketHint, output + idx);
sPymbed 17:ff9d1e86ad5f 6617 idx += SESSION_HINT_SZ;
sPymbed 17:ff9d1e86ad5f 6618 /* Age add - obfuscator */
sPymbed 17:ff9d1e86ad5f 6619 c32toa(ssl->session.ticketAdd, output + idx);
sPymbed 17:ff9d1e86ad5f 6620 idx += SESSION_ADD_SZ;
sPymbed 17:ff9d1e86ad5f 6621
sPymbed 17:ff9d1e86ad5f 6622 #ifndef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 6623 output[idx++] = ssl->session.ticketNonce.len;
sPymbed 17:ff9d1e86ad5f 6624 output[idx++] = ssl->session.ticketNonce.data[0];
sPymbed 17:ff9d1e86ad5f 6625 #endif
sPymbed 17:ff9d1e86ad5f 6626
sPymbed 17:ff9d1e86ad5f 6627 /* length */
sPymbed 17:ff9d1e86ad5f 6628 c16toa(ssl->session.ticketLen, output + idx);
sPymbed 17:ff9d1e86ad5f 6629 idx += LENGTH_SZ;
sPymbed 17:ff9d1e86ad5f 6630 /* ticket */
sPymbed 17:ff9d1e86ad5f 6631 XMEMCPY(output + idx, ssl->session.ticket, ssl->session.ticketLen);
sPymbed 17:ff9d1e86ad5f 6632 idx += ssl->session.ticketLen;
sPymbed 17:ff9d1e86ad5f 6633
sPymbed 17:ff9d1e86ad5f 6634 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 6635 extSz = 0;
sPymbed 17:ff9d1e86ad5f 6636 ret = TLSX_WriteResponse(ssl, output + idx, session_ticket, &extSz);
sPymbed 17:ff9d1e86ad5f 6637 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 6638 return ret;
sPymbed 17:ff9d1e86ad5f 6639 idx += extSz;
sPymbed 17:ff9d1e86ad5f 6640 #else
sPymbed 17:ff9d1e86ad5f 6641 /* No extension support - empty extensions. */
sPymbed 17:ff9d1e86ad5f 6642 c16toa(0, output + idx);
sPymbed 17:ff9d1e86ad5f 6643 idx += EXTS_SZ;
sPymbed 17:ff9d1e86ad5f 6644 #endif
sPymbed 17:ff9d1e86ad5f 6645
sPymbed 17:ff9d1e86ad5f 6646 ssl->options.haveSessionId = 1;
sPymbed 17:ff9d1e86ad5f 6647
sPymbed 17:ff9d1e86ad5f 6648 #ifndef NO_SESSION_CACHE
sPymbed 17:ff9d1e86ad5f 6649 AddSession(ssl);
sPymbed 17:ff9d1e86ad5f 6650 #endif
sPymbed 17:ff9d1e86ad5f 6651
sPymbed 17:ff9d1e86ad5f 6652 /* This message is always encrypted. */
sPymbed 17:ff9d1e86ad5f 6653 sendSz = BuildTls13Message(ssl, output, sendSz, output + RECORD_HEADER_SZ,
sPymbed 17:ff9d1e86ad5f 6654 idx - RECORD_HEADER_SZ, handshake, 0, 0, 0);
sPymbed 17:ff9d1e86ad5f 6655 if (sendSz < 0)
sPymbed 17:ff9d1e86ad5f 6656 return sendSz;
sPymbed 17:ff9d1e86ad5f 6657
sPymbed 17:ff9d1e86ad5f 6658 ssl->buffers.outputBuffer.length += sendSz;
sPymbed 17:ff9d1e86ad5f 6659
sPymbed 17:ff9d1e86ad5f 6660 if (!ssl->options.groupMessages)
sPymbed 17:ff9d1e86ad5f 6661 ret = SendBuffered(ssl);
sPymbed 17:ff9d1e86ad5f 6662
sPymbed 17:ff9d1e86ad5f 6663 WOLFSSL_LEAVE("SendTls13NewSessionTicket", 0);
sPymbed 17:ff9d1e86ad5f 6664 WOLFSSL_END(WC_FUNC_NEW_SESSION_TICKET_SEND);
sPymbed 17:ff9d1e86ad5f 6665
sPymbed 17:ff9d1e86ad5f 6666 return ret;
sPymbed 17:ff9d1e86ad5f 6667 }
sPymbed 17:ff9d1e86ad5f 6668 #endif /* HAVE_SESSION_TICKET */
sPymbed 17:ff9d1e86ad5f 6669 #endif /* NO_WOLFSSL_SERVER */
sPymbed 17:ff9d1e86ad5f 6670
sPymbed 17:ff9d1e86ad5f 6671 /* Make sure no duplicates, no fast forward, or other problems
sPymbed 17:ff9d1e86ad5f 6672 *
sPymbed 17:ff9d1e86ad5f 6673 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 6674 * type Type of handshake message received.
sPymbed 17:ff9d1e86ad5f 6675 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 6676 */
sPymbed 17:ff9d1e86ad5f 6677 static int SanityCheckTls13MsgReceived(WOLFSSL* ssl, byte type)
sPymbed 17:ff9d1e86ad5f 6678 {
sPymbed 17:ff9d1e86ad5f 6679 /* verify not a duplicate, mark received, check state */
sPymbed 17:ff9d1e86ad5f 6680 switch (type) {
sPymbed 17:ff9d1e86ad5f 6681
sPymbed 17:ff9d1e86ad5f 6682 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 6683 case client_hello:
sPymbed 17:ff9d1e86ad5f 6684 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 6685 if (ssl->options.side == WOLFSSL_CLIENT_END) {
sPymbed 17:ff9d1e86ad5f 6686 WOLFSSL_MSG("ClientHello received by client");
sPymbed 17:ff9d1e86ad5f 6687 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6688 }
sPymbed 17:ff9d1e86ad5f 6689 #endif
sPymbed 17:ff9d1e86ad5f 6690 if (ssl->options.clientState >= CLIENT_HELLO_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6691 WOLFSSL_MSG("ClientHello received out of order");
sPymbed 17:ff9d1e86ad5f 6692 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6693 }
sPymbed 17:ff9d1e86ad5f 6694 if (ssl->msgsReceived.got_client_hello == 2) {
sPymbed 17:ff9d1e86ad5f 6695 WOLFSSL_MSG("Too many ClientHello received");
sPymbed 17:ff9d1e86ad5f 6696 return DUPLICATE_MSG_E;
sPymbed 17:ff9d1e86ad5f 6697 }
sPymbed 17:ff9d1e86ad5f 6698 ssl->msgsReceived.got_client_hello++;
sPymbed 17:ff9d1e86ad5f 6699
sPymbed 17:ff9d1e86ad5f 6700 break;
sPymbed 17:ff9d1e86ad5f 6701 #endif
sPymbed 17:ff9d1e86ad5f 6702
sPymbed 17:ff9d1e86ad5f 6703 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 6704 case server_hello:
sPymbed 17:ff9d1e86ad5f 6705 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 6706 if (ssl->options.side == WOLFSSL_SERVER_END) {
sPymbed 17:ff9d1e86ad5f 6707 WOLFSSL_MSG("ServerHello received by server");
sPymbed 17:ff9d1e86ad5f 6708 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6709 }
sPymbed 17:ff9d1e86ad5f 6710 #endif
sPymbed 17:ff9d1e86ad5f 6711 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 6712 if (ssl->msgsReceived.got_server_hello) {
sPymbed 17:ff9d1e86ad5f 6713 WOLFSSL_MSG("Duplicate ServerHello received");
sPymbed 17:ff9d1e86ad5f 6714 return DUPLICATE_MSG_E;
sPymbed 17:ff9d1e86ad5f 6715 }
sPymbed 17:ff9d1e86ad5f 6716 ssl->msgsReceived.got_server_hello = 1;
sPymbed 17:ff9d1e86ad5f 6717 #else
sPymbed 17:ff9d1e86ad5f 6718 if (ssl->msgsReceived.got_server_hello == 2) {
sPymbed 17:ff9d1e86ad5f 6719 WOLFSSL_MSG("Duplicate ServerHello received");
sPymbed 17:ff9d1e86ad5f 6720 return DUPLICATE_MSG_E;
sPymbed 17:ff9d1e86ad5f 6721 }
sPymbed 17:ff9d1e86ad5f 6722 ssl->msgsReceived.got_server_hello++;
sPymbed 17:ff9d1e86ad5f 6723 #endif
sPymbed 17:ff9d1e86ad5f 6724
sPymbed 17:ff9d1e86ad5f 6725 break;
sPymbed 17:ff9d1e86ad5f 6726 #endif
sPymbed 17:ff9d1e86ad5f 6727
sPymbed 17:ff9d1e86ad5f 6728 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 6729 case session_ticket:
sPymbed 17:ff9d1e86ad5f 6730 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 6731 if (ssl->options.side == WOLFSSL_SERVER_END) {
sPymbed 17:ff9d1e86ad5f 6732 WOLFSSL_MSG("NewSessionTicket received by server");
sPymbed 17:ff9d1e86ad5f 6733 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6734 }
sPymbed 17:ff9d1e86ad5f 6735 #endif
sPymbed 17:ff9d1e86ad5f 6736 if (ssl->options.clientState < CLIENT_FINISHED_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6737 WOLFSSL_MSG("NewSessionTicket received out of order");
sPymbed 17:ff9d1e86ad5f 6738 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6739 }
sPymbed 17:ff9d1e86ad5f 6740 ssl->msgsReceived.got_session_ticket = 1;
sPymbed 17:ff9d1e86ad5f 6741
sPymbed 17:ff9d1e86ad5f 6742 break;
sPymbed 17:ff9d1e86ad5f 6743 #endif
sPymbed 17:ff9d1e86ad5f 6744
sPymbed 17:ff9d1e86ad5f 6745 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 6746 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 6747 case end_of_early_data:
sPymbed 17:ff9d1e86ad5f 6748 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 6749 if (ssl->options.side == WOLFSSL_CLIENT_END) {
sPymbed 17:ff9d1e86ad5f 6750 WOLFSSL_MSG("EndOfEarlyData received by client");
sPymbed 17:ff9d1e86ad5f 6751 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6752 }
sPymbed 17:ff9d1e86ad5f 6753 #endif
sPymbed 17:ff9d1e86ad5f 6754 if (ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6755 WOLFSSL_MSG("EndOfEarlyData received out of order");
sPymbed 17:ff9d1e86ad5f 6756 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6757 }
sPymbed 17:ff9d1e86ad5f 6758 if (ssl->options.clientState >= CLIENT_FINISHED_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6759 WOLFSSL_MSG("EndOfEarlyData received out of order");
sPymbed 17:ff9d1e86ad5f 6760 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6761 }
sPymbed 17:ff9d1e86ad5f 6762 if (ssl->msgsReceived.got_end_of_early_data == 1) {
sPymbed 17:ff9d1e86ad5f 6763 WOLFSSL_MSG("Too many EndOfEarlyData received");
sPymbed 17:ff9d1e86ad5f 6764 return DUPLICATE_MSG_E;
sPymbed 17:ff9d1e86ad5f 6765 }
sPymbed 17:ff9d1e86ad5f 6766 ssl->msgsReceived.got_end_of_early_data++;
sPymbed 17:ff9d1e86ad5f 6767
sPymbed 17:ff9d1e86ad5f 6768 break;
sPymbed 17:ff9d1e86ad5f 6769 #endif
sPymbed 17:ff9d1e86ad5f 6770 #endif
sPymbed 17:ff9d1e86ad5f 6771
sPymbed 17:ff9d1e86ad5f 6772 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 6773 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 6774 case hello_retry_request:
sPymbed 17:ff9d1e86ad5f 6775 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 6776 if (ssl->options.side == WOLFSSL_SERVER_END) {
sPymbed 17:ff9d1e86ad5f 6777 WOLFSSL_MSG("HelloRetryRequest received by server");
sPymbed 17:ff9d1e86ad5f 6778 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6779 }
sPymbed 17:ff9d1e86ad5f 6780 #endif
sPymbed 17:ff9d1e86ad5f 6781 if (ssl->options.clientState > CLIENT_FINISHED_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6782 WOLFSSL_MSG("HelloRetryRequest received out of order");
sPymbed 17:ff9d1e86ad5f 6783 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6784 }
sPymbed 17:ff9d1e86ad5f 6785 if (ssl->msgsReceived.got_hello_retry_request) {
sPymbed 17:ff9d1e86ad5f 6786 WOLFSSL_MSG("Duplicate HelloRetryRequest received");
sPymbed 17:ff9d1e86ad5f 6787 return DUPLICATE_MSG_E;
sPymbed 17:ff9d1e86ad5f 6788 }
sPymbed 17:ff9d1e86ad5f 6789 ssl->msgsReceived.got_hello_retry_request = 1;
sPymbed 17:ff9d1e86ad5f 6790
sPymbed 17:ff9d1e86ad5f 6791 break;
sPymbed 17:ff9d1e86ad5f 6792 #endif
sPymbed 17:ff9d1e86ad5f 6793 #endif
sPymbed 17:ff9d1e86ad5f 6794
sPymbed 17:ff9d1e86ad5f 6795 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 6796 case encrypted_extensions:
sPymbed 17:ff9d1e86ad5f 6797 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 6798 if (ssl->options.side == WOLFSSL_SERVER_END) {
sPymbed 17:ff9d1e86ad5f 6799 WOLFSSL_MSG("EncryptedExtensions received by server");
sPymbed 17:ff9d1e86ad5f 6800 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6801 }
sPymbed 17:ff9d1e86ad5f 6802 #endif
sPymbed 17:ff9d1e86ad5f 6803 if (ssl->options.serverState != SERVER_HELLO_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6804 WOLFSSL_MSG("EncryptedExtensions received out of order");
sPymbed 17:ff9d1e86ad5f 6805 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6806 }
sPymbed 17:ff9d1e86ad5f 6807 if (ssl->msgsReceived.got_encrypted_extensions) {
sPymbed 17:ff9d1e86ad5f 6808 WOLFSSL_MSG("Duplicate EncryptedExtensions received");
sPymbed 17:ff9d1e86ad5f 6809 return DUPLICATE_MSG_E;
sPymbed 17:ff9d1e86ad5f 6810 }
sPymbed 17:ff9d1e86ad5f 6811 ssl->msgsReceived.got_encrypted_extensions = 1;
sPymbed 17:ff9d1e86ad5f 6812
sPymbed 17:ff9d1e86ad5f 6813 break;
sPymbed 17:ff9d1e86ad5f 6814 #endif
sPymbed 17:ff9d1e86ad5f 6815
sPymbed 17:ff9d1e86ad5f 6816 case certificate:
sPymbed 17:ff9d1e86ad5f 6817 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 6818 if (ssl->options.side == WOLFSSL_CLIENT_END &&
sPymbed 17:ff9d1e86ad5f 6819 ssl->options.serverState !=
sPymbed 17:ff9d1e86ad5f 6820 SERVER_ENCRYPTED_EXTENSIONS_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6821 WOLFSSL_MSG("Certificate received out of order - Client");
sPymbed 17:ff9d1e86ad5f 6822 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6823 }
sPymbed 17:ff9d1e86ad5f 6824 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 6825 /* Server's authenticating with PSK must not send this. */
sPymbed 17:ff9d1e86ad5f 6826 if (ssl->options.side == WOLFSSL_CLIENT_END &&
sPymbed 17:ff9d1e86ad5f 6827 ssl->options.serverState == SERVER_CERT_COMPLETE &&
sPymbed 17:ff9d1e86ad5f 6828 ssl->arrays->psk_keySz != 0) {
sPymbed 17:ff9d1e86ad5f 6829 WOLFSSL_MSG("Certificate received while using PSK");
sPymbed 17:ff9d1e86ad5f 6830 return SANITY_MSG_E;
sPymbed 17:ff9d1e86ad5f 6831 }
sPymbed 17:ff9d1e86ad5f 6832 #endif
sPymbed 17:ff9d1e86ad5f 6833 #endif
sPymbed 17:ff9d1e86ad5f 6834 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 6835 if (ssl->options.side == WOLFSSL_SERVER_END &&
sPymbed 17:ff9d1e86ad5f 6836 ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6837 WOLFSSL_MSG("Certificate received out of order - Server");
sPymbed 17:ff9d1e86ad5f 6838 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6839 }
sPymbed 17:ff9d1e86ad5f 6840 #endif
sPymbed 17:ff9d1e86ad5f 6841 if (ssl->msgsReceived.got_certificate) {
sPymbed 17:ff9d1e86ad5f 6842 WOLFSSL_MSG("Duplicate Certificate received");
sPymbed 17:ff9d1e86ad5f 6843 return DUPLICATE_MSG_E;
sPymbed 17:ff9d1e86ad5f 6844 }
sPymbed 17:ff9d1e86ad5f 6845 ssl->msgsReceived.got_certificate = 1;
sPymbed 17:ff9d1e86ad5f 6846
sPymbed 17:ff9d1e86ad5f 6847 break;
sPymbed 17:ff9d1e86ad5f 6848
sPymbed 17:ff9d1e86ad5f 6849 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 6850 case certificate_request:
sPymbed 17:ff9d1e86ad5f 6851 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 6852 if (ssl->options.side == WOLFSSL_SERVER_END) {
sPymbed 17:ff9d1e86ad5f 6853 WOLFSSL_MSG("CertificateRequest received by server");
sPymbed 17:ff9d1e86ad5f 6854 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6855 }
sPymbed 17:ff9d1e86ad5f 6856 #endif
sPymbed 17:ff9d1e86ad5f 6857 #ifndef WOLFSSL_POST_HANDSHAKE_AUTH
sPymbed 17:ff9d1e86ad5f 6858 if (ssl->options.serverState !=
sPymbed 17:ff9d1e86ad5f 6859 SERVER_ENCRYPTED_EXTENSIONS_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6860 WOLFSSL_MSG("CertificateRequest received out of order");
sPymbed 17:ff9d1e86ad5f 6861 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6862 }
sPymbed 17:ff9d1e86ad5f 6863 #else
sPymbed 17:ff9d1e86ad5f 6864 if (ssl->options.serverState !=
sPymbed 17:ff9d1e86ad5f 6865 SERVER_ENCRYPTED_EXTENSIONS_COMPLETE &&
sPymbed 17:ff9d1e86ad5f 6866 (ssl->options.serverState != SERVER_FINISHED_COMPLETE ||
sPymbed 17:ff9d1e86ad5f 6867 ssl->options.clientState != CLIENT_FINISHED_COMPLETE)) {
sPymbed 17:ff9d1e86ad5f 6868 WOLFSSL_MSG("CertificateRequest received out of order");
sPymbed 17:ff9d1e86ad5f 6869 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6870 }
sPymbed 17:ff9d1e86ad5f 6871 #endif
sPymbed 17:ff9d1e86ad5f 6872 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 6873 /* Server's authenticating with PSK must not send this. */
sPymbed 17:ff9d1e86ad5f 6874 if (ssl->options.serverState ==
sPymbed 17:ff9d1e86ad5f 6875 SERVER_ENCRYPTED_EXTENSIONS_COMPLETE &&
sPymbed 17:ff9d1e86ad5f 6876 ssl->arrays->psk_keySz != 0) {
sPymbed 17:ff9d1e86ad5f 6877 WOLFSSL_MSG("CertificateRequset received while using PSK");
sPymbed 17:ff9d1e86ad5f 6878 return SANITY_MSG_E;
sPymbed 17:ff9d1e86ad5f 6879 }
sPymbed 17:ff9d1e86ad5f 6880 #endif
sPymbed 17:ff9d1e86ad5f 6881 #ifndef WOLFSSL_POST_HANDSHAKE_AUTH
sPymbed 17:ff9d1e86ad5f 6882 if (ssl->msgsReceived.got_certificate_request) {
sPymbed 17:ff9d1e86ad5f 6883 WOLFSSL_MSG("Duplicate CertificateRequest received");
sPymbed 17:ff9d1e86ad5f 6884 return DUPLICATE_MSG_E;
sPymbed 17:ff9d1e86ad5f 6885 }
sPymbed 17:ff9d1e86ad5f 6886 #endif
sPymbed 17:ff9d1e86ad5f 6887 ssl->msgsReceived.got_certificate_request = 1;
sPymbed 17:ff9d1e86ad5f 6888
sPymbed 17:ff9d1e86ad5f 6889 break;
sPymbed 17:ff9d1e86ad5f 6890 #endif
sPymbed 17:ff9d1e86ad5f 6891
sPymbed 17:ff9d1e86ad5f 6892 case certificate_verify:
sPymbed 17:ff9d1e86ad5f 6893 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 6894 if (ssl->options.side == WOLFSSL_CLIENT_END) {
sPymbed 17:ff9d1e86ad5f 6895 if (ssl->options.serverState != SERVER_CERT_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6896 WOLFSSL_MSG("No Cert before CertVerify");
sPymbed 17:ff9d1e86ad5f 6897 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6898 }
sPymbed 17:ff9d1e86ad5f 6899 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 6900 /* Server's authenticating with PSK must not send this. */
sPymbed 17:ff9d1e86ad5f 6901 if (ssl->options.serverState == SERVER_CERT_COMPLETE &&
sPymbed 17:ff9d1e86ad5f 6902 ssl->arrays->psk_keySz != 0) {
sPymbed 17:ff9d1e86ad5f 6903 WOLFSSL_MSG("CertificateVerify received while using PSK");
sPymbed 17:ff9d1e86ad5f 6904 return SANITY_MSG_E;
sPymbed 17:ff9d1e86ad5f 6905 }
sPymbed 17:ff9d1e86ad5f 6906 #endif
sPymbed 17:ff9d1e86ad5f 6907 }
sPymbed 17:ff9d1e86ad5f 6908 #endif
sPymbed 17:ff9d1e86ad5f 6909 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 6910 if (ssl->options.side == WOLFSSL_SERVER_END) {
sPymbed 17:ff9d1e86ad5f 6911 if (ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6912 WOLFSSL_MSG("CertificateVerify received out of order");
sPymbed 17:ff9d1e86ad5f 6913 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6914 }
sPymbed 17:ff9d1e86ad5f 6915 if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6916 WOLFSSL_MSG("CertificateVerify before ClientHello done");
sPymbed 17:ff9d1e86ad5f 6917 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6918 }
sPymbed 17:ff9d1e86ad5f 6919 if (!ssl->msgsReceived.got_certificate) {
sPymbed 17:ff9d1e86ad5f 6920 WOLFSSL_MSG("No Cert before CertificateVerify");
sPymbed 17:ff9d1e86ad5f 6921 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6922 }
sPymbed 17:ff9d1e86ad5f 6923 }
sPymbed 17:ff9d1e86ad5f 6924 #endif
sPymbed 17:ff9d1e86ad5f 6925 if (ssl->msgsReceived.got_certificate_verify) {
sPymbed 17:ff9d1e86ad5f 6926 WOLFSSL_MSG("Duplicate CertificateVerify received");
sPymbed 17:ff9d1e86ad5f 6927 return DUPLICATE_MSG_E;
sPymbed 17:ff9d1e86ad5f 6928 }
sPymbed 17:ff9d1e86ad5f 6929 ssl->msgsReceived.got_certificate_verify = 1;
sPymbed 17:ff9d1e86ad5f 6930
sPymbed 17:ff9d1e86ad5f 6931 break;
sPymbed 17:ff9d1e86ad5f 6932
sPymbed 17:ff9d1e86ad5f 6933 case finished:
sPymbed 17:ff9d1e86ad5f 6934 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 6935 if (ssl->options.side == WOLFSSL_CLIENT_END) {
sPymbed 17:ff9d1e86ad5f 6936 if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6937 WOLFSSL_MSG("Finished received out of order");
sPymbed 17:ff9d1e86ad5f 6938 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6939 }
sPymbed 17:ff9d1e86ad5f 6940 if (ssl->options.serverState <
sPymbed 17:ff9d1e86ad5f 6941 SERVER_ENCRYPTED_EXTENSIONS_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6942 WOLFSSL_MSG("Finished received out of order");
sPymbed 17:ff9d1e86ad5f 6943 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6944 }
sPymbed 17:ff9d1e86ad5f 6945 }
sPymbed 17:ff9d1e86ad5f 6946 #endif
sPymbed 17:ff9d1e86ad5f 6947 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 6948 if (ssl->options.side == WOLFSSL_SERVER_END) {
sPymbed 17:ff9d1e86ad5f 6949 if (ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6950 WOLFSSL_MSG("Finished received out of order");
sPymbed 17:ff9d1e86ad5f 6951 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6952 }
sPymbed 17:ff9d1e86ad5f 6953 if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 6954 WOLFSSL_MSG("Finished received out of order");
sPymbed 17:ff9d1e86ad5f 6955 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6956 }
sPymbed 17:ff9d1e86ad5f 6957 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 6958 if (ssl->earlyData == process_early_data) {
sPymbed 17:ff9d1e86ad5f 6959 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6960 }
sPymbed 17:ff9d1e86ad5f 6961 #endif
sPymbed 17:ff9d1e86ad5f 6962 }
sPymbed 17:ff9d1e86ad5f 6963 #endif
sPymbed 17:ff9d1e86ad5f 6964 if (ssl->msgsReceived.got_finished) {
sPymbed 17:ff9d1e86ad5f 6965 WOLFSSL_MSG("Duplicate Finished received");
sPymbed 17:ff9d1e86ad5f 6966 return DUPLICATE_MSG_E;
sPymbed 17:ff9d1e86ad5f 6967 }
sPymbed 17:ff9d1e86ad5f 6968 ssl->msgsReceived.got_finished = 1;
sPymbed 17:ff9d1e86ad5f 6969
sPymbed 17:ff9d1e86ad5f 6970 break;
sPymbed 17:ff9d1e86ad5f 6971
sPymbed 17:ff9d1e86ad5f 6972 case key_update:
sPymbed 17:ff9d1e86ad5f 6973 if (!ssl->msgsReceived.got_finished) {
sPymbed 17:ff9d1e86ad5f 6974 WOLFSSL_MSG("No KeyUpdate before Finished");
sPymbed 17:ff9d1e86ad5f 6975 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 6976 }
sPymbed 17:ff9d1e86ad5f 6977 break;
sPymbed 17:ff9d1e86ad5f 6978
sPymbed 17:ff9d1e86ad5f 6979 default:
sPymbed 17:ff9d1e86ad5f 6980 WOLFSSL_MSG("Unknown message type");
sPymbed 17:ff9d1e86ad5f 6981 return SANITY_MSG_E;
sPymbed 17:ff9d1e86ad5f 6982 }
sPymbed 17:ff9d1e86ad5f 6983
sPymbed 17:ff9d1e86ad5f 6984 return 0;
sPymbed 17:ff9d1e86ad5f 6985 }
sPymbed 17:ff9d1e86ad5f 6986
sPymbed 17:ff9d1e86ad5f 6987 /* Handle a type of handshake message that has been received.
sPymbed 17:ff9d1e86ad5f 6988 *
sPymbed 17:ff9d1e86ad5f 6989 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 6990 * input The message buffer.
sPymbed 17:ff9d1e86ad5f 6991 * inOutIdx On entry, the index into the buffer of the current message.
sPymbed 17:ff9d1e86ad5f 6992 * On exit, the index into the buffer of the next message.
sPymbed 17:ff9d1e86ad5f 6993 * size The length of the current handshake message.
sPymbed 17:ff9d1e86ad5f 6994 * totalSz Length of remaining data in the message buffer.
sPymbed 17:ff9d1e86ad5f 6995 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 6996 */
sPymbed 17:ff9d1e86ad5f 6997 int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
sPymbed 17:ff9d1e86ad5f 6998 byte type, word32 size, word32 totalSz)
sPymbed 17:ff9d1e86ad5f 6999 {
sPymbed 17:ff9d1e86ad5f 7000 int ret = 0;
sPymbed 17:ff9d1e86ad5f 7001 word32 inIdx = *inOutIdx;
sPymbed 17:ff9d1e86ad5f 7002
sPymbed 17:ff9d1e86ad5f 7003 (void)totalSz;
sPymbed 17:ff9d1e86ad5f 7004
sPymbed 17:ff9d1e86ad5f 7005 WOLFSSL_ENTER("DoTls13HandShakeMsgType");
sPymbed 17:ff9d1e86ad5f 7006
sPymbed 17:ff9d1e86ad5f 7007 /* make sure can read the message */
sPymbed 17:ff9d1e86ad5f 7008 if (*inOutIdx + size > totalSz)
sPymbed 17:ff9d1e86ad5f 7009 return INCOMPLETE_DATA;
sPymbed 17:ff9d1e86ad5f 7010
sPymbed 17:ff9d1e86ad5f 7011 /* sanity check msg received */
sPymbed 17:ff9d1e86ad5f 7012 if ((ret = SanityCheckTls13MsgReceived(ssl, type)) != 0) {
sPymbed 17:ff9d1e86ad5f 7013 WOLFSSL_MSG("Sanity Check on handshake message type received failed");
sPymbed 17:ff9d1e86ad5f 7014 SendAlert(ssl, alert_fatal, unexpected_message);
sPymbed 17:ff9d1e86ad5f 7015 return ret;
sPymbed 17:ff9d1e86ad5f 7016 }
sPymbed 17:ff9d1e86ad5f 7017
sPymbed 17:ff9d1e86ad5f 7018 #ifdef WOLFSSL_CALLBACKS
sPymbed 17:ff9d1e86ad5f 7019 /* add name later, add on record and handshake header part back on */
sPymbed 17:ff9d1e86ad5f 7020 if (ssl->toInfoOn) {
sPymbed 17:ff9d1e86ad5f 7021 int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 7022 AddPacketInfo(ssl, 0, handshake, input + *inOutIdx - add,
sPymbed 17:ff9d1e86ad5f 7023 size + add, READ_PROTO, ssl->heap);
sPymbed 17:ff9d1e86ad5f 7024 AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
sPymbed 17:ff9d1e86ad5f 7025 }
sPymbed 17:ff9d1e86ad5f 7026 #endif
sPymbed 17:ff9d1e86ad5f 7027
sPymbed 17:ff9d1e86ad5f 7028 if (ssl->options.handShakeState == HANDSHAKE_DONE &&
sPymbed 17:ff9d1e86ad5f 7029 type != session_ticket && type != certificate_request &&
sPymbed 17:ff9d1e86ad5f 7030 type != certificate && type != key_update) {
sPymbed 17:ff9d1e86ad5f 7031 WOLFSSL_MSG("HandShake message after handshake complete");
sPymbed 17:ff9d1e86ad5f 7032 SendAlert(ssl, alert_fatal, unexpected_message);
sPymbed 17:ff9d1e86ad5f 7033 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 7034 }
sPymbed 17:ff9d1e86ad5f 7035
sPymbed 17:ff9d1e86ad5f 7036 if (ssl->options.side == WOLFSSL_CLIENT_END &&
sPymbed 17:ff9d1e86ad5f 7037 ssl->options.serverState == NULL_STATE &&
sPymbed 17:ff9d1e86ad5f 7038 type != server_hello && type != hello_retry_request) {
sPymbed 17:ff9d1e86ad5f 7039 WOLFSSL_MSG("First server message not server hello");
sPymbed 17:ff9d1e86ad5f 7040 SendAlert(ssl, alert_fatal, unexpected_message);
sPymbed 17:ff9d1e86ad5f 7041 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 7042 }
sPymbed 17:ff9d1e86ad5f 7043
sPymbed 17:ff9d1e86ad5f 7044 if (ssl->options.side == WOLFSSL_SERVER_END &&
sPymbed 17:ff9d1e86ad5f 7045 ssl->options.clientState == NULL_STATE && type != client_hello) {
sPymbed 17:ff9d1e86ad5f 7046 WOLFSSL_MSG("First client message not client hello");
sPymbed 17:ff9d1e86ad5f 7047 SendAlert(ssl, alert_fatal, unexpected_message);
sPymbed 17:ff9d1e86ad5f 7048 return OUT_OF_ORDER_E;
sPymbed 17:ff9d1e86ad5f 7049 }
sPymbed 17:ff9d1e86ad5f 7050
sPymbed 17:ff9d1e86ad5f 7051 /* above checks handshake state */
sPymbed 17:ff9d1e86ad5f 7052 switch (type) {
sPymbed 17:ff9d1e86ad5f 7053 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 7054 /* Messages only recieved by client. */
sPymbed 17:ff9d1e86ad5f 7055 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 7056 case hello_retry_request:
sPymbed 17:ff9d1e86ad5f 7057 WOLFSSL_MSG("processing hello rety request");
sPymbed 17:ff9d1e86ad5f 7058 ret = DoTls13HelloRetryRequest(ssl, input, inOutIdx, size);
sPymbed 17:ff9d1e86ad5f 7059 break;
sPymbed 17:ff9d1e86ad5f 7060 #endif
sPymbed 17:ff9d1e86ad5f 7061
sPymbed 17:ff9d1e86ad5f 7062 case server_hello:
sPymbed 17:ff9d1e86ad5f 7063 WOLFSSL_MSG("processing server hello");
sPymbed 17:ff9d1e86ad5f 7064 ret = DoTls13ServerHello(ssl, input, inOutIdx, size, &type);
sPymbed 17:ff9d1e86ad5f 7065 break;
sPymbed 17:ff9d1e86ad5f 7066
sPymbed 17:ff9d1e86ad5f 7067 case encrypted_extensions:
sPymbed 17:ff9d1e86ad5f 7068 WOLFSSL_MSG("processing encrypted extensions");
sPymbed 17:ff9d1e86ad5f 7069 ret = DoTls13EncryptedExtensions(ssl, input, inOutIdx, size);
sPymbed 17:ff9d1e86ad5f 7070 break;
sPymbed 17:ff9d1e86ad5f 7071
sPymbed 17:ff9d1e86ad5f 7072 #ifndef NO_CERTS
sPymbed 17:ff9d1e86ad5f 7073 case certificate_request:
sPymbed 17:ff9d1e86ad5f 7074 WOLFSSL_MSG("processing certificate request");
sPymbed 17:ff9d1e86ad5f 7075 ret = DoTls13CertificateRequest(ssl, input, inOutIdx, size);
sPymbed 17:ff9d1e86ad5f 7076 break;
sPymbed 17:ff9d1e86ad5f 7077 #endif
sPymbed 17:ff9d1e86ad5f 7078
sPymbed 17:ff9d1e86ad5f 7079 case session_ticket:
sPymbed 17:ff9d1e86ad5f 7080 WOLFSSL_MSG("processing new session ticket");
sPymbed 17:ff9d1e86ad5f 7081 ret = DoTls13NewSessionTicket(ssl, input, inOutIdx, size);
sPymbed 17:ff9d1e86ad5f 7082 break;
sPymbed 17:ff9d1e86ad5f 7083 #endif /* !NO_WOLFSSL_CLIENT */
sPymbed 17:ff9d1e86ad5f 7084
sPymbed 17:ff9d1e86ad5f 7085 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 7086 /* Messages only recieved by server. */
sPymbed 17:ff9d1e86ad5f 7087 case client_hello:
sPymbed 17:ff9d1e86ad5f 7088 WOLFSSL_MSG("processing client hello");
sPymbed 17:ff9d1e86ad5f 7089 ret = DoTls13ClientHello(ssl, input, inOutIdx, size);
sPymbed 17:ff9d1e86ad5f 7090 break;
sPymbed 17:ff9d1e86ad5f 7091
sPymbed 17:ff9d1e86ad5f 7092 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 7093 case end_of_early_data:
sPymbed 17:ff9d1e86ad5f 7094 WOLFSSL_MSG("processing end of early data");
sPymbed 17:ff9d1e86ad5f 7095 ret = DoTls13EndOfEarlyData(ssl, input, inOutIdx, size);
sPymbed 17:ff9d1e86ad5f 7096 break;
sPymbed 17:ff9d1e86ad5f 7097 #endif
sPymbed 17:ff9d1e86ad5f 7098 #endif /* !NO_WOLFSSL_SERVER */
sPymbed 17:ff9d1e86ad5f 7099
sPymbed 17:ff9d1e86ad5f 7100 /* Messages recieved by both client and server. */
sPymbed 17:ff9d1e86ad5f 7101 #ifndef NO_CERTS
sPymbed 17:ff9d1e86ad5f 7102 case certificate:
sPymbed 17:ff9d1e86ad5f 7103 WOLFSSL_MSG("processing certificate");
sPymbed 17:ff9d1e86ad5f 7104 ret = DoTls13Certificate(ssl, input, inOutIdx, size);
sPymbed 17:ff9d1e86ad5f 7105 break;
sPymbed 17:ff9d1e86ad5f 7106 #endif
sPymbed 17:ff9d1e86ad5f 7107
sPymbed 17:ff9d1e86ad5f 7108 #if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)
sPymbed 17:ff9d1e86ad5f 7109 case certificate_verify:
sPymbed 17:ff9d1e86ad5f 7110 WOLFSSL_MSG("processing certificate verify");
sPymbed 17:ff9d1e86ad5f 7111 ret = DoTls13CertificateVerify(ssl, input, inOutIdx, size);
sPymbed 17:ff9d1e86ad5f 7112 break;
sPymbed 17:ff9d1e86ad5f 7113 #endif /* !NO_RSA || HAVE_ECC */
sPymbed 17:ff9d1e86ad5f 7114
sPymbed 17:ff9d1e86ad5f 7115 case finished:
sPymbed 17:ff9d1e86ad5f 7116 WOLFSSL_MSG("processing finished");
sPymbed 17:ff9d1e86ad5f 7117 ret = DoTls13Finished(ssl, input, inOutIdx, size, totalSz, NO_SNIFF);
sPymbed 17:ff9d1e86ad5f 7118 break;
sPymbed 17:ff9d1e86ad5f 7119
sPymbed 17:ff9d1e86ad5f 7120 case key_update:
sPymbed 17:ff9d1e86ad5f 7121 WOLFSSL_MSG("processing finished");
sPymbed 17:ff9d1e86ad5f 7122 ret = DoTls13KeyUpdate(ssl, input, inOutIdx, size);
sPymbed 17:ff9d1e86ad5f 7123 break;
sPymbed 17:ff9d1e86ad5f 7124
sPymbed 17:ff9d1e86ad5f 7125 default:
sPymbed 17:ff9d1e86ad5f 7126 WOLFSSL_MSG("Unknown handshake message type");
sPymbed 17:ff9d1e86ad5f 7127 ret = UNKNOWN_HANDSHAKE_TYPE;
sPymbed 17:ff9d1e86ad5f 7128 break;
sPymbed 17:ff9d1e86ad5f 7129 }
sPymbed 17:ff9d1e86ad5f 7130
sPymbed 17:ff9d1e86ad5f 7131 /* reset error */
sPymbed 17:ff9d1e86ad5f 7132 if (ret == 0 && ssl->error == WC_PENDING_E)
sPymbed 17:ff9d1e86ad5f 7133 ssl->error = 0;
sPymbed 17:ff9d1e86ad5f 7134
sPymbed 17:ff9d1e86ad5f 7135 if (ret == 0 && type != client_hello && type != session_ticket &&
sPymbed 17:ff9d1e86ad5f 7136 type != key_update) {
sPymbed 17:ff9d1e86ad5f 7137 ret = HashInput(ssl, input + inIdx, size);
sPymbed 17:ff9d1e86ad5f 7138 }
sPymbed 17:ff9d1e86ad5f 7139
sPymbed 17:ff9d1e86ad5f 7140 if (ret == BUFFER_ERROR || ret == MISSING_HANDSHAKE_DATA)
sPymbed 17:ff9d1e86ad5f 7141 SendAlert(ssl, alert_fatal, decode_error);
sPymbed 17:ff9d1e86ad5f 7142 else if (ret == EXT_NOT_ALLOWED || ret == PEER_KEY_ERROR ||
sPymbed 17:ff9d1e86ad5f 7143 ret == ECC_PEERKEY_ERROR || ret == BAD_KEY_SHARE_DATA ||
sPymbed 17:ff9d1e86ad5f 7144 ret == PSK_KEY_ERROR || ret == INVALID_PARAMETER) {
sPymbed 17:ff9d1e86ad5f 7145 SendAlert(ssl, alert_fatal, illegal_parameter);
sPymbed 17:ff9d1e86ad5f 7146 }
sPymbed 17:ff9d1e86ad5f 7147
sPymbed 17:ff9d1e86ad5f 7148 if (ssl->options.tls1_3) {
sPymbed 17:ff9d1e86ad5f 7149 /* Need to hash input message before deriving secrets. */
sPymbed 17:ff9d1e86ad5f 7150 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 7151 if (ssl->options.side == WOLFSSL_CLIENT_END) {
sPymbed 17:ff9d1e86ad5f 7152 if (type == server_hello) {
sPymbed 17:ff9d1e86ad5f 7153 if ((ret = DeriveEarlySecret(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 7154 return ret;
sPymbed 17:ff9d1e86ad5f 7155 if ((ret = DeriveHandshakeSecret(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 7156 return ret;
sPymbed 17:ff9d1e86ad5f 7157
sPymbed 17:ff9d1e86ad5f 7158 if ((ret = DeriveTls13Keys(ssl, handshake_key,
sPymbed 17:ff9d1e86ad5f 7159 ENCRYPT_AND_DECRYPT_SIDE, 1)) != 0) {
sPymbed 17:ff9d1e86ad5f 7160 return ret;
sPymbed 17:ff9d1e86ad5f 7161 }
sPymbed 17:ff9d1e86ad5f 7162 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 7163 if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
sPymbed 17:ff9d1e86ad5f 7164 return ret;
sPymbed 17:ff9d1e86ad5f 7165 #else
sPymbed 17:ff9d1e86ad5f 7166 if ((ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE)) != 0)
sPymbed 17:ff9d1e86ad5f 7167 return ret;
sPymbed 17:ff9d1e86ad5f 7168 #endif
sPymbed 17:ff9d1e86ad5f 7169 }
sPymbed 17:ff9d1e86ad5f 7170
sPymbed 17:ff9d1e86ad5f 7171 if (type == finished) {
sPymbed 17:ff9d1e86ad5f 7172 if ((ret = DeriveMasterSecret(ssl)) != 0)
sPymbed 17:ff9d1e86ad5f 7173 return ret;
sPymbed 17:ff9d1e86ad5f 7174 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 7175 if ((ret = DeriveTls13Keys(ssl, traffic_key,
sPymbed 17:ff9d1e86ad5f 7176 ENCRYPT_AND_DECRYPT_SIDE,
sPymbed 17:ff9d1e86ad5f 7177 ssl->earlyData == no_early_data)) != 0) {
sPymbed 17:ff9d1e86ad5f 7178 return ret;
sPymbed 17:ff9d1e86ad5f 7179 }
sPymbed 17:ff9d1e86ad5f 7180 #else
sPymbed 17:ff9d1e86ad5f 7181 if ((ret = DeriveTls13Keys(ssl, traffic_key,
sPymbed 17:ff9d1e86ad5f 7182 ENCRYPT_AND_DECRYPT_SIDE, 1)) != 0) {
sPymbed 17:ff9d1e86ad5f 7183 return ret;
sPymbed 17:ff9d1e86ad5f 7184 }
sPymbed 17:ff9d1e86ad5f 7185 #endif
sPymbed 17:ff9d1e86ad5f 7186 }
sPymbed 17:ff9d1e86ad5f 7187 #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
sPymbed 17:ff9d1e86ad5f 7188 if (type == certificate_request &&
sPymbed 17:ff9d1e86ad5f 7189 ssl->options.handShakeState == HANDSHAKE_DONE) {
sPymbed 17:ff9d1e86ad5f 7190 /* reset handshake states */
sPymbed 17:ff9d1e86ad5f 7191 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
sPymbed 17:ff9d1e86ad5f 7192 ssl->options.connectState = FIRST_REPLY_DONE;
sPymbed 17:ff9d1e86ad5f 7193 ssl->options.handShakeState = CLIENT_HELLO_COMPLETE;
sPymbed 17:ff9d1e86ad5f 7194
sPymbed 17:ff9d1e86ad5f 7195 if (wolfSSL_connect_TLSv13(ssl) != SSL_SUCCESS)
sPymbed 17:ff9d1e86ad5f 7196 ret = POST_HAND_AUTH_ERROR;
sPymbed 17:ff9d1e86ad5f 7197 }
sPymbed 17:ff9d1e86ad5f 7198 #endif
sPymbed 17:ff9d1e86ad5f 7199 }
sPymbed 17:ff9d1e86ad5f 7200 #endif /* NO_WOLFSSL_CLIENT */
sPymbed 17:ff9d1e86ad5f 7201
sPymbed 17:ff9d1e86ad5f 7202 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 7203 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 7204 if (ssl->options.side == WOLFSSL_SERVER_END && type == finished) {
sPymbed 17:ff9d1e86ad5f 7205 ret = DeriveResumptionSecret(ssl, ssl->session.masterSecret);
sPymbed 17:ff9d1e86ad5f 7206 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 7207 return ret;
sPymbed 17:ff9d1e86ad5f 7208 }
sPymbed 17:ff9d1e86ad5f 7209 #endif
sPymbed 17:ff9d1e86ad5f 7210 #endif /* NO_WOLFSSL_SERVER */
sPymbed 17:ff9d1e86ad5f 7211 }
sPymbed 17:ff9d1e86ad5f 7212
sPymbed 17:ff9d1e86ad5f 7213 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 7214 /* if async, offset index so this msg will be processed again */
sPymbed 17:ff9d1e86ad5f 7215 if (ret == WC_PENDING_E && *inOutIdx > 0) {
sPymbed 17:ff9d1e86ad5f 7216 *inOutIdx -= HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 7217 }
sPymbed 17:ff9d1e86ad5f 7218 #endif
sPymbed 17:ff9d1e86ad5f 7219
sPymbed 17:ff9d1e86ad5f 7220 WOLFSSL_LEAVE("DoTls13HandShakeMsgType()", ret);
sPymbed 17:ff9d1e86ad5f 7221 return ret;
sPymbed 17:ff9d1e86ad5f 7222 }
sPymbed 17:ff9d1e86ad5f 7223
sPymbed 17:ff9d1e86ad5f 7224
sPymbed 17:ff9d1e86ad5f 7225 /* Handle a handshake message that has been received.
sPymbed 17:ff9d1e86ad5f 7226 *
sPymbed 17:ff9d1e86ad5f 7227 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 7228 * input The message buffer.
sPymbed 17:ff9d1e86ad5f 7229 * inOutIdx On entry, the index into the buffer of the current message.
sPymbed 17:ff9d1e86ad5f 7230 * On exit, the index into the buffer of the next message.
sPymbed 17:ff9d1e86ad5f 7231 * totalSz Length of remaining data in the message buffer.
sPymbed 17:ff9d1e86ad5f 7232 * returns 0 on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 7233 */
sPymbed 17:ff9d1e86ad5f 7234 int DoTls13HandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
sPymbed 17:ff9d1e86ad5f 7235 word32 totalSz)
sPymbed 17:ff9d1e86ad5f 7236 {
sPymbed 17:ff9d1e86ad5f 7237 int ret = 0;
sPymbed 17:ff9d1e86ad5f 7238 word32 inputLength;
sPymbed 17:ff9d1e86ad5f 7239
sPymbed 17:ff9d1e86ad5f 7240 WOLFSSL_ENTER("DoTls13HandShakeMsg()");
sPymbed 17:ff9d1e86ad5f 7241
sPymbed 17:ff9d1e86ad5f 7242 if (ssl->arrays == NULL) {
sPymbed 17:ff9d1e86ad5f 7243 byte type;
sPymbed 17:ff9d1e86ad5f 7244 word32 size;
sPymbed 17:ff9d1e86ad5f 7245
sPymbed 17:ff9d1e86ad5f 7246 if (GetHandshakeHeader(ssl,input,inOutIdx,&type, &size, totalSz) != 0)
sPymbed 17:ff9d1e86ad5f 7247 return PARSE_ERROR;
sPymbed 17:ff9d1e86ad5f 7248
sPymbed 17:ff9d1e86ad5f 7249 return DoTls13HandShakeMsgType(ssl, input, inOutIdx, type, size,
sPymbed 17:ff9d1e86ad5f 7250 totalSz);
sPymbed 17:ff9d1e86ad5f 7251 }
sPymbed 17:ff9d1e86ad5f 7252
sPymbed 17:ff9d1e86ad5f 7253 inputLength = ssl->buffers.inputBuffer.length - *inOutIdx - ssl->keys.padSz;
sPymbed 17:ff9d1e86ad5f 7254
sPymbed 17:ff9d1e86ad5f 7255 /* If there is a pending fragmented handshake message,
sPymbed 17:ff9d1e86ad5f 7256 * pending message size will be non-zero. */
sPymbed 17:ff9d1e86ad5f 7257 if (ssl->arrays->pendingMsgSz == 0) {
sPymbed 17:ff9d1e86ad5f 7258 byte type;
sPymbed 17:ff9d1e86ad5f 7259 word32 size;
sPymbed 17:ff9d1e86ad5f 7260
sPymbed 17:ff9d1e86ad5f 7261 if (GetHandshakeHeader(ssl,input, inOutIdx, &type, &size, totalSz) != 0)
sPymbed 17:ff9d1e86ad5f 7262 return PARSE_ERROR;
sPymbed 17:ff9d1e86ad5f 7263
sPymbed 17:ff9d1e86ad5f 7264 /* Cap the maximum size of a handshake message to something reasonable.
sPymbed 17:ff9d1e86ad5f 7265 * By default is the maximum size of a certificate message assuming
sPymbed 17:ff9d1e86ad5f 7266 * nine 2048-bit RSA certificates in the chain. */
sPymbed 17:ff9d1e86ad5f 7267 if (size > MAX_HANDSHAKE_SZ) {
sPymbed 17:ff9d1e86ad5f 7268 WOLFSSL_MSG("Handshake message too large");
sPymbed 17:ff9d1e86ad5f 7269 return HANDSHAKE_SIZE_ERROR;
sPymbed 17:ff9d1e86ad5f 7270 }
sPymbed 17:ff9d1e86ad5f 7271
sPymbed 17:ff9d1e86ad5f 7272 /* size is the size of the certificate message payload */
sPymbed 17:ff9d1e86ad5f 7273 if (inputLength - HANDSHAKE_HEADER_SZ < size) {
sPymbed 17:ff9d1e86ad5f 7274 ssl->arrays->pendingMsgType = type;
sPymbed 17:ff9d1e86ad5f 7275 ssl->arrays->pendingMsgSz = size + HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 7276 ssl->arrays->pendingMsg = (byte*)XMALLOC(size + HANDSHAKE_HEADER_SZ,
sPymbed 17:ff9d1e86ad5f 7277 ssl->heap,
sPymbed 17:ff9d1e86ad5f 7278 DYNAMIC_TYPE_ARRAYS);
sPymbed 17:ff9d1e86ad5f 7279 if (ssl->arrays->pendingMsg == NULL)
sPymbed 17:ff9d1e86ad5f 7280 return MEMORY_E;
sPymbed 17:ff9d1e86ad5f 7281 XMEMCPY(ssl->arrays->pendingMsg,
sPymbed 17:ff9d1e86ad5f 7282 input + *inOutIdx - HANDSHAKE_HEADER_SZ,
sPymbed 17:ff9d1e86ad5f 7283 inputLength);
sPymbed 17:ff9d1e86ad5f 7284 ssl->arrays->pendingMsgOffset = inputLength;
sPymbed 17:ff9d1e86ad5f 7285 *inOutIdx += inputLength + ssl->keys.padSz - HANDSHAKE_HEADER_SZ;
sPymbed 17:ff9d1e86ad5f 7286 return 0;
sPymbed 17:ff9d1e86ad5f 7287 }
sPymbed 17:ff9d1e86ad5f 7288
sPymbed 17:ff9d1e86ad5f 7289 ret = DoTls13HandShakeMsgType(ssl, input, inOutIdx, type, size,
sPymbed 17:ff9d1e86ad5f 7290 totalSz);
sPymbed 17:ff9d1e86ad5f 7291 }
sPymbed 17:ff9d1e86ad5f 7292 else {
sPymbed 17:ff9d1e86ad5f 7293 if (inputLength + ssl->arrays->pendingMsgOffset >
sPymbed 17:ff9d1e86ad5f 7294 ssl->arrays->pendingMsgSz) {
sPymbed 17:ff9d1e86ad5f 7295 inputLength = ssl->arrays->pendingMsgSz -
sPymbed 17:ff9d1e86ad5f 7296 ssl->arrays->pendingMsgOffset;
sPymbed 17:ff9d1e86ad5f 7297 }
sPymbed 17:ff9d1e86ad5f 7298 XMEMCPY(ssl->arrays->pendingMsg + ssl->arrays->pendingMsgOffset,
sPymbed 17:ff9d1e86ad5f 7299 input + *inOutIdx, inputLength);
sPymbed 17:ff9d1e86ad5f 7300 ssl->arrays->pendingMsgOffset += inputLength;
sPymbed 17:ff9d1e86ad5f 7301 *inOutIdx += inputLength + ssl->keys.padSz;
sPymbed 17:ff9d1e86ad5f 7302
sPymbed 17:ff9d1e86ad5f 7303 if (ssl->arrays->pendingMsgOffset == ssl->arrays->pendingMsgSz)
sPymbed 17:ff9d1e86ad5f 7304 {
sPymbed 17:ff9d1e86ad5f 7305 word32 idx = 0;
sPymbed 17:ff9d1e86ad5f 7306 ret = DoTls13HandShakeMsgType(ssl,
sPymbed 17:ff9d1e86ad5f 7307 ssl->arrays->pendingMsg + HANDSHAKE_HEADER_SZ,
sPymbed 17:ff9d1e86ad5f 7308 &idx, ssl->arrays->pendingMsgType,
sPymbed 17:ff9d1e86ad5f 7309 ssl->arrays->pendingMsgSz - HANDSHAKE_HEADER_SZ,
sPymbed 17:ff9d1e86ad5f 7310 ssl->arrays->pendingMsgSz);
sPymbed 17:ff9d1e86ad5f 7311 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 17:ff9d1e86ad5f 7312 if (ret == WC_PENDING_E) {
sPymbed 17:ff9d1e86ad5f 7313 /* setup to process fragment again */
sPymbed 17:ff9d1e86ad5f 7314 ssl->arrays->pendingMsgOffset -= inputLength;
sPymbed 17:ff9d1e86ad5f 7315 *inOutIdx -= inputLength + ssl->keys.padSz;
sPymbed 17:ff9d1e86ad5f 7316 }
sPymbed 17:ff9d1e86ad5f 7317 else
sPymbed 17:ff9d1e86ad5f 7318 #endif
sPymbed 17:ff9d1e86ad5f 7319 {
sPymbed 17:ff9d1e86ad5f 7320 XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
sPymbed 17:ff9d1e86ad5f 7321 ssl->arrays->pendingMsg = NULL;
sPymbed 17:ff9d1e86ad5f 7322 ssl->arrays->pendingMsgSz = 0;
sPymbed 17:ff9d1e86ad5f 7323 }
sPymbed 17:ff9d1e86ad5f 7324 }
sPymbed 17:ff9d1e86ad5f 7325 }
sPymbed 17:ff9d1e86ad5f 7326
sPymbed 17:ff9d1e86ad5f 7327 WOLFSSL_LEAVE("DoTls13HandShakeMsg()", ret);
sPymbed 17:ff9d1e86ad5f 7328 return ret;
sPymbed 17:ff9d1e86ad5f 7329 }
sPymbed 17:ff9d1e86ad5f 7330
sPymbed 17:ff9d1e86ad5f 7331 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 7332
sPymbed 17:ff9d1e86ad5f 7333 /* The client connecting to the server.
sPymbed 17:ff9d1e86ad5f 7334 * The protocol version is expecting to be TLS v1.3.
sPymbed 17:ff9d1e86ad5f 7335 * If the server downgrades, and older versions of the protocol are compiled
sPymbed 17:ff9d1e86ad5f 7336 * in, the client will fallback to wolfSSL_connect().
sPymbed 17:ff9d1e86ad5f 7337 * Please see note at top of README if you get an error from connect.
sPymbed 17:ff9d1e86ad5f 7338 *
sPymbed 17:ff9d1e86ad5f 7339 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 7340 * returns WOLFSSL_SUCCESS on successful handshake, WOLFSSL_FATAL_ERROR when
sPymbed 17:ff9d1e86ad5f 7341 * unrecoverable error occurs and 0 otherwise.
sPymbed 17:ff9d1e86ad5f 7342 * For more error information use wolfSSL_get_error().
sPymbed 17:ff9d1e86ad5f 7343 */
sPymbed 17:ff9d1e86ad5f 7344 int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 7345 {
sPymbed 17:ff9d1e86ad5f 7346 WOLFSSL_ENTER("wolfSSL_connect_TLSv13()");
sPymbed 17:ff9d1e86ad5f 7347
sPymbed 17:ff9d1e86ad5f 7348 #ifdef HAVE_ERRNO_H
sPymbed 17:ff9d1e86ad5f 7349 errno = 0;
sPymbed 17:ff9d1e86ad5f 7350 #endif
sPymbed 17:ff9d1e86ad5f 7351
sPymbed 17:ff9d1e86ad5f 7352 if (ssl->options.side != WOLFSSL_CLIENT_END) {
sPymbed 17:ff9d1e86ad5f 7353 WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
sPymbed 17:ff9d1e86ad5f 7354 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7355 }
sPymbed 17:ff9d1e86ad5f 7356
sPymbed 17:ff9d1e86ad5f 7357 if (ssl->buffers.outputBuffer.length > 0) {
sPymbed 17:ff9d1e86ad5f 7358 if ((ssl->error = SendBuffered(ssl)) == 0) {
sPymbed 17:ff9d1e86ad5f 7359 /* fragOffset is non-zero when sending fragments. On the last
sPymbed 17:ff9d1e86ad5f 7360 * fragment, fragOffset is zero again, and the state can be
sPymbed 17:ff9d1e86ad5f 7361 * advanced. */
sPymbed 17:ff9d1e86ad5f 7362 if (ssl->fragOffset == 0) {
sPymbed 17:ff9d1e86ad5f 7363 ssl->options.connectState++;
sPymbed 17:ff9d1e86ad5f 7364 WOLFSSL_MSG("connect state: "
sPymbed 17:ff9d1e86ad5f 7365 "Advanced from last buffered fragment send");
sPymbed 17:ff9d1e86ad5f 7366 }
sPymbed 17:ff9d1e86ad5f 7367 else {
sPymbed 17:ff9d1e86ad5f 7368 WOLFSSL_MSG("connect state: "
sPymbed 17:ff9d1e86ad5f 7369 "Not advanced, more fragments to send");
sPymbed 17:ff9d1e86ad5f 7370 }
sPymbed 17:ff9d1e86ad5f 7371 }
sPymbed 17:ff9d1e86ad5f 7372 else {
sPymbed 17:ff9d1e86ad5f 7373 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 7374 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7375 }
sPymbed 17:ff9d1e86ad5f 7376 }
sPymbed 17:ff9d1e86ad5f 7377
sPymbed 17:ff9d1e86ad5f 7378 switch (ssl->options.connectState) {
sPymbed 17:ff9d1e86ad5f 7379
sPymbed 17:ff9d1e86ad5f 7380 case CONNECT_BEGIN:
sPymbed 17:ff9d1e86ad5f 7381 /* Always send client hello first. */
sPymbed 17:ff9d1e86ad5f 7382 if ((ssl->error = SendTls13ClientHello(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 7383 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 7384 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7385 }
sPymbed 17:ff9d1e86ad5f 7386
sPymbed 17:ff9d1e86ad5f 7387 ssl->options.connectState = CLIENT_HELLO_SENT;
sPymbed 17:ff9d1e86ad5f 7388 WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
sPymbed 17:ff9d1e86ad5f 7389 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 7390 if (ssl->earlyData != no_early_data) {
sPymbed 17:ff9d1e86ad5f 7391 #if !defined(WOLFSSL_TLS13_DRAFT_18) && \
sPymbed 17:ff9d1e86ad5f 7392 defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
sPymbed 17:ff9d1e86ad5f 7393 if ((ssl->error = SendChangeCipher(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 7394 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 7395 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7396 }
sPymbed 17:ff9d1e86ad5f 7397 ssl->options.sentChangeCipher = 1;
sPymbed 17:ff9d1e86ad5f 7398 #endif
sPymbed 17:ff9d1e86ad5f 7399 ssl->options.handShakeState = CLIENT_HELLO_COMPLETE;
sPymbed 17:ff9d1e86ad5f 7400 return WOLFSSL_SUCCESS;
sPymbed 17:ff9d1e86ad5f 7401 }
sPymbed 17:ff9d1e86ad5f 7402 #endif
sPymbed 17:ff9d1e86ad5f 7403 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 7404
sPymbed 17:ff9d1e86ad5f 7405 case CLIENT_HELLO_SENT:
sPymbed 17:ff9d1e86ad5f 7406 /* Get the response/s from the server. */
sPymbed 17:ff9d1e86ad5f 7407 while (ssl->options.serverState <
sPymbed 17:ff9d1e86ad5f 7408 SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 7409 if ((ssl->error = ProcessReply(ssl)) < 0) {
sPymbed 17:ff9d1e86ad5f 7410 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 7411 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7412 }
sPymbed 17:ff9d1e86ad5f 7413 }
sPymbed 17:ff9d1e86ad5f 7414
sPymbed 17:ff9d1e86ad5f 7415 ssl->options.connectState = HELLO_AGAIN;
sPymbed 17:ff9d1e86ad5f 7416 WOLFSSL_MSG("connect state: HELLO_AGAIN");
sPymbed 17:ff9d1e86ad5f 7417 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 7418
sPymbed 17:ff9d1e86ad5f 7419 case HELLO_AGAIN:
sPymbed 17:ff9d1e86ad5f 7420 if (ssl->options.certOnly)
sPymbed 17:ff9d1e86ad5f 7421 return WOLFSSL_SUCCESS;
sPymbed 17:ff9d1e86ad5f 7422
sPymbed 17:ff9d1e86ad5f 7423 if (!ssl->options.tls1_3) {
sPymbed 17:ff9d1e86ad5f 7424 #ifndef WOLFSSL_NO_TLS12
sPymbed 17:ff9d1e86ad5f 7425 if (ssl->options.downgrade)
sPymbed 17:ff9d1e86ad5f 7426 return wolfSSL_connect(ssl);
sPymbed 17:ff9d1e86ad5f 7427 #endif
sPymbed 17:ff9d1e86ad5f 7428
sPymbed 17:ff9d1e86ad5f 7429 WOLFSSL_MSG("Client using higher version, fatal error");
sPymbed 17:ff9d1e86ad5f 7430 return VERSION_ERROR;
sPymbed 17:ff9d1e86ad5f 7431 }
sPymbed 17:ff9d1e86ad5f 7432
sPymbed 17:ff9d1e86ad5f 7433 if (ssl->options.serverState ==
sPymbed 17:ff9d1e86ad5f 7434 SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 7435 #if !defined(WOLFSSL_TLS13_DRAFT_18) && \
sPymbed 17:ff9d1e86ad5f 7436 defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
sPymbed 17:ff9d1e86ad5f 7437 if (!ssl->options.sentChangeCipher) {
sPymbed 17:ff9d1e86ad5f 7438 if ((ssl->error = SendChangeCipher(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 7439 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 7440 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7441 }
sPymbed 17:ff9d1e86ad5f 7442 ssl->options.sentChangeCipher = 1;
sPymbed 17:ff9d1e86ad5f 7443 }
sPymbed 17:ff9d1e86ad5f 7444 #endif
sPymbed 17:ff9d1e86ad5f 7445 /* Try again with different security parameters. */
sPymbed 17:ff9d1e86ad5f 7446 if ((ssl->error = SendTls13ClientHello(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 7447 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 7448 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7449 }
sPymbed 17:ff9d1e86ad5f 7450 }
sPymbed 17:ff9d1e86ad5f 7451
sPymbed 17:ff9d1e86ad5f 7452 ssl->options.connectState = HELLO_AGAIN_REPLY;
sPymbed 17:ff9d1e86ad5f 7453 WOLFSSL_MSG("connect state: HELLO_AGAIN_REPLY");
sPymbed 17:ff9d1e86ad5f 7454 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 7455
sPymbed 17:ff9d1e86ad5f 7456 case HELLO_AGAIN_REPLY:
sPymbed 17:ff9d1e86ad5f 7457 /* Get the response/s from the server. */
sPymbed 17:ff9d1e86ad5f 7458 while (ssl->options.serverState < SERVER_FINISHED_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 7459 if ((ssl->error = ProcessReply(ssl)) < 0) {
sPymbed 17:ff9d1e86ad5f 7460 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 7461 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7462 }
sPymbed 17:ff9d1e86ad5f 7463 }
sPymbed 17:ff9d1e86ad5f 7464
sPymbed 17:ff9d1e86ad5f 7465 ssl->options.connectState = FIRST_REPLY_DONE;
sPymbed 17:ff9d1e86ad5f 7466 WOLFSSL_MSG("connect state: FIRST_REPLY_DONE");
sPymbed 17:ff9d1e86ad5f 7467 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 7468
sPymbed 17:ff9d1e86ad5f 7469 case FIRST_REPLY_DONE:
sPymbed 17:ff9d1e86ad5f 7470 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 7471 if (ssl->earlyData != no_early_data) {
sPymbed 17:ff9d1e86ad5f 7472 if ((ssl->error = SendTls13EndOfEarlyData(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 7473 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 7474 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7475 }
sPymbed 17:ff9d1e86ad5f 7476 WOLFSSL_MSG("sent: end_of_early_data");
sPymbed 17:ff9d1e86ad5f 7477 }
sPymbed 17:ff9d1e86ad5f 7478 #endif
sPymbed 17:ff9d1e86ad5f 7479
sPymbed 17:ff9d1e86ad5f 7480 ssl->options.connectState = FIRST_REPLY_FIRST;
sPymbed 17:ff9d1e86ad5f 7481 WOLFSSL_MSG("connect state: FIRST_REPLY_FIRST");
sPymbed 17:ff9d1e86ad5f 7482 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 7483
sPymbed 17:ff9d1e86ad5f 7484 case FIRST_REPLY_FIRST:
sPymbed 17:ff9d1e86ad5f 7485 #if !defined(WOLFSSL_TLS13_DRAFT_18) && \
sPymbed 17:ff9d1e86ad5f 7486 defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
sPymbed 17:ff9d1e86ad5f 7487 if (!ssl->options.sentChangeCipher) {
sPymbed 17:ff9d1e86ad5f 7488 if ((ssl->error = SendChangeCipher(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 7489 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 7490 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7491 }
sPymbed 17:ff9d1e86ad5f 7492 ssl->options.sentChangeCipher = 1;
sPymbed 17:ff9d1e86ad5f 7493 }
sPymbed 17:ff9d1e86ad5f 7494 #endif
sPymbed 17:ff9d1e86ad5f 7495
sPymbed 17:ff9d1e86ad5f 7496 ssl->options.connectState = FIRST_REPLY_SECOND;
sPymbed 17:ff9d1e86ad5f 7497 WOLFSSL_MSG("connect state: FIRST_REPLY_SECOND");
sPymbed 17:ff9d1e86ad5f 7498 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 7499
sPymbed 17:ff9d1e86ad5f 7500 case FIRST_REPLY_SECOND:
sPymbed 17:ff9d1e86ad5f 7501 #ifndef NO_CERTS
sPymbed 17:ff9d1e86ad5f 7502 if (!ssl->options.resuming && ssl->options.sendVerify) {
sPymbed 17:ff9d1e86ad5f 7503 ssl->error = SendTls13Certificate(ssl);
sPymbed 17:ff9d1e86ad5f 7504 if (ssl->error != 0) {
sPymbed 17:ff9d1e86ad5f 7505 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 7506 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7507 }
sPymbed 17:ff9d1e86ad5f 7508 WOLFSSL_MSG("sent: certificate");
sPymbed 17:ff9d1e86ad5f 7509 }
sPymbed 17:ff9d1e86ad5f 7510 #endif
sPymbed 17:ff9d1e86ad5f 7511
sPymbed 17:ff9d1e86ad5f 7512 ssl->options.connectState = FIRST_REPLY_THIRD;
sPymbed 17:ff9d1e86ad5f 7513 WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD");
sPymbed 17:ff9d1e86ad5f 7514 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 7515
sPymbed 17:ff9d1e86ad5f 7516 case FIRST_REPLY_THIRD:
sPymbed 17:ff9d1e86ad5f 7517 #ifndef NO_CERTS
sPymbed 17:ff9d1e86ad5f 7518 if (!ssl->options.resuming && ssl->options.sendVerify) {
sPymbed 17:ff9d1e86ad5f 7519 ssl->error = SendTls13CertificateVerify(ssl);
sPymbed 17:ff9d1e86ad5f 7520 if (ssl->error != 0) {
sPymbed 17:ff9d1e86ad5f 7521 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 7522 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7523 }
sPymbed 17:ff9d1e86ad5f 7524 WOLFSSL_MSG("sent: certificate verify");
sPymbed 17:ff9d1e86ad5f 7525 }
sPymbed 17:ff9d1e86ad5f 7526 #endif
sPymbed 17:ff9d1e86ad5f 7527
sPymbed 17:ff9d1e86ad5f 7528 ssl->options.connectState = FIRST_REPLY_FOURTH;
sPymbed 17:ff9d1e86ad5f 7529 WOLFSSL_MSG("connect state: FIRST_REPLY_FOURTH");
sPymbed 17:ff9d1e86ad5f 7530 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 7531
sPymbed 17:ff9d1e86ad5f 7532 case FIRST_REPLY_FOURTH:
sPymbed 17:ff9d1e86ad5f 7533 if ((ssl->error = SendTls13Finished(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 7534 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 7535 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7536 }
sPymbed 17:ff9d1e86ad5f 7537 WOLFSSL_MSG("sent: finished");
sPymbed 17:ff9d1e86ad5f 7538
sPymbed 17:ff9d1e86ad5f 7539 ssl->options.connectState = FINISHED_DONE;
sPymbed 17:ff9d1e86ad5f 7540 WOLFSSL_MSG("connect state: FINISHED_DONE");
sPymbed 17:ff9d1e86ad5f 7541 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 7542
sPymbed 17:ff9d1e86ad5f 7543 case FINISHED_DONE:
sPymbed 17:ff9d1e86ad5f 7544 #ifndef NO_HANDSHAKE_DONE_CB
sPymbed 17:ff9d1e86ad5f 7545 if (ssl->hsDoneCb != NULL) {
sPymbed 17:ff9d1e86ad5f 7546 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
sPymbed 17:ff9d1e86ad5f 7547 if (cbret < 0) {
sPymbed 17:ff9d1e86ad5f 7548 ssl->error = cbret;
sPymbed 17:ff9d1e86ad5f 7549 WOLFSSL_MSG("HandShake Done Cb don't continue error");
sPymbed 17:ff9d1e86ad5f 7550 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7551 }
sPymbed 17:ff9d1e86ad5f 7552 }
sPymbed 17:ff9d1e86ad5f 7553 #endif /* NO_HANDSHAKE_DONE_CB */
sPymbed 17:ff9d1e86ad5f 7554
sPymbed 17:ff9d1e86ad5f 7555 WOLFSSL_LEAVE("wolfSSL_connect_TLSv13()", WOLFSSL_SUCCESS);
sPymbed 17:ff9d1e86ad5f 7556 return WOLFSSL_SUCCESS;
sPymbed 17:ff9d1e86ad5f 7557
sPymbed 17:ff9d1e86ad5f 7558 default:
sPymbed 17:ff9d1e86ad5f 7559 WOLFSSL_MSG("Unknown connect state ERROR");
sPymbed 17:ff9d1e86ad5f 7560 return WOLFSSL_FATAL_ERROR; /* unknown connect state */
sPymbed 17:ff9d1e86ad5f 7561 }
sPymbed 17:ff9d1e86ad5f 7562 }
sPymbed 17:ff9d1e86ad5f 7563 #endif
sPymbed 17:ff9d1e86ad5f 7564
sPymbed 17:ff9d1e86ad5f 7565 #if defined(WOLFSSL_SEND_HRR_COOKIE)
sPymbed 17:ff9d1e86ad5f 7566 /* Send a cookie with the HelloRetryRequest to avoid storing state.
sPymbed 17:ff9d1e86ad5f 7567 *
sPymbed 17:ff9d1e86ad5f 7568 * ssl SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 7569 * secret Secret to use when generating integrity check for cookie.
sPymbed 17:ff9d1e86ad5f 7570 * A value of NULL indicates to generate a new random secret.
sPymbed 17:ff9d1e86ad5f 7571 * secretSz Size of secret data in bytes.
sPymbed 17:ff9d1e86ad5f 7572 * Use a value of 0 to indicate use of default size.
sPymbed 17:ff9d1e86ad5f 7573 * returns BAD_FUNC_ARG when ssl is NULL or not using TLS v1.3, SIDE_ERROR when
sPymbed 17:ff9d1e86ad5f 7574 * called on a client; WOLFSSL_SUCCESS on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 7575 */
sPymbed 17:ff9d1e86ad5f 7576 int wolfSSL_send_hrr_cookie(WOLFSSL* ssl, const unsigned char* secret,
sPymbed 17:ff9d1e86ad5f 7577 unsigned int secretSz)
sPymbed 17:ff9d1e86ad5f 7578 {
sPymbed 17:ff9d1e86ad5f 7579 int ret;
sPymbed 17:ff9d1e86ad5f 7580
sPymbed 17:ff9d1e86ad5f 7581 if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
sPymbed 17:ff9d1e86ad5f 7582 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7583 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 7584 if (ssl->options.side == WOLFSSL_CLIENT_END)
sPymbed 17:ff9d1e86ad5f 7585 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 7586
sPymbed 17:ff9d1e86ad5f 7587 if (secretSz == 0) {
sPymbed 17:ff9d1e86ad5f 7588 #if !defined(NO_SHA) && defined(NO_SHA256)
sPymbed 17:ff9d1e86ad5f 7589 secretSz = WC_SHA_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 7590 #endif /* NO_SHA */
sPymbed 17:ff9d1e86ad5f 7591 #ifndef NO_SHA256
sPymbed 17:ff9d1e86ad5f 7592 secretSz = WC_SHA256_DIGEST_SIZE;
sPymbed 17:ff9d1e86ad5f 7593 #endif /* NO_SHA256 */
sPymbed 17:ff9d1e86ad5f 7594 }
sPymbed 17:ff9d1e86ad5f 7595
sPymbed 17:ff9d1e86ad5f 7596 if (secretSz != ssl->buffers.tls13CookieSecret.length) {
sPymbed 17:ff9d1e86ad5f 7597 byte* newSecret;
sPymbed 17:ff9d1e86ad5f 7598
sPymbed 17:ff9d1e86ad5f 7599 if (ssl->buffers.tls13CookieSecret.buffer != NULL) {
sPymbed 17:ff9d1e86ad5f 7600 ForceZero(ssl->buffers.tls13CookieSecret.buffer,
sPymbed 17:ff9d1e86ad5f 7601 ssl->buffers.tls13CookieSecret.length);
sPymbed 17:ff9d1e86ad5f 7602 XFREE(ssl->buffers.tls13CookieSecret.buffer,
sPymbed 17:ff9d1e86ad5f 7603 ssl->heap, DYNAMIC_TYPE_COOKIE_PWD);
sPymbed 17:ff9d1e86ad5f 7604 }
sPymbed 17:ff9d1e86ad5f 7605
sPymbed 17:ff9d1e86ad5f 7606 newSecret = (byte*)XMALLOC(secretSz, ssl->heap,
sPymbed 17:ff9d1e86ad5f 7607 DYNAMIC_TYPE_COOKIE_PWD);
sPymbed 17:ff9d1e86ad5f 7608 if (newSecret == NULL) {
sPymbed 17:ff9d1e86ad5f 7609 ssl->buffers.tls13CookieSecret.buffer = NULL;
sPymbed 17:ff9d1e86ad5f 7610 ssl->buffers.tls13CookieSecret.length = 0;
sPymbed 17:ff9d1e86ad5f 7611 WOLFSSL_MSG("couldn't allocate new cookie secret");
sPymbed 17:ff9d1e86ad5f 7612 return MEMORY_ERROR;
sPymbed 17:ff9d1e86ad5f 7613 }
sPymbed 17:ff9d1e86ad5f 7614 ssl->buffers.tls13CookieSecret.buffer = newSecret;
sPymbed 17:ff9d1e86ad5f 7615 ssl->buffers.tls13CookieSecret.length = secretSz;
sPymbed 17:ff9d1e86ad5f 7616 }
sPymbed 17:ff9d1e86ad5f 7617
sPymbed 17:ff9d1e86ad5f 7618 /* If the supplied secret is NULL, randomly generate a new secret. */
sPymbed 17:ff9d1e86ad5f 7619 if (secret == NULL) {
sPymbed 17:ff9d1e86ad5f 7620 ret = wc_RNG_GenerateBlock(ssl->rng,
sPymbed 17:ff9d1e86ad5f 7621 ssl->buffers.tls13CookieSecret.buffer, secretSz);
sPymbed 17:ff9d1e86ad5f 7622 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 7623 return ret;
sPymbed 17:ff9d1e86ad5f 7624 }
sPymbed 17:ff9d1e86ad5f 7625 else
sPymbed 17:ff9d1e86ad5f 7626 XMEMCPY(ssl->buffers.tls13CookieSecret.buffer, secret, secretSz);
sPymbed 17:ff9d1e86ad5f 7627
sPymbed 17:ff9d1e86ad5f 7628 ssl->options.sendCookie = 1;
sPymbed 17:ff9d1e86ad5f 7629
sPymbed 17:ff9d1e86ad5f 7630 ret = WOLFSSL_SUCCESS;
sPymbed 17:ff9d1e86ad5f 7631 #else
sPymbed 17:ff9d1e86ad5f 7632 (void)secret;
sPymbed 17:ff9d1e86ad5f 7633 (void)secretSz;
sPymbed 17:ff9d1e86ad5f 7634
sPymbed 17:ff9d1e86ad5f 7635 ret = SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 7636 #endif
sPymbed 17:ff9d1e86ad5f 7637
sPymbed 17:ff9d1e86ad5f 7638 return ret;
sPymbed 17:ff9d1e86ad5f 7639 }
sPymbed 17:ff9d1e86ad5f 7640 #endif
sPymbed 17:ff9d1e86ad5f 7641
sPymbed 17:ff9d1e86ad5f 7642 /* Create a key share entry from group.
sPymbed 17:ff9d1e86ad5f 7643 * Generates a key pair.
sPymbed 17:ff9d1e86ad5f 7644 *
sPymbed 17:ff9d1e86ad5f 7645 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 7646 * group The named group.
sPymbed 17:ff9d1e86ad5f 7647 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 7648 */
sPymbed 17:ff9d1e86ad5f 7649 int wolfSSL_UseKeyShare(WOLFSSL* ssl, word16 group)
sPymbed 17:ff9d1e86ad5f 7650 {
sPymbed 17:ff9d1e86ad5f 7651 int ret;
sPymbed 17:ff9d1e86ad5f 7652
sPymbed 17:ff9d1e86ad5f 7653 if (ssl == NULL)
sPymbed 17:ff9d1e86ad5f 7654 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7655
sPymbed 17:ff9d1e86ad5f 7656 ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL);
sPymbed 17:ff9d1e86ad5f 7657 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 7658 return ret;
sPymbed 17:ff9d1e86ad5f 7659
sPymbed 17:ff9d1e86ad5f 7660 return WOLFSSL_SUCCESS;
sPymbed 17:ff9d1e86ad5f 7661 }
sPymbed 17:ff9d1e86ad5f 7662
sPymbed 17:ff9d1e86ad5f 7663 /* Send no key share entries - use HelloRetryRequest to negotiate shared group.
sPymbed 17:ff9d1e86ad5f 7664 *
sPymbed 17:ff9d1e86ad5f 7665 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 7666 * returns 0 on success, otherwise failure.
sPymbed 17:ff9d1e86ad5f 7667 */
sPymbed 17:ff9d1e86ad5f 7668 int wolfSSL_NoKeyShares(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 7669 {
sPymbed 17:ff9d1e86ad5f 7670 int ret;
sPymbed 17:ff9d1e86ad5f 7671
sPymbed 17:ff9d1e86ad5f 7672 if (ssl == NULL)
sPymbed 17:ff9d1e86ad5f 7673 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7674 if (ssl->options.side == WOLFSSL_SERVER_END)
sPymbed 17:ff9d1e86ad5f 7675 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 7676
sPymbed 17:ff9d1e86ad5f 7677 ret = TLSX_KeyShare_Empty(ssl);
sPymbed 17:ff9d1e86ad5f 7678 if (ret != 0)
sPymbed 17:ff9d1e86ad5f 7679 return ret;
sPymbed 17:ff9d1e86ad5f 7680
sPymbed 17:ff9d1e86ad5f 7681 return WOLFSSL_SUCCESS;
sPymbed 17:ff9d1e86ad5f 7682 }
sPymbed 17:ff9d1e86ad5f 7683
sPymbed 17:ff9d1e86ad5f 7684 /* Do not send a ticket after TLS v1.3 handshake for resumption.
sPymbed 17:ff9d1e86ad5f 7685 *
sPymbed 17:ff9d1e86ad5f 7686 * ctx The SSL/TLS CTX object.
sPymbed 17:ff9d1e86ad5f 7687 * returns BAD_FUNC_ARG when ctx is NULL and 0 on success.
sPymbed 17:ff9d1e86ad5f 7688 */
sPymbed 17:ff9d1e86ad5f 7689 int wolfSSL_CTX_no_ticket_TLSv13(WOLFSSL_CTX* ctx)
sPymbed 17:ff9d1e86ad5f 7690 {
sPymbed 17:ff9d1e86ad5f 7691 if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version))
sPymbed 17:ff9d1e86ad5f 7692 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7693 if (ctx->method->side == WOLFSSL_CLIENT_END)
sPymbed 17:ff9d1e86ad5f 7694 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 7695
sPymbed 17:ff9d1e86ad5f 7696 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 7697 ctx->noTicketTls13 = 1;
sPymbed 17:ff9d1e86ad5f 7698 #endif
sPymbed 17:ff9d1e86ad5f 7699
sPymbed 17:ff9d1e86ad5f 7700 return 0;
sPymbed 17:ff9d1e86ad5f 7701 }
sPymbed 17:ff9d1e86ad5f 7702
sPymbed 17:ff9d1e86ad5f 7703 /* Do not send a ticket after TLS v1.3 handshake for resumption.
sPymbed 17:ff9d1e86ad5f 7704 *
sPymbed 17:ff9d1e86ad5f 7705 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 7706 * returns BAD_FUNC_ARG when ssl is NULL, not using TLS v1.3, or called on
sPymbed 17:ff9d1e86ad5f 7707 * a client and 0 on success.
sPymbed 17:ff9d1e86ad5f 7708 */
sPymbed 17:ff9d1e86ad5f 7709 int wolfSSL_no_ticket_TLSv13(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 7710 {
sPymbed 17:ff9d1e86ad5f 7711 if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
sPymbed 17:ff9d1e86ad5f 7712 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7713 if (ssl->options.side == WOLFSSL_CLIENT_END)
sPymbed 17:ff9d1e86ad5f 7714 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 7715
sPymbed 17:ff9d1e86ad5f 7716 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 7717 ssl->options.noTicketTls13 = 1;
sPymbed 17:ff9d1e86ad5f 7718 #endif
sPymbed 17:ff9d1e86ad5f 7719
sPymbed 17:ff9d1e86ad5f 7720 return 0;
sPymbed 17:ff9d1e86ad5f 7721 }
sPymbed 17:ff9d1e86ad5f 7722
sPymbed 17:ff9d1e86ad5f 7723 /* Disallow (EC)DHE key exchange when using pre-shared keys.
sPymbed 17:ff9d1e86ad5f 7724 *
sPymbed 17:ff9d1e86ad5f 7725 * ctx The SSL/TLS CTX object.
sPymbed 17:ff9d1e86ad5f 7726 * returns BAD_FUNC_ARG when ctx is NULL and 0 on success.
sPymbed 17:ff9d1e86ad5f 7727 */
sPymbed 17:ff9d1e86ad5f 7728 int wolfSSL_CTX_no_dhe_psk(WOLFSSL_CTX* ctx)
sPymbed 17:ff9d1e86ad5f 7729 {
sPymbed 17:ff9d1e86ad5f 7730 if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version))
sPymbed 17:ff9d1e86ad5f 7731 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7732
sPymbed 17:ff9d1e86ad5f 7733 ctx->noPskDheKe = 1;
sPymbed 17:ff9d1e86ad5f 7734
sPymbed 17:ff9d1e86ad5f 7735 return 0;
sPymbed 17:ff9d1e86ad5f 7736 }
sPymbed 17:ff9d1e86ad5f 7737
sPymbed 17:ff9d1e86ad5f 7738 /* Disallow (EC)DHE key exchange when using pre-shared keys.
sPymbed 17:ff9d1e86ad5f 7739 *
sPymbed 17:ff9d1e86ad5f 7740 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 7741 * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3 and 0 on
sPymbed 17:ff9d1e86ad5f 7742 * success.
sPymbed 17:ff9d1e86ad5f 7743 */
sPymbed 17:ff9d1e86ad5f 7744 int wolfSSL_no_dhe_psk(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 7745 {
sPymbed 17:ff9d1e86ad5f 7746 if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
sPymbed 17:ff9d1e86ad5f 7747 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7748
sPymbed 17:ff9d1e86ad5f 7749 ssl->options.noPskDheKe = 1;
sPymbed 17:ff9d1e86ad5f 7750
sPymbed 17:ff9d1e86ad5f 7751 return 0;
sPymbed 17:ff9d1e86ad5f 7752 }
sPymbed 17:ff9d1e86ad5f 7753
sPymbed 17:ff9d1e86ad5f 7754 /* Update the keys for encryption and decryption.
sPymbed 17:ff9d1e86ad5f 7755 * If using non-blocking I/O and WOLFSSL_ERROR_WANT_WRITE is returned then
sPymbed 17:ff9d1e86ad5f 7756 * calling wolfSSL_write() will have the message sent when ready.
sPymbed 17:ff9d1e86ad5f 7757 *
sPymbed 17:ff9d1e86ad5f 7758 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 7759 * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
sPymbed 17:ff9d1e86ad5f 7760 * WOLFSSL_ERROR_WANT_WRITE when non-blocking I/O is not ready to write,
sPymbed 17:ff9d1e86ad5f 7761 * WOLFSSL_SUCCESS on success and otherwise failure.
sPymbed 17:ff9d1e86ad5f 7762 */
sPymbed 17:ff9d1e86ad5f 7763 int wolfSSL_update_keys(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 7764 {
sPymbed 17:ff9d1e86ad5f 7765 int ret;
sPymbed 17:ff9d1e86ad5f 7766
sPymbed 17:ff9d1e86ad5f 7767 if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
sPymbed 17:ff9d1e86ad5f 7768 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7769
sPymbed 17:ff9d1e86ad5f 7770 ret = SendTls13KeyUpdate(ssl);
sPymbed 17:ff9d1e86ad5f 7771 if (ret == WANT_WRITE)
sPymbed 17:ff9d1e86ad5f 7772 ret = WOLFSSL_ERROR_WANT_WRITE;
sPymbed 17:ff9d1e86ad5f 7773 else if (ret == 0)
sPymbed 17:ff9d1e86ad5f 7774 ret = WOLFSSL_SUCCESS;
sPymbed 17:ff9d1e86ad5f 7775 return ret;
sPymbed 17:ff9d1e86ad5f 7776 }
sPymbed 17:ff9d1e86ad5f 7777
sPymbed 17:ff9d1e86ad5f 7778 #if !defined(NO_CERTS) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
sPymbed 17:ff9d1e86ad5f 7779 /* Allow post-handshake authentication in TLS v1.3 connections.
sPymbed 17:ff9d1e86ad5f 7780 *
sPymbed 17:ff9d1e86ad5f 7781 * ctx The SSL/TLS CTX object.
sPymbed 17:ff9d1e86ad5f 7782 * returns BAD_FUNC_ARG when ctx is NULL, SIDE_ERROR when not a client and
sPymbed 17:ff9d1e86ad5f 7783 * 0 on success.
sPymbed 17:ff9d1e86ad5f 7784 */
sPymbed 17:ff9d1e86ad5f 7785 int wolfSSL_CTX_allow_post_handshake_auth(WOLFSSL_CTX* ctx)
sPymbed 17:ff9d1e86ad5f 7786 {
sPymbed 17:ff9d1e86ad5f 7787 if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version))
sPymbed 17:ff9d1e86ad5f 7788 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7789 if (ctx->method->side == WOLFSSL_SERVER_END)
sPymbed 17:ff9d1e86ad5f 7790 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 7791
sPymbed 17:ff9d1e86ad5f 7792 ctx->postHandshakeAuth = 1;
sPymbed 17:ff9d1e86ad5f 7793
sPymbed 17:ff9d1e86ad5f 7794 return 0;
sPymbed 17:ff9d1e86ad5f 7795 }
sPymbed 17:ff9d1e86ad5f 7796
sPymbed 17:ff9d1e86ad5f 7797 /* Allow post-handshake authentication in TLS v1.3 connection.
sPymbed 17:ff9d1e86ad5f 7798 *
sPymbed 17:ff9d1e86ad5f 7799 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 7800 * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
sPymbed 17:ff9d1e86ad5f 7801 * SIDE_ERROR when not a client and 0 on success.
sPymbed 17:ff9d1e86ad5f 7802 */
sPymbed 17:ff9d1e86ad5f 7803 int wolfSSL_allow_post_handshake_auth(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 7804 {
sPymbed 17:ff9d1e86ad5f 7805 if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
sPymbed 17:ff9d1e86ad5f 7806 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7807 if (ssl->options.side == WOLFSSL_SERVER_END)
sPymbed 17:ff9d1e86ad5f 7808 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 7809
sPymbed 17:ff9d1e86ad5f 7810 ssl->options.postHandshakeAuth = 1;
sPymbed 17:ff9d1e86ad5f 7811
sPymbed 17:ff9d1e86ad5f 7812 return 0;
sPymbed 17:ff9d1e86ad5f 7813 }
sPymbed 17:ff9d1e86ad5f 7814
sPymbed 17:ff9d1e86ad5f 7815 /* Request a certificate of the client.
sPymbed 17:ff9d1e86ad5f 7816 * Can be called any time after handshake completion.
sPymbed 17:ff9d1e86ad5f 7817 * A maximum of 256 requests can be sent on a connection.
sPymbed 17:ff9d1e86ad5f 7818 *
sPymbed 17:ff9d1e86ad5f 7819 * ssl SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 7820 */
sPymbed 17:ff9d1e86ad5f 7821 int wolfSSL_request_certificate(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 7822 {
sPymbed 17:ff9d1e86ad5f 7823 int ret;
sPymbed 17:ff9d1e86ad5f 7824 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 7825 CertReqCtx* certReqCtx;
sPymbed 17:ff9d1e86ad5f 7826 #endif
sPymbed 17:ff9d1e86ad5f 7827
sPymbed 17:ff9d1e86ad5f 7828 if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
sPymbed 17:ff9d1e86ad5f 7829 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7830 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 7831 if (ssl->options.side == WOLFSSL_CLIENT_END)
sPymbed 17:ff9d1e86ad5f 7832 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 7833 if (ssl->options.handShakeState != HANDSHAKE_DONE)
sPymbed 17:ff9d1e86ad5f 7834 return NOT_READY_ERROR;
sPymbed 17:ff9d1e86ad5f 7835 if (!ssl->options.postHandshakeAuth)
sPymbed 17:ff9d1e86ad5f 7836 return POST_HAND_AUTH_ERROR;
sPymbed 17:ff9d1e86ad5f 7837
sPymbed 17:ff9d1e86ad5f 7838 certReqCtx = (CertReqCtx*)XMALLOC(sizeof(CertReqCtx), ssl->heap,
sPymbed 17:ff9d1e86ad5f 7839 DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 17:ff9d1e86ad5f 7840 if (certReqCtx == NULL)
sPymbed 17:ff9d1e86ad5f 7841 return MEMORY_E;
sPymbed 17:ff9d1e86ad5f 7842 XMEMSET(certReqCtx, 0, sizeof(CertReqCtx));
sPymbed 17:ff9d1e86ad5f 7843 certReqCtx->next = ssl->certReqCtx;
sPymbed 17:ff9d1e86ad5f 7844 certReqCtx->len = 1;
sPymbed 17:ff9d1e86ad5f 7845 if (certReqCtx->next != NULL)
sPymbed 17:ff9d1e86ad5f 7846 certReqCtx->ctx = certReqCtx->next->ctx + 1;
sPymbed 17:ff9d1e86ad5f 7847 ssl->certReqCtx = certReqCtx;
sPymbed 17:ff9d1e86ad5f 7848
sPymbed 17:ff9d1e86ad5f 7849 ssl->msgsReceived.got_certificate = 0;
sPymbed 17:ff9d1e86ad5f 7850 ssl->msgsReceived.got_certificate_verify = 0;
sPymbed 17:ff9d1e86ad5f 7851 ssl->msgsReceived.got_finished = 0;
sPymbed 17:ff9d1e86ad5f 7852
sPymbed 17:ff9d1e86ad5f 7853 ret = SendTls13CertificateRequest(ssl, &certReqCtx->ctx, certReqCtx->len);
sPymbed 17:ff9d1e86ad5f 7854 if (ret == WANT_WRITE)
sPymbed 17:ff9d1e86ad5f 7855 ret = WOLFSSL_ERROR_WANT_WRITE;
sPymbed 17:ff9d1e86ad5f 7856 else if (ret == 0)
sPymbed 17:ff9d1e86ad5f 7857 ret = WOLFSSL_SUCCESS;
sPymbed 17:ff9d1e86ad5f 7858 #else
sPymbed 17:ff9d1e86ad5f 7859 ret = SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 7860 #endif
sPymbed 17:ff9d1e86ad5f 7861
sPymbed 17:ff9d1e86ad5f 7862 return ret;
sPymbed 17:ff9d1e86ad5f 7863 }
sPymbed 17:ff9d1e86ad5f 7864 #endif /* !NO_CERTS && WOLFSSL_POST_HANDSHAKE_AUTH */
sPymbed 17:ff9d1e86ad5f 7865
sPymbed 17:ff9d1e86ad5f 7866 #if !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
sPymbed 17:ff9d1e86ad5f 7867 /* Get the preferred key exchange group.
sPymbed 17:ff9d1e86ad5f 7868 *
sPymbed 17:ff9d1e86ad5f 7869 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 7870 * returns BAD_FUNC_ARG when ssl is NULL or not using TLS v1.3,
sPymbed 17:ff9d1e86ad5f 7871 * SIDE_ERROR when not a client, NOT_READY_ERROR when handshake not complete
sPymbed 17:ff9d1e86ad5f 7872 * and group number on success.
sPymbed 17:ff9d1e86ad5f 7873 */
sPymbed 17:ff9d1e86ad5f 7874 int wolfSSL_preferred_group(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 7875 {
sPymbed 17:ff9d1e86ad5f 7876 if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
sPymbed 17:ff9d1e86ad5f 7877 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7878 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 7879 if (ssl->options.side == WOLFSSL_SERVER_END)
sPymbed 17:ff9d1e86ad5f 7880 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 7881 if (ssl->options.handShakeState != HANDSHAKE_DONE)
sPymbed 17:ff9d1e86ad5f 7882 return NOT_READY_ERROR;
sPymbed 17:ff9d1e86ad5f 7883
sPymbed 17:ff9d1e86ad5f 7884 /* Return supported groups only. */
sPymbed 17:ff9d1e86ad5f 7885 return TLSX_SupportedCurve_Preferred(ssl, 1);
sPymbed 17:ff9d1e86ad5f 7886 #else
sPymbed 17:ff9d1e86ad5f 7887 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 7888 #endif
sPymbed 17:ff9d1e86ad5f 7889 }
sPymbed 17:ff9d1e86ad5f 7890 #endif
sPymbed 17:ff9d1e86ad5f 7891
sPymbed 17:ff9d1e86ad5f 7892 /* Sets the key exchange groups in rank order on a context.
sPymbed 17:ff9d1e86ad5f 7893 *
sPymbed 17:ff9d1e86ad5f 7894 * ctx SSL/TLS context object.
sPymbed 17:ff9d1e86ad5f 7895 * groups Array of groups.
sPymbed 17:ff9d1e86ad5f 7896 * count Number of groups in array.
sPymbed 17:ff9d1e86ad5f 7897 * returns BAD_FUNC_ARG when ctx or groups is NULL, not using TLS v1.3 or
sPymbed 17:ff9d1e86ad5f 7898 * count is greater than WOLFSSL_MAX_GROUP_COUNT and WOLFSSL_SUCCESS on success.
sPymbed 17:ff9d1e86ad5f 7899 */
sPymbed 17:ff9d1e86ad5f 7900 int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups, int count)
sPymbed 17:ff9d1e86ad5f 7901 {
sPymbed 17:ff9d1e86ad5f 7902 int i;
sPymbed 17:ff9d1e86ad5f 7903
sPymbed 17:ff9d1e86ad5f 7904 if (ctx == NULL || groups == NULL || count > WOLFSSL_MAX_GROUP_COUNT)
sPymbed 17:ff9d1e86ad5f 7905 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7906 if (!IsAtLeastTLSv1_3(ctx->method->version))
sPymbed 17:ff9d1e86ad5f 7907 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7908
sPymbed 17:ff9d1e86ad5f 7909 for (i = 0; i < count; i++)
sPymbed 17:ff9d1e86ad5f 7910 ctx->group[i] = (word16)groups[i];
sPymbed 17:ff9d1e86ad5f 7911 ctx->numGroups = (byte)count;
sPymbed 17:ff9d1e86ad5f 7912
sPymbed 17:ff9d1e86ad5f 7913 return WOLFSSL_SUCCESS;
sPymbed 17:ff9d1e86ad5f 7914 }
sPymbed 17:ff9d1e86ad5f 7915
sPymbed 17:ff9d1e86ad5f 7916 /* Sets the key exchange groups in rank order.
sPymbed 17:ff9d1e86ad5f 7917 *
sPymbed 17:ff9d1e86ad5f 7918 * ssl SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 7919 * groups Array of groups.
sPymbed 17:ff9d1e86ad5f 7920 * count Number of groups in array.
sPymbed 17:ff9d1e86ad5f 7921 * returns BAD_FUNC_ARG when ssl or groups is NULL, not using TLS v1.3 or
sPymbed 17:ff9d1e86ad5f 7922 * count is greater than WOLFSSL_MAX_GROUP_COUNT and WOLFSSL_SUCCESS on success.
sPymbed 17:ff9d1e86ad5f 7923 */
sPymbed 17:ff9d1e86ad5f 7924 int wolfSSL_set_groups(WOLFSSL* ssl, int* groups, int count)
sPymbed 17:ff9d1e86ad5f 7925 {
sPymbed 17:ff9d1e86ad5f 7926 int i;
sPymbed 17:ff9d1e86ad5f 7927
sPymbed 17:ff9d1e86ad5f 7928 if (ssl == NULL || groups == NULL || count > WOLFSSL_MAX_GROUP_COUNT)
sPymbed 17:ff9d1e86ad5f 7929 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7930 if (!IsAtLeastTLSv1_3(ssl->version))
sPymbed 17:ff9d1e86ad5f 7931 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 7932
sPymbed 17:ff9d1e86ad5f 7933 for (i = 0; i < count; i++)
sPymbed 17:ff9d1e86ad5f 7934 ssl->group[i] = (word16)groups[i];
sPymbed 17:ff9d1e86ad5f 7935 ssl->numGroups = (byte)count;
sPymbed 17:ff9d1e86ad5f 7936
sPymbed 17:ff9d1e86ad5f 7937 return WOLFSSL_SUCCESS;
sPymbed 17:ff9d1e86ad5f 7938 }
sPymbed 17:ff9d1e86ad5f 7939
sPymbed 17:ff9d1e86ad5f 7940 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 7941 /* The server accepting a connection from a client.
sPymbed 17:ff9d1e86ad5f 7942 * The protocol version is expecting to be TLS v1.3.
sPymbed 17:ff9d1e86ad5f 7943 * If the client downgrades, and older versions of the protocol are compiled
sPymbed 17:ff9d1e86ad5f 7944 * in, the server will fallback to wolfSSL_accept().
sPymbed 17:ff9d1e86ad5f 7945 * Please see note at top of README if you get an error from accept.
sPymbed 17:ff9d1e86ad5f 7946 *
sPymbed 17:ff9d1e86ad5f 7947 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 7948 * returns WOLFSSL_SUCCESS on successful handshake, WOLFSSL_FATAL_ERROR when
sPymbed 17:ff9d1e86ad5f 7949 * unrecoverable error occurs and 0 otherwise.
sPymbed 17:ff9d1e86ad5f 7950 * For more error information use wolfSSL_get_error().
sPymbed 17:ff9d1e86ad5f 7951 */
sPymbed 17:ff9d1e86ad5f 7952 int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
sPymbed 17:ff9d1e86ad5f 7953 {
sPymbed 17:ff9d1e86ad5f 7954 word16 havePSK = 0;
sPymbed 17:ff9d1e86ad5f 7955 WOLFSSL_ENTER("SSL_accept_TLSv13()");
sPymbed 17:ff9d1e86ad5f 7956
sPymbed 17:ff9d1e86ad5f 7957 #ifdef HAVE_ERRNO_H
sPymbed 17:ff9d1e86ad5f 7958 errno = 0;
sPymbed 17:ff9d1e86ad5f 7959 #endif
sPymbed 17:ff9d1e86ad5f 7960
sPymbed 17:ff9d1e86ad5f 7961 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
sPymbed 17:ff9d1e86ad5f 7962 havePSK = ssl->options.havePSK;
sPymbed 17:ff9d1e86ad5f 7963 #endif
sPymbed 17:ff9d1e86ad5f 7964 (void)havePSK;
sPymbed 17:ff9d1e86ad5f 7965
sPymbed 17:ff9d1e86ad5f 7966 if (ssl->options.side != WOLFSSL_SERVER_END) {
sPymbed 17:ff9d1e86ad5f 7967 WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
sPymbed 17:ff9d1e86ad5f 7968 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7969 }
sPymbed 17:ff9d1e86ad5f 7970
sPymbed 17:ff9d1e86ad5f 7971 #ifndef NO_CERTS
sPymbed 17:ff9d1e86ad5f 7972 /* allow no private key if using PK callbacks and CB is set */
sPymbed 17:ff9d1e86ad5f 7973 if (!havePSK) {
sPymbed 17:ff9d1e86ad5f 7974 if (!ssl->buffers.certificate ||
sPymbed 17:ff9d1e86ad5f 7975 !ssl->buffers.certificate->buffer) {
sPymbed 17:ff9d1e86ad5f 7976
sPymbed 17:ff9d1e86ad5f 7977 WOLFSSL_MSG("accept error: server cert required");
sPymbed 17:ff9d1e86ad5f 7978 WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY);
sPymbed 17:ff9d1e86ad5f 7979 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7980 }
sPymbed 17:ff9d1e86ad5f 7981
sPymbed 17:ff9d1e86ad5f 7982 #ifdef HAVE_PK_CALLBACKS
sPymbed 17:ff9d1e86ad5f 7983 if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) {
sPymbed 17:ff9d1e86ad5f 7984 WOLFSSL_MSG("Using PK for server private key");
sPymbed 17:ff9d1e86ad5f 7985 }
sPymbed 17:ff9d1e86ad5f 7986 else
sPymbed 17:ff9d1e86ad5f 7987 #endif
sPymbed 17:ff9d1e86ad5f 7988 if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
sPymbed 17:ff9d1e86ad5f 7989 WOLFSSL_MSG("accept error: server key required");
sPymbed 17:ff9d1e86ad5f 7990 WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY);
sPymbed 17:ff9d1e86ad5f 7991 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 7992 }
sPymbed 17:ff9d1e86ad5f 7993 }
sPymbed 17:ff9d1e86ad5f 7994 #endif
sPymbed 17:ff9d1e86ad5f 7995
sPymbed 17:ff9d1e86ad5f 7996 if (ssl->buffers.outputBuffer.length > 0) {
sPymbed 17:ff9d1e86ad5f 7997 if ((ssl->error = SendBuffered(ssl)) == 0) {
sPymbed 17:ff9d1e86ad5f 7998 /* fragOffset is non-zero when sending fragments. On the last
sPymbed 17:ff9d1e86ad5f 7999 * fragment, fragOffset is zero again, and the state can be
sPymbed 17:ff9d1e86ad5f 8000 * advanced. */
sPymbed 17:ff9d1e86ad5f 8001 if (ssl->fragOffset == 0) {
sPymbed 17:ff9d1e86ad5f 8002 ssl->options.acceptState++;
sPymbed 17:ff9d1e86ad5f 8003 WOLFSSL_MSG("accept state: "
sPymbed 17:ff9d1e86ad5f 8004 "Advanced from last buffered fragment send");
sPymbed 17:ff9d1e86ad5f 8005 }
sPymbed 17:ff9d1e86ad5f 8006 else {
sPymbed 17:ff9d1e86ad5f 8007 WOLFSSL_MSG("accept state: "
sPymbed 17:ff9d1e86ad5f 8008 "Not advanced, more fragments to send");
sPymbed 17:ff9d1e86ad5f 8009 }
sPymbed 17:ff9d1e86ad5f 8010 }
sPymbed 17:ff9d1e86ad5f 8011 else {
sPymbed 17:ff9d1e86ad5f 8012 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8013 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8014 }
sPymbed 17:ff9d1e86ad5f 8015 }
sPymbed 17:ff9d1e86ad5f 8016
sPymbed 17:ff9d1e86ad5f 8017 switch (ssl->options.acceptState) {
sPymbed 17:ff9d1e86ad5f 8018
sPymbed 17:ff9d1e86ad5f 8019 case TLS13_ACCEPT_BEGIN :
sPymbed 17:ff9d1e86ad5f 8020 /* get client_hello */
sPymbed 17:ff9d1e86ad5f 8021 while (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 8022 if ((ssl->error = ProcessReply(ssl)) < 0) {
sPymbed 17:ff9d1e86ad5f 8023 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8024 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8025 }
sPymbed 17:ff9d1e86ad5f 8026 }
sPymbed 17:ff9d1e86ad5f 8027
sPymbed 17:ff9d1e86ad5f 8028 ssl->options.acceptState = TLS13_ACCEPT_CLIENT_HELLO_DONE;
sPymbed 17:ff9d1e86ad5f 8029 WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
sPymbed 17:ff9d1e86ad5f 8030 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8031
sPymbed 17:ff9d1e86ad5f 8032 case TLS13_ACCEPT_CLIENT_HELLO_DONE :
sPymbed 17:ff9d1e86ad5f 8033 #ifdef WOLFSSL_TLS13_DRAFT_18
sPymbed 17:ff9d1e86ad5f 8034 if (ssl->options.serverState ==
sPymbed 17:ff9d1e86ad5f 8035 SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 8036 if ((ssl->error = SendTls13HelloRetryRequest(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 8037 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8038 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8039 }
sPymbed 17:ff9d1e86ad5f 8040 }
sPymbed 17:ff9d1e86ad5f 8041
sPymbed 17:ff9d1e86ad5f 8042 ssl->options.acceptState = TLS13_ACCEPT_FIRST_REPLY_DONE;
sPymbed 17:ff9d1e86ad5f 8043 WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
sPymbed 17:ff9d1e86ad5f 8044 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8045
sPymbed 17:ff9d1e86ad5f 8046 case TLS13_ACCEPT_HELLO_RETRY_REQUEST_DONE :
sPymbed 17:ff9d1e86ad5f 8047 #else
sPymbed 17:ff9d1e86ad5f 8048 if (ssl->options.serverState ==
sPymbed 17:ff9d1e86ad5f 8049 SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 8050 if ((ssl->error = SendTls13ServerHello(ssl,
sPymbed 17:ff9d1e86ad5f 8051 hello_retry_request)) != 0) {
sPymbed 17:ff9d1e86ad5f 8052 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8053 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8054 }
sPymbed 17:ff9d1e86ad5f 8055 }
sPymbed 17:ff9d1e86ad5f 8056
sPymbed 17:ff9d1e86ad5f 8057 ssl->options.acceptState = TLS13_ACCEPT_HELLO_RETRY_REQUEST_DONE;
sPymbed 17:ff9d1e86ad5f 8058 WOLFSSL_MSG("accept state ACCEPT_HELLO_RETRY_REQUEST_DONE");
sPymbed 17:ff9d1e86ad5f 8059 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8060
sPymbed 17:ff9d1e86ad5f 8061 case TLS13_ACCEPT_HELLO_RETRY_REQUEST_DONE :
sPymbed 17:ff9d1e86ad5f 8062 #ifdef WOLFSSL_TLS13_MIDDLEBOX_COMPAT
sPymbed 17:ff9d1e86ad5f 8063 if (ssl->options.serverState ==
sPymbed 17:ff9d1e86ad5f 8064 SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 8065 if ((ssl->error = SendChangeCipher(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 8066 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8067 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8068 }
sPymbed 17:ff9d1e86ad5f 8069 ssl->options.sentChangeCipher = 1;
sPymbed 17:ff9d1e86ad5f 8070 }
sPymbed 17:ff9d1e86ad5f 8071 #endif
sPymbed 17:ff9d1e86ad5f 8072 ssl->options.acceptState = TLS13_ACCEPT_FIRST_REPLY_DONE;
sPymbed 17:ff9d1e86ad5f 8073 WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
sPymbed 17:ff9d1e86ad5f 8074 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8075 #endif
sPymbed 17:ff9d1e86ad5f 8076
sPymbed 17:ff9d1e86ad5f 8077 case TLS13_ACCEPT_FIRST_REPLY_DONE :
sPymbed 17:ff9d1e86ad5f 8078 if (ssl->options.serverState ==
sPymbed 17:ff9d1e86ad5f 8079 SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 8080 ssl->options.clientState = NULL_STATE;
sPymbed 17:ff9d1e86ad5f 8081 while (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 8082 if ((ssl->error = ProcessReply(ssl)) < 0) {
sPymbed 17:ff9d1e86ad5f 8083 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8084 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8085 }
sPymbed 17:ff9d1e86ad5f 8086 }
sPymbed 17:ff9d1e86ad5f 8087 }
sPymbed 17:ff9d1e86ad5f 8088
sPymbed 17:ff9d1e86ad5f 8089 ssl->options.acceptState = TLS13_ACCEPT_SECOND_REPLY_DONE;
sPymbed 17:ff9d1e86ad5f 8090 WOLFSSL_MSG("accept state ACCEPT_SECOND_REPLY_DONE");
sPymbed 17:ff9d1e86ad5f 8091 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8092
sPymbed 17:ff9d1e86ad5f 8093 case TLS13_ACCEPT_SECOND_REPLY_DONE :
sPymbed 17:ff9d1e86ad5f 8094 if ((ssl->error = SendTls13ServerHello(ssl, server_hello)) != 0) {
sPymbed 17:ff9d1e86ad5f 8095 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8096 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8097 }
sPymbed 17:ff9d1e86ad5f 8098 ssl->options.acceptState = TLS13_SERVER_HELLO_SENT;
sPymbed 17:ff9d1e86ad5f 8099 WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
sPymbed 17:ff9d1e86ad5f 8100 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8101
sPymbed 17:ff9d1e86ad5f 8102 case TLS13_SERVER_HELLO_SENT :
sPymbed 17:ff9d1e86ad5f 8103 #if !defined(WOLFSSL_TLS13_DRAFT_18) && \
sPymbed 17:ff9d1e86ad5f 8104 defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
sPymbed 17:ff9d1e86ad5f 8105 if (!ssl->options.sentChangeCipher) {
sPymbed 17:ff9d1e86ad5f 8106 if ((ssl->error = SendChangeCipher(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 8107 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8108 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8109 }
sPymbed 17:ff9d1e86ad5f 8110 ssl->options.sentChangeCipher = 1;
sPymbed 17:ff9d1e86ad5f 8111 }
sPymbed 17:ff9d1e86ad5f 8112 #endif
sPymbed 17:ff9d1e86ad5f 8113
sPymbed 17:ff9d1e86ad5f 8114 ssl->options.acceptState = TLS13_ACCEPT_THIRD_REPLY_DONE;
sPymbed 17:ff9d1e86ad5f 8115 WOLFSSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
sPymbed 17:ff9d1e86ad5f 8116 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8117
sPymbed 17:ff9d1e86ad5f 8118 case TLS13_ACCEPT_THIRD_REPLY_DONE :
sPymbed 17:ff9d1e86ad5f 8119 if (!ssl->options.noPskDheKe) {
sPymbed 17:ff9d1e86ad5f 8120 ssl->error = TLSX_KeyShare_DeriveSecret(ssl);
sPymbed 17:ff9d1e86ad5f 8121 if (ssl->error != 0)
sPymbed 17:ff9d1e86ad5f 8122 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8123 }
sPymbed 17:ff9d1e86ad5f 8124
sPymbed 17:ff9d1e86ad5f 8125 if ((ssl->error = SendTls13EncryptedExtensions(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 8126 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8127 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8128 }
sPymbed 17:ff9d1e86ad5f 8129 ssl->options.acceptState = TLS13_SERVER_EXTENSIONS_SENT;
sPymbed 17:ff9d1e86ad5f 8130 WOLFSSL_MSG("accept state SERVER_EXTENSIONS_SENT");
sPymbed 17:ff9d1e86ad5f 8131 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8132
sPymbed 17:ff9d1e86ad5f 8133 case TLS13_SERVER_EXTENSIONS_SENT :
sPymbed 17:ff9d1e86ad5f 8134 #ifndef NO_CERTS
sPymbed 17:ff9d1e86ad5f 8135 if (!ssl->options.resuming) {
sPymbed 17:ff9d1e86ad5f 8136 if (ssl->options.verifyPeer) {
sPymbed 17:ff9d1e86ad5f 8137 ssl->error = SendTls13CertificateRequest(ssl, NULL, 0);
sPymbed 17:ff9d1e86ad5f 8138 if (ssl->error != 0) {
sPymbed 17:ff9d1e86ad5f 8139 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8140 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8141 }
sPymbed 17:ff9d1e86ad5f 8142 }
sPymbed 17:ff9d1e86ad5f 8143 }
sPymbed 17:ff9d1e86ad5f 8144 #endif
sPymbed 17:ff9d1e86ad5f 8145 ssl->options.acceptState = TLS13_CERT_REQ_SENT;
sPymbed 17:ff9d1e86ad5f 8146 WOLFSSL_MSG("accept state CERT_REQ_SENT");
sPymbed 17:ff9d1e86ad5f 8147 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8148
sPymbed 17:ff9d1e86ad5f 8149 case TLS13_CERT_REQ_SENT :
sPymbed 17:ff9d1e86ad5f 8150 #ifndef NO_CERTS
sPymbed 17:ff9d1e86ad5f 8151 if (!ssl->options.resuming && ssl->options.sendVerify) {
sPymbed 17:ff9d1e86ad5f 8152 if ((ssl->error = SendTls13Certificate(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 8153 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8154 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8155 }
sPymbed 17:ff9d1e86ad5f 8156 }
sPymbed 17:ff9d1e86ad5f 8157 #endif
sPymbed 17:ff9d1e86ad5f 8158 ssl->options.acceptState = TLS13_CERT_SENT;
sPymbed 17:ff9d1e86ad5f 8159 WOLFSSL_MSG("accept state CERT_SENT");
sPymbed 17:ff9d1e86ad5f 8160 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8161
sPymbed 17:ff9d1e86ad5f 8162 case TLS13_CERT_SENT :
sPymbed 17:ff9d1e86ad5f 8163 #ifndef NO_CERTS
sPymbed 17:ff9d1e86ad5f 8164 if (!ssl->options.resuming && ssl->options.sendVerify) {
sPymbed 17:ff9d1e86ad5f 8165 if ((ssl->error = SendTls13CertificateVerify(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 8166 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8167 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8168 }
sPymbed 17:ff9d1e86ad5f 8169 }
sPymbed 17:ff9d1e86ad5f 8170 #endif
sPymbed 17:ff9d1e86ad5f 8171 ssl->options.acceptState = TLS13_CERT_VERIFY_SENT;
sPymbed 17:ff9d1e86ad5f 8172 WOLFSSL_MSG("accept state CERT_VERIFY_SENT");
sPymbed 17:ff9d1e86ad5f 8173 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8174
sPymbed 17:ff9d1e86ad5f 8175 case TLS13_CERT_VERIFY_SENT :
sPymbed 17:ff9d1e86ad5f 8176 if ((ssl->error = SendTls13Finished(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 8177 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8178 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8179 }
sPymbed 17:ff9d1e86ad5f 8180
sPymbed 17:ff9d1e86ad5f 8181 ssl->options.acceptState = TLS13_ACCEPT_FINISHED_SENT;
sPymbed 17:ff9d1e86ad5f 8182 WOLFSSL_MSG("accept state ACCEPT_FINISHED_SENT");
sPymbed 17:ff9d1e86ad5f 8183 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 8184 if (ssl->earlyData != no_early_data) {
sPymbed 17:ff9d1e86ad5f 8185 ssl->options.handShakeState = SERVER_FINISHED_COMPLETE;
sPymbed 17:ff9d1e86ad5f 8186 return WOLFSSL_SUCCESS;
sPymbed 17:ff9d1e86ad5f 8187 }
sPymbed 17:ff9d1e86ad5f 8188 #endif
sPymbed 17:ff9d1e86ad5f 8189 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8190
sPymbed 17:ff9d1e86ad5f 8191 case TLS13_ACCEPT_FINISHED_SENT :
sPymbed 17:ff9d1e86ad5f 8192 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 8193 #ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
sPymbed 17:ff9d1e86ad5f 8194 if (!ssl->options.resuming && !ssl->options.verifyPeer &&
sPymbed 17:ff9d1e86ad5f 8195 !ssl->options.noTicketTls13 && ssl->ctx->ticketEncCb != NULL) {
sPymbed 17:ff9d1e86ad5f 8196 if ((ssl->error = SendTls13NewSessionTicket(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 8197 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8198 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8199 }
sPymbed 17:ff9d1e86ad5f 8200 }
sPymbed 17:ff9d1e86ad5f 8201 #endif
sPymbed 17:ff9d1e86ad5f 8202 #endif /* HAVE_SESSION_TICKET */
sPymbed 17:ff9d1e86ad5f 8203 ssl->options.acceptState = TLS13_PRE_TICKET_SENT;
sPymbed 17:ff9d1e86ad5f 8204 WOLFSSL_MSG("accept state TICKET_SENT");
sPymbed 17:ff9d1e86ad5f 8205 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8206
sPymbed 17:ff9d1e86ad5f 8207 case TLS13_PRE_TICKET_SENT :
sPymbed 17:ff9d1e86ad5f 8208 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
sPymbed 17:ff9d1e86ad5f 8209 if ( (ssl->error = ProcessReply(ssl)) < 0) {
sPymbed 17:ff9d1e86ad5f 8210 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8211 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8212 }
sPymbed 17:ff9d1e86ad5f 8213
sPymbed 17:ff9d1e86ad5f 8214 ssl->options.acceptState = TLS13_ACCEPT_FINISHED_DONE;
sPymbed 17:ff9d1e86ad5f 8215 WOLFSSL_MSG("accept state ACCEPT_FINISHED_DONE");
sPymbed 17:ff9d1e86ad5f 8216 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8217
sPymbed 17:ff9d1e86ad5f 8218 case TLS13_ACCEPT_FINISHED_DONE :
sPymbed 17:ff9d1e86ad5f 8219 #ifdef HAVE_SESSION_TICKET
sPymbed 17:ff9d1e86ad5f 8220 #ifdef WOLFSSL_TLS13_TICKET_BEFORE_FINISHED
sPymbed 17:ff9d1e86ad5f 8221 if (!ssl->options.verifyPeer) {
sPymbed 17:ff9d1e86ad5f 8222 }
sPymbed 17:ff9d1e86ad5f 8223 else
sPymbed 17:ff9d1e86ad5f 8224 #endif
sPymbed 17:ff9d1e86ad5f 8225 if (!ssl->options.resuming &&
sPymbed 17:ff9d1e86ad5f 8226 !ssl->options.noTicketTls13 && ssl->ctx->ticketEncCb != NULL) {
sPymbed 17:ff9d1e86ad5f 8227 if ((ssl->error = SendTls13NewSessionTicket(ssl)) != 0) {
sPymbed 17:ff9d1e86ad5f 8228 WOLFSSL_ERROR(ssl->error);
sPymbed 17:ff9d1e86ad5f 8229 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8230 }
sPymbed 17:ff9d1e86ad5f 8231 }
sPymbed 17:ff9d1e86ad5f 8232 #endif /* HAVE_SESSION_TICKET */
sPymbed 17:ff9d1e86ad5f 8233 ssl->options.acceptState = TLS13_TICKET_SENT;
sPymbed 17:ff9d1e86ad5f 8234 WOLFSSL_MSG("accept state TICKET_SENT");
sPymbed 17:ff9d1e86ad5f 8235 FALL_THROUGH;
sPymbed 17:ff9d1e86ad5f 8236
sPymbed 17:ff9d1e86ad5f 8237 case TLS13_TICKET_SENT :
sPymbed 17:ff9d1e86ad5f 8238 #ifndef NO_HANDSHAKE_DONE_CB
sPymbed 17:ff9d1e86ad5f 8239 if (ssl->hsDoneCb) {
sPymbed 17:ff9d1e86ad5f 8240 int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
sPymbed 17:ff9d1e86ad5f 8241 if (cbret < 0) {
sPymbed 17:ff9d1e86ad5f 8242 ssl->error = cbret;
sPymbed 17:ff9d1e86ad5f 8243 WOLFSSL_MSG("HandShake Done Cb don't continue error");
sPymbed 17:ff9d1e86ad5f 8244 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8245 }
sPymbed 17:ff9d1e86ad5f 8246 }
sPymbed 17:ff9d1e86ad5f 8247 #endif /* NO_HANDSHAKE_DONE_CB */
sPymbed 17:ff9d1e86ad5f 8248
sPymbed 17:ff9d1e86ad5f 8249 WOLFSSL_LEAVE("SSL_accept()", WOLFSSL_SUCCESS);
sPymbed 17:ff9d1e86ad5f 8250 return WOLFSSL_SUCCESS;
sPymbed 17:ff9d1e86ad5f 8251
sPymbed 17:ff9d1e86ad5f 8252 default :
sPymbed 17:ff9d1e86ad5f 8253 WOLFSSL_MSG("Unknown accept state ERROR");
sPymbed 17:ff9d1e86ad5f 8254 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8255 }
sPymbed 17:ff9d1e86ad5f 8256 }
sPymbed 17:ff9d1e86ad5f 8257 #endif
sPymbed 17:ff9d1e86ad5f 8258
sPymbed 17:ff9d1e86ad5f 8259 #ifdef WOLFSSL_EARLY_DATA
sPymbed 17:ff9d1e86ad5f 8260 /* Sets the maximum amount of early data that can be seen by server when using
sPymbed 17:ff9d1e86ad5f 8261 * session tickets for resumption.
sPymbed 17:ff9d1e86ad5f 8262 * A value of zero indicates no early data is to be sent by client using session
sPymbed 17:ff9d1e86ad5f 8263 * tickets.
sPymbed 17:ff9d1e86ad5f 8264 *
sPymbed 17:ff9d1e86ad5f 8265 * ctx The SSL/TLS CTX object.
sPymbed 17:ff9d1e86ad5f 8266 * sz Maximum size of the early data.
sPymbed 17:ff9d1e86ad5f 8267 * returns BAD_FUNC_ARG when ctx is NULL, SIDE_ERROR when not a server and
sPymbed 17:ff9d1e86ad5f 8268 * 0 on success.
sPymbed 17:ff9d1e86ad5f 8269 */
sPymbed 17:ff9d1e86ad5f 8270 int wolfSSL_CTX_set_max_early_data(WOLFSSL_CTX* ctx, unsigned int sz)
sPymbed 17:ff9d1e86ad5f 8271 {
sPymbed 17:ff9d1e86ad5f 8272 if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version))
sPymbed 17:ff9d1e86ad5f 8273 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 8274 if (ctx->method->side == WOLFSSL_CLIENT_END)
sPymbed 17:ff9d1e86ad5f 8275 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 8276
sPymbed 17:ff9d1e86ad5f 8277 ctx->maxEarlyDataSz = sz;
sPymbed 17:ff9d1e86ad5f 8278
sPymbed 17:ff9d1e86ad5f 8279 return 0;
sPymbed 17:ff9d1e86ad5f 8280 }
sPymbed 17:ff9d1e86ad5f 8281
sPymbed 17:ff9d1e86ad5f 8282 /* Sets the maximum amount of early data that can be seen by server when using
sPymbed 17:ff9d1e86ad5f 8283 * session tickets for resumption.
sPymbed 17:ff9d1e86ad5f 8284 * A value of zero indicates no early data is to be sent by client using session
sPymbed 17:ff9d1e86ad5f 8285 * tickets.
sPymbed 17:ff9d1e86ad5f 8286 *
sPymbed 17:ff9d1e86ad5f 8287 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 8288 * sz Maximum size of the early data.
sPymbed 17:ff9d1e86ad5f 8289 * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
sPymbed 17:ff9d1e86ad5f 8290 * SIDE_ERROR when not a server and 0 on success.
sPymbed 17:ff9d1e86ad5f 8291 */
sPymbed 17:ff9d1e86ad5f 8292 int wolfSSL_set_max_early_data(WOLFSSL* ssl, unsigned int sz)
sPymbed 17:ff9d1e86ad5f 8293 {
sPymbed 17:ff9d1e86ad5f 8294 if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version))
sPymbed 17:ff9d1e86ad5f 8295 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 8296 if (ssl->options.side == WOLFSSL_CLIENT_END)
sPymbed 17:ff9d1e86ad5f 8297 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 8298
sPymbed 17:ff9d1e86ad5f 8299 ssl->options.maxEarlyDataSz = sz;
sPymbed 17:ff9d1e86ad5f 8300
sPymbed 17:ff9d1e86ad5f 8301 return 0;
sPymbed 17:ff9d1e86ad5f 8302 }
sPymbed 17:ff9d1e86ad5f 8303
sPymbed 17:ff9d1e86ad5f 8304 /* Write early data to the server.
sPymbed 17:ff9d1e86ad5f 8305 *
sPymbed 17:ff9d1e86ad5f 8306 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 8307 * data Early data to write
sPymbed 17:ff9d1e86ad5f 8308 * sz The size of the eary data in bytes.
sPymbed 17:ff9d1e86ad5f 8309 * outSz The number of early data bytes written.
sPymbed 17:ff9d1e86ad5f 8310 * returns BAD_FUNC_ARG when: ssl, data or outSz is NULL; sz is negative;
sPymbed 17:ff9d1e86ad5f 8311 * or not using TLS v1.3. SIDE ERROR when not a server. Otherwise the number of
sPymbed 17:ff9d1e86ad5f 8312 * early data bytes written.
sPymbed 17:ff9d1e86ad5f 8313 */
sPymbed 17:ff9d1e86ad5f 8314 int wolfSSL_write_early_data(WOLFSSL* ssl, const void* data, int sz, int* outSz)
sPymbed 17:ff9d1e86ad5f 8315 {
sPymbed 17:ff9d1e86ad5f 8316 int ret = 0;
sPymbed 17:ff9d1e86ad5f 8317
sPymbed 17:ff9d1e86ad5f 8318 WOLFSSL_ENTER("SSL_write_early_data()");
sPymbed 17:ff9d1e86ad5f 8319
sPymbed 17:ff9d1e86ad5f 8320 if (ssl == NULL || data == NULL || sz < 0 || outSz == NULL)
sPymbed 17:ff9d1e86ad5f 8321 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 8322 if (!IsAtLeastTLSv1_3(ssl->version))
sPymbed 17:ff9d1e86ad5f 8323 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 8324
sPymbed 17:ff9d1e86ad5f 8325 #ifndef NO_WOLFSSL_CLIENT
sPymbed 17:ff9d1e86ad5f 8326 if (ssl->options.side == WOLFSSL_SERVER_END)
sPymbed 17:ff9d1e86ad5f 8327 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 8328
sPymbed 17:ff9d1e86ad5f 8329 if (ssl->options.handShakeState == NULL_STATE) {
sPymbed 17:ff9d1e86ad5f 8330 ssl->earlyData = expecting_early_data;
sPymbed 17:ff9d1e86ad5f 8331 ret = wolfSSL_connect_TLSv13(ssl);
sPymbed 17:ff9d1e86ad5f 8332 if (ret <= 0)
sPymbed 17:ff9d1e86ad5f 8333 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8334 }
sPymbed 17:ff9d1e86ad5f 8335 if (ssl->options.handShakeState == CLIENT_HELLO_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 8336 ret = SendData(ssl, data, sz);
sPymbed 17:ff9d1e86ad5f 8337 if (ret > 0)
sPymbed 17:ff9d1e86ad5f 8338 *outSz = ret;
sPymbed 17:ff9d1e86ad5f 8339 }
sPymbed 17:ff9d1e86ad5f 8340 #else
sPymbed 17:ff9d1e86ad5f 8341 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 8342 #endif
sPymbed 17:ff9d1e86ad5f 8343
sPymbed 17:ff9d1e86ad5f 8344 WOLFSSL_LEAVE("SSL_write_early_data()", ret);
sPymbed 17:ff9d1e86ad5f 8345
sPymbed 17:ff9d1e86ad5f 8346 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 8347 ret = WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8348 return ret;
sPymbed 17:ff9d1e86ad5f 8349 }
sPymbed 17:ff9d1e86ad5f 8350
sPymbed 17:ff9d1e86ad5f 8351 /* Read the any early data from the client.
sPymbed 17:ff9d1e86ad5f 8352 *
sPymbed 17:ff9d1e86ad5f 8353 * ssl The SSL/TLS object.
sPymbed 17:ff9d1e86ad5f 8354 * data Buffer to put the early data into.
sPymbed 17:ff9d1e86ad5f 8355 * sz The size of the buffer in bytes.
sPymbed 17:ff9d1e86ad5f 8356 * outSz The number of early data bytes read.
sPymbed 17:ff9d1e86ad5f 8357 * returns BAD_FUNC_ARG when: ssl, data or outSz is NULL; sz is negative;
sPymbed 17:ff9d1e86ad5f 8358 * or not using TLS v1.3. SIDE ERROR when not a server. Otherwise the number of
sPymbed 17:ff9d1e86ad5f 8359 * early data bytes read.
sPymbed 17:ff9d1e86ad5f 8360 */
sPymbed 17:ff9d1e86ad5f 8361 int wolfSSL_read_early_data(WOLFSSL* ssl, void* data, int sz, int* outSz)
sPymbed 17:ff9d1e86ad5f 8362 {
sPymbed 17:ff9d1e86ad5f 8363 int ret = 0;
sPymbed 17:ff9d1e86ad5f 8364
sPymbed 17:ff9d1e86ad5f 8365 WOLFSSL_ENTER("wolfSSL_read_early_data()");
sPymbed 17:ff9d1e86ad5f 8366
sPymbed 17:ff9d1e86ad5f 8367
sPymbed 17:ff9d1e86ad5f 8368 if (ssl == NULL || data == NULL || sz < 0 || outSz == NULL)
sPymbed 17:ff9d1e86ad5f 8369 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 8370 if (!IsAtLeastTLSv1_3(ssl->version))
sPymbed 17:ff9d1e86ad5f 8371 return BAD_FUNC_ARG;
sPymbed 17:ff9d1e86ad5f 8372
sPymbed 17:ff9d1e86ad5f 8373 #ifndef NO_WOLFSSL_SERVER
sPymbed 17:ff9d1e86ad5f 8374 if (ssl->options.side == WOLFSSL_CLIENT_END)
sPymbed 17:ff9d1e86ad5f 8375 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 8376
sPymbed 17:ff9d1e86ad5f 8377 if (ssl->options.handShakeState == NULL_STATE) {
sPymbed 17:ff9d1e86ad5f 8378 ssl->earlyData = expecting_early_data;
sPymbed 17:ff9d1e86ad5f 8379 ret = wolfSSL_accept_TLSv13(ssl);
sPymbed 17:ff9d1e86ad5f 8380 if (ret <= 0)
sPymbed 17:ff9d1e86ad5f 8381 return WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8382 }
sPymbed 17:ff9d1e86ad5f 8383 if (ssl->options.handShakeState == SERVER_FINISHED_COMPLETE) {
sPymbed 17:ff9d1e86ad5f 8384 ret = ReceiveData(ssl, (byte*)data, sz, FALSE);
sPymbed 17:ff9d1e86ad5f 8385 if (ret > 0)
sPymbed 17:ff9d1e86ad5f 8386 *outSz = ret;
sPymbed 17:ff9d1e86ad5f 8387 if (ssl->error == ZERO_RETURN)
sPymbed 17:ff9d1e86ad5f 8388 ssl->error = WOLFSSL_ERROR_NONE;
sPymbed 17:ff9d1e86ad5f 8389 }
sPymbed 17:ff9d1e86ad5f 8390 else
sPymbed 17:ff9d1e86ad5f 8391 ret = 0;
sPymbed 17:ff9d1e86ad5f 8392 #else
sPymbed 17:ff9d1e86ad5f 8393 return SIDE_ERROR;
sPymbed 17:ff9d1e86ad5f 8394 #endif
sPymbed 17:ff9d1e86ad5f 8395
sPymbed 17:ff9d1e86ad5f 8396 WOLFSSL_LEAVE("wolfSSL_read_early_data()", ret);
sPymbed 17:ff9d1e86ad5f 8397
sPymbed 17:ff9d1e86ad5f 8398 if (ret < 0)
sPymbed 17:ff9d1e86ad5f 8399 ret = WOLFSSL_FATAL_ERROR;
sPymbed 17:ff9d1e86ad5f 8400 return ret;
sPymbed 17:ff9d1e86ad5f 8401 }
sPymbed 17:ff9d1e86ad5f 8402 #endif
sPymbed 17:ff9d1e86ad5f 8403
sPymbed 17:ff9d1e86ad5f 8404 #undef ERROR_OUT
sPymbed 17:ff9d1e86ad5f 8405
sPymbed 17:ff9d1e86ad5f 8406 #endif /* !WOLFCRYPT_ONLY */
sPymbed 17:ff9d1e86ad5f 8407
sPymbed 17:ff9d1e86ad5f 8408 #endif /* WOLFSSL_TLS13 */
sPymbed 17:ff9d1e86ad5f 8409