Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
wolfSSL
Date:
Fri Jun 26 00:39:20 2015 +0000
Revision:
0:d92f9d21154c
wolfSSL 3.6.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 0:d92f9d21154c 1 /* internal.c
wolfSSL 0:d92f9d21154c 2 *
wolfSSL 0:d92f9d21154c 3 * Copyright (C) 2006-2015 wolfSSL Inc.
wolfSSL 0:d92f9d21154c 4 *
wolfSSL 0:d92f9d21154c 5 * This file is part of wolfSSL. (formerly known as CyaSSL)
wolfSSL 0:d92f9d21154c 6 *
wolfSSL 0:d92f9d21154c 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 0:d92f9d21154c 8 * it under the terms of the GNU General Public License as published by
wolfSSL 0:d92f9d21154c 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 0:d92f9d21154c 10 * (at your option) any later version.
wolfSSL 0:d92f9d21154c 11 *
wolfSSL 0:d92f9d21154c 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 0:d92f9d21154c 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 0:d92f9d21154c 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 0:d92f9d21154c 15 * GNU General Public License for more details.
wolfSSL 0:d92f9d21154c 16 *
wolfSSL 0:d92f9d21154c 17 * You should have received a copy of the GNU General Public License
wolfSSL 0:d92f9d21154c 18 * along with this program; if not, write to the Free Software
wolfSSL 0:d92f9d21154c 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
wolfSSL 0:d92f9d21154c 20 */
wolfSSL 0:d92f9d21154c 21
wolfSSL 0:d92f9d21154c 22
wolfSSL 0:d92f9d21154c 23 #ifdef HAVE_CONFIG_H
wolfSSL 0:d92f9d21154c 24 #include <config.h>
wolfSSL 0:d92f9d21154c 25 #endif
wolfSSL 0:d92f9d21154c 26
wolfSSL 0:d92f9d21154c 27 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 0:d92f9d21154c 28
wolfSSL 0:d92f9d21154c 29 #include <wolfssl/internal.h>
wolfSSL 0:d92f9d21154c 30 #include <wolfssl/error-ssl.h>
wolfSSL 0:d92f9d21154c 31 #include <wolfssl/wolfcrypt/asn.h>
wolfSSL 0:d92f9d21154c 32 #include <wolfssl/wolfcrypt/dh.h>
wolfSSL 0:d92f9d21154c 33 #ifdef NO_INLINE
wolfSSL 0:d92f9d21154c 34 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 0:d92f9d21154c 35 #else
wolfSSL 0:d92f9d21154c 36 #include <wolfcrypt/src/misc.c>
wolfSSL 0:d92f9d21154c 37 #endif
wolfSSL 0:d92f9d21154c 38
wolfSSL 0:d92f9d21154c 39 #ifdef HAVE_LIBZ
wolfSSL 0:d92f9d21154c 40 #include "zlib.h"
wolfSSL 0:d92f9d21154c 41 #endif
wolfSSL 0:d92f9d21154c 42
wolfSSL 0:d92f9d21154c 43 #ifdef HAVE_NTRU
wolfSSL 0:d92f9d21154c 44 #include "ntru_crypto.h"
wolfSSL 0:d92f9d21154c 45 #endif
wolfSSL 0:d92f9d21154c 46
wolfSSL 0:d92f9d21154c 47 #if defined(DEBUG_WOLFSSL) || defined(SHOW_SECRETS) || defined(CHACHA_AEAD_TEST)
wolfSSL 0:d92f9d21154c 48 #ifdef FREESCALE_MQX
wolfSSL 0:d92f9d21154c 49 #include <fio.h>
wolfSSL 0:d92f9d21154c 50 #else
wolfSSL 0:d92f9d21154c 51 #include <stdio.h>
wolfSSL 0:d92f9d21154c 52 #endif
wolfSSL 0:d92f9d21154c 53 #endif
wolfSSL 0:d92f9d21154c 54
wolfSSL 0:d92f9d21154c 55 #ifdef __sun
wolfSSL 0:d92f9d21154c 56 #include <sys/filio.h>
wolfSSL 0:d92f9d21154c 57 #endif
wolfSSL 0:d92f9d21154c 58
wolfSSL 0:d92f9d21154c 59 #ifndef TRUE
wolfSSL 0:d92f9d21154c 60 #define TRUE 1
wolfSSL 0:d92f9d21154c 61 #endif
wolfSSL 0:d92f9d21154c 62 #ifndef FALSE
wolfSSL 0:d92f9d21154c 63 #define FALSE 0
wolfSSL 0:d92f9d21154c 64 #endif
wolfSSL 0:d92f9d21154c 65
wolfSSL 0:d92f9d21154c 66 #ifdef _MSC_VER
wolfSSL 0:d92f9d21154c 67 /* disable for while(0) cases at the .c level for now */
wolfSSL 0:d92f9d21154c 68 #pragma warning(disable:4127)
wolfSSL 0:d92f9d21154c 69 #endif
wolfSSL 0:d92f9d21154c 70
wolfSSL 0:d92f9d21154c 71 #if defined(WOLFSSL_CALLBACKS) && !defined(LARGE_STATIC_BUFFERS)
wolfSSL 0:d92f9d21154c 72 #error \
wolfSSL 0:d92f9d21154c 73 WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
wolfSSL 0:d92f9d21154c 74 #endif
wolfSSL 0:d92f9d21154c 75
wolfSSL 0:d92f9d21154c 76 #if defined(HAVE_SECURE_RENEGOTIATION) && defined(HAVE_RENEGOTIATION_INDICATION)
wolfSSL 0:d92f9d21154c 77 #error Cannot use both secure-renegotiation and renegotiation-indication
wolfSSL 0:d92f9d21154c 78 #endif
wolfSSL 0:d92f9d21154c 79
wolfSSL 0:d92f9d21154c 80 static int BuildMessage(WOLFSSL* ssl, byte* output, int outSz,
wolfSSL 0:d92f9d21154c 81 const byte* input, int inSz, int type);
wolfSSL 0:d92f9d21154c 82
wolfSSL 0:d92f9d21154c 83 #ifndef NO_WOLFSSL_CLIENT
wolfSSL 0:d92f9d21154c 84 static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input, word32*,
wolfSSL 0:d92f9d21154c 85 word32);
wolfSSL 0:d92f9d21154c 86 static int DoServerHello(WOLFSSL* ssl, const byte* input, word32*, word32);
wolfSSL 0:d92f9d21154c 87 static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, word32*,
wolfSSL 0:d92f9d21154c 88 word32);
wolfSSL 0:d92f9d21154c 89 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 90 static int DoCertificateRequest(WOLFSSL* ssl, const byte* input, word32*,
wolfSSL 0:d92f9d21154c 91 word32);
wolfSSL 0:d92f9d21154c 92 #endif
wolfSSL 0:d92f9d21154c 93 #ifdef HAVE_SESSION_TICKET
wolfSSL 0:d92f9d21154c 94 static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32*,
wolfSSL 0:d92f9d21154c 95 word32);
wolfSSL 0:d92f9d21154c 96 #endif
wolfSSL 0:d92f9d21154c 97 #endif
wolfSSL 0:d92f9d21154c 98
wolfSSL 0:d92f9d21154c 99
wolfSSL 0:d92f9d21154c 100 #ifndef NO_WOLFSSL_SERVER
wolfSSL 0:d92f9d21154c 101 static int DoClientHello(WOLFSSL* ssl, const byte* input, word32*, word32);
wolfSSL 0:d92f9d21154c 102 static int DoClientKeyExchange(WOLFSSL* ssl, byte* input, word32*, word32);
wolfSSL 0:d92f9d21154c 103 #if !defined(NO_RSA) || defined(HAVE_ECC)
wolfSSL 0:d92f9d21154c 104 static int DoCertificateVerify(WOLFSSL* ssl, byte*, word32*, word32);
wolfSSL 0:d92f9d21154c 105 #endif
wolfSSL 0:d92f9d21154c 106 #endif
wolfSSL 0:d92f9d21154c 107
wolfSSL 0:d92f9d21154c 108
wolfSSL 0:d92f9d21154c 109 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 110 static INLINE int DtlsCheckWindow(DtlsState* state);
wolfSSL 0:d92f9d21154c 111 static INLINE int DtlsUpdateWindow(DtlsState* state);
wolfSSL 0:d92f9d21154c 112 #endif
wolfSSL 0:d92f9d21154c 113
wolfSSL 0:d92f9d21154c 114
wolfSSL 0:d92f9d21154c 115 typedef enum {
wolfSSL 0:d92f9d21154c 116 doProcessInit = 0,
wolfSSL 0:d92f9d21154c 117 #ifndef NO_WOLFSSL_SERVER
wolfSSL 0:d92f9d21154c 118 runProcessOldClientHello,
wolfSSL 0:d92f9d21154c 119 #endif
wolfSSL 0:d92f9d21154c 120 getRecordLayerHeader,
wolfSSL 0:d92f9d21154c 121 getData,
wolfSSL 0:d92f9d21154c 122 runProcessingOneMessage
wolfSSL 0:d92f9d21154c 123 } processReply;
wolfSSL 0:d92f9d21154c 124
wolfSSL 0:d92f9d21154c 125 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 126 static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
wolfSSL 0:d92f9d21154c 127 int content, int verify);
wolfSSL 0:d92f9d21154c 128
wolfSSL 0:d92f9d21154c 129 #endif
wolfSSL 0:d92f9d21154c 130
wolfSSL 0:d92f9d21154c 131 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 132 static int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes);
wolfSSL 0:d92f9d21154c 133 #endif
wolfSSL 0:d92f9d21154c 134
wolfSSL 0:d92f9d21154c 135 static void PickHashSigAlgo(WOLFSSL* ssl,
wolfSSL 0:d92f9d21154c 136 const byte* hashSigAlgo, word32 hashSigAlgoSz);
wolfSSL 0:d92f9d21154c 137
wolfSSL 0:d92f9d21154c 138 #ifndef WOLFSSL_HAVE_MIN
wolfSSL 0:d92f9d21154c 139 #define WOLFSSL_HAVE_MIN
wolfSSL 0:d92f9d21154c 140
wolfSSL 0:d92f9d21154c 141 static INLINE word32 min(word32 a, word32 b)
wolfSSL 0:d92f9d21154c 142 {
wolfSSL 0:d92f9d21154c 143 return a > b ? b : a;
wolfSSL 0:d92f9d21154c 144 }
wolfSSL 0:d92f9d21154c 145
wolfSSL 0:d92f9d21154c 146 #endif /* WOLFSSL_HAVE_MIN */
wolfSSL 0:d92f9d21154c 147
wolfSSL 0:d92f9d21154c 148
wolfSSL 0:d92f9d21154c 149 int IsTLS(const WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 150 {
wolfSSL 0:d92f9d21154c 151 if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_MINOR)
wolfSSL 0:d92f9d21154c 152 return 1;
wolfSSL 0:d92f9d21154c 153
wolfSSL 0:d92f9d21154c 154 return 0;
wolfSSL 0:d92f9d21154c 155 }
wolfSSL 0:d92f9d21154c 156
wolfSSL 0:d92f9d21154c 157
wolfSSL 0:d92f9d21154c 158 int IsAtLeastTLSv1_2(const WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 159 {
wolfSSL 0:d92f9d21154c 160 if (ssl->version.major == SSLv3_MAJOR && ssl->version.minor >=TLSv1_2_MINOR)
wolfSSL 0:d92f9d21154c 161 return 1;
wolfSSL 0:d92f9d21154c 162 if (ssl->version.major == DTLS_MAJOR && ssl->version.minor <= DTLSv1_2_MINOR)
wolfSSL 0:d92f9d21154c 163 return 1;
wolfSSL 0:d92f9d21154c 164
wolfSSL 0:d92f9d21154c 165 return 0;
wolfSSL 0:d92f9d21154c 166 }
wolfSSL 0:d92f9d21154c 167
wolfSSL 0:d92f9d21154c 168
wolfSSL 0:d92f9d21154c 169 #ifdef HAVE_NTRU
wolfSSL 0:d92f9d21154c 170
wolfSSL 0:d92f9d21154c 171 static byte GetEntropy(ENTROPY_CMD cmd, byte* out)
wolfSSL 0:d92f9d21154c 172 {
wolfSSL 0:d92f9d21154c 173 /* TODO: add locking? */
wolfSSL 0:d92f9d21154c 174 static RNG rng;
wolfSSL 0:d92f9d21154c 175
wolfSSL 0:d92f9d21154c 176 if (cmd == INIT)
wolfSSL 0:d92f9d21154c 177 return (wc_InitRng(&rng) == 0) ? 1 : 0;
wolfSSL 0:d92f9d21154c 178
wolfSSL 0:d92f9d21154c 179 if (out == NULL)
wolfSSL 0:d92f9d21154c 180 return 0;
wolfSSL 0:d92f9d21154c 181
wolfSSL 0:d92f9d21154c 182 if (cmd == GET_BYTE_OF_ENTROPY)
wolfSSL 0:d92f9d21154c 183 return (wc_RNG_GenerateBlock(&rng, out, 1) == 0) ? 1 : 0;
wolfSSL 0:d92f9d21154c 184
wolfSSL 0:d92f9d21154c 185 if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) {
wolfSSL 0:d92f9d21154c 186 *out = 1;
wolfSSL 0:d92f9d21154c 187 return 1;
wolfSSL 0:d92f9d21154c 188 }
wolfSSL 0:d92f9d21154c 189
wolfSSL 0:d92f9d21154c 190 return 0;
wolfSSL 0:d92f9d21154c 191 }
wolfSSL 0:d92f9d21154c 192
wolfSSL 0:d92f9d21154c 193 #endif /* HAVE_NTRU */
wolfSSL 0:d92f9d21154c 194
wolfSSL 0:d92f9d21154c 195 /* used by ssl.c too */
wolfSSL 0:d92f9d21154c 196 void c32to24(word32 in, word24 out)
wolfSSL 0:d92f9d21154c 197 {
wolfSSL 0:d92f9d21154c 198 out[0] = (in >> 16) & 0xff;
wolfSSL 0:d92f9d21154c 199 out[1] = (in >> 8) & 0xff;
wolfSSL 0:d92f9d21154c 200 out[2] = in & 0xff;
wolfSSL 0:d92f9d21154c 201 }
wolfSSL 0:d92f9d21154c 202
wolfSSL 0:d92f9d21154c 203
wolfSSL 0:d92f9d21154c 204 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 205
wolfSSL 0:d92f9d21154c 206 static INLINE void c32to48(word32 in, byte out[6])
wolfSSL 0:d92f9d21154c 207 {
wolfSSL 0:d92f9d21154c 208 out[0] = 0;
wolfSSL 0:d92f9d21154c 209 out[1] = 0;
wolfSSL 0:d92f9d21154c 210 out[2] = (in >> 24) & 0xff;
wolfSSL 0:d92f9d21154c 211 out[3] = (in >> 16) & 0xff;
wolfSSL 0:d92f9d21154c 212 out[4] = (in >> 8) & 0xff;
wolfSSL 0:d92f9d21154c 213 out[5] = in & 0xff;
wolfSSL 0:d92f9d21154c 214 }
wolfSSL 0:d92f9d21154c 215
wolfSSL 0:d92f9d21154c 216 #endif /* WOLFSSL_DTLS */
wolfSSL 0:d92f9d21154c 217
wolfSSL 0:d92f9d21154c 218
wolfSSL 0:d92f9d21154c 219 /* convert 16 bit integer to opaque */
wolfSSL 0:d92f9d21154c 220 static INLINE void c16toa(word16 u16, byte* c)
wolfSSL 0:d92f9d21154c 221 {
wolfSSL 0:d92f9d21154c 222 c[0] = (u16 >> 8) & 0xff;
wolfSSL 0:d92f9d21154c 223 c[1] = u16 & 0xff;
wolfSSL 0:d92f9d21154c 224 }
wolfSSL 0:d92f9d21154c 225
wolfSSL 0:d92f9d21154c 226
wolfSSL 0:d92f9d21154c 227 #if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \
wolfSSL 0:d92f9d21154c 228 || defined(HAVE_AESGCM)
wolfSSL 0:d92f9d21154c 229 /* convert 32 bit integer to opaque */
wolfSSL 0:d92f9d21154c 230 static INLINE void c32toa(word32 u32, byte* c)
wolfSSL 0:d92f9d21154c 231 {
wolfSSL 0:d92f9d21154c 232 c[0] = (u32 >> 24) & 0xff;
wolfSSL 0:d92f9d21154c 233 c[1] = (u32 >> 16) & 0xff;
wolfSSL 0:d92f9d21154c 234 c[2] = (u32 >> 8) & 0xff;
wolfSSL 0:d92f9d21154c 235 c[3] = u32 & 0xff;
wolfSSL 0:d92f9d21154c 236 }
wolfSSL 0:d92f9d21154c 237 #endif
wolfSSL 0:d92f9d21154c 238
wolfSSL 0:d92f9d21154c 239
wolfSSL 0:d92f9d21154c 240 /* convert a 24 bit integer into a 32 bit one */
wolfSSL 0:d92f9d21154c 241 static INLINE void c24to32(const word24 u24, word32* u32)
wolfSSL 0:d92f9d21154c 242 {
wolfSSL 0:d92f9d21154c 243 *u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2];
wolfSSL 0:d92f9d21154c 244 }
wolfSSL 0:d92f9d21154c 245
wolfSSL 0:d92f9d21154c 246
wolfSSL 0:d92f9d21154c 247 /* convert opaque to 16 bit integer */
wolfSSL 0:d92f9d21154c 248 static INLINE void ato16(const byte* c, word16* u16)
wolfSSL 0:d92f9d21154c 249 {
wolfSSL 0:d92f9d21154c 250 *u16 = (word16) ((c[0] << 8) | (c[1]));
wolfSSL 0:d92f9d21154c 251 }
wolfSSL 0:d92f9d21154c 252
wolfSSL 0:d92f9d21154c 253
wolfSSL 0:d92f9d21154c 254 #if defined(WOLFSSL_DTLS) || defined(HAVE_SESSION_TICKET)
wolfSSL 0:d92f9d21154c 255
wolfSSL 0:d92f9d21154c 256 /* convert opaque to 32 bit integer */
wolfSSL 0:d92f9d21154c 257 static INLINE void ato32(const byte* c, word32* u32)
wolfSSL 0:d92f9d21154c 258 {
wolfSSL 0:d92f9d21154c 259 *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
wolfSSL 0:d92f9d21154c 260 }
wolfSSL 0:d92f9d21154c 261
wolfSSL 0:d92f9d21154c 262 #endif /* WOLFSSL_DTLS */
wolfSSL 0:d92f9d21154c 263
wolfSSL 0:d92f9d21154c 264
wolfSSL 0:d92f9d21154c 265 #ifdef HAVE_LIBZ
wolfSSL 0:d92f9d21154c 266
wolfSSL 0:d92f9d21154c 267 /* alloc user allocs to work with zlib */
wolfSSL 0:d92f9d21154c 268 static void* myAlloc(void* opaque, unsigned int item, unsigned int size)
wolfSSL 0:d92f9d21154c 269 {
wolfSSL 0:d92f9d21154c 270 (void)opaque;
wolfSSL 0:d92f9d21154c 271 return XMALLOC(item * size, opaque, DYNAMIC_TYPE_LIBZ);
wolfSSL 0:d92f9d21154c 272 }
wolfSSL 0:d92f9d21154c 273
wolfSSL 0:d92f9d21154c 274
wolfSSL 0:d92f9d21154c 275 static void myFree(void* opaque, void* memory)
wolfSSL 0:d92f9d21154c 276 {
wolfSSL 0:d92f9d21154c 277 (void)opaque;
wolfSSL 0:d92f9d21154c 278 XFREE(memory, opaque, DYNAMIC_TYPE_LIBZ);
wolfSSL 0:d92f9d21154c 279 }
wolfSSL 0:d92f9d21154c 280
wolfSSL 0:d92f9d21154c 281
wolfSSL 0:d92f9d21154c 282 /* init zlib comp/decomp streams, 0 on success */
wolfSSL 0:d92f9d21154c 283 static int InitStreams(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 284 {
wolfSSL 0:d92f9d21154c 285 ssl->c_stream.zalloc = (alloc_func)myAlloc;
wolfSSL 0:d92f9d21154c 286 ssl->c_stream.zfree = (free_func)myFree;
wolfSSL 0:d92f9d21154c 287 ssl->c_stream.opaque = (voidpf)ssl->heap;
wolfSSL 0:d92f9d21154c 288
wolfSSL 0:d92f9d21154c 289 if (deflateInit(&ssl->c_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
wolfSSL 0:d92f9d21154c 290 return ZLIB_INIT_ERROR;
wolfSSL 0:d92f9d21154c 291
wolfSSL 0:d92f9d21154c 292 ssl->didStreamInit = 1;
wolfSSL 0:d92f9d21154c 293
wolfSSL 0:d92f9d21154c 294 ssl->d_stream.zalloc = (alloc_func)myAlloc;
wolfSSL 0:d92f9d21154c 295 ssl->d_stream.zfree = (free_func)myFree;
wolfSSL 0:d92f9d21154c 296 ssl->d_stream.opaque = (voidpf)ssl->heap;
wolfSSL 0:d92f9d21154c 297
wolfSSL 0:d92f9d21154c 298 if (inflateInit(&ssl->d_stream) != Z_OK) return ZLIB_INIT_ERROR;
wolfSSL 0:d92f9d21154c 299
wolfSSL 0:d92f9d21154c 300 return 0;
wolfSSL 0:d92f9d21154c 301 }
wolfSSL 0:d92f9d21154c 302
wolfSSL 0:d92f9d21154c 303
wolfSSL 0:d92f9d21154c 304 static void FreeStreams(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 305 {
wolfSSL 0:d92f9d21154c 306 if (ssl->didStreamInit) {
wolfSSL 0:d92f9d21154c 307 deflateEnd(&ssl->c_stream);
wolfSSL 0:d92f9d21154c 308 inflateEnd(&ssl->d_stream);
wolfSSL 0:d92f9d21154c 309 }
wolfSSL 0:d92f9d21154c 310 }
wolfSSL 0:d92f9d21154c 311
wolfSSL 0:d92f9d21154c 312
wolfSSL 0:d92f9d21154c 313 /* compress in to out, return out size or error */
wolfSSL 0:d92f9d21154c 314 static int myCompress(WOLFSSL* ssl, byte* in, int inSz, byte* out, int outSz)
wolfSSL 0:d92f9d21154c 315 {
wolfSSL 0:d92f9d21154c 316 int err;
wolfSSL 0:d92f9d21154c 317 int currTotal = (int)ssl->c_stream.total_out;
wolfSSL 0:d92f9d21154c 318
wolfSSL 0:d92f9d21154c 319 ssl->c_stream.next_in = in;
wolfSSL 0:d92f9d21154c 320 ssl->c_stream.avail_in = inSz;
wolfSSL 0:d92f9d21154c 321 ssl->c_stream.next_out = out;
wolfSSL 0:d92f9d21154c 322 ssl->c_stream.avail_out = outSz;
wolfSSL 0:d92f9d21154c 323
wolfSSL 0:d92f9d21154c 324 err = deflate(&ssl->c_stream, Z_SYNC_FLUSH);
wolfSSL 0:d92f9d21154c 325 if (err != Z_OK && err != Z_STREAM_END) return ZLIB_COMPRESS_ERROR;
wolfSSL 0:d92f9d21154c 326
wolfSSL 0:d92f9d21154c 327 return (int)ssl->c_stream.total_out - currTotal;
wolfSSL 0:d92f9d21154c 328 }
wolfSSL 0:d92f9d21154c 329
wolfSSL 0:d92f9d21154c 330
wolfSSL 0:d92f9d21154c 331 /* decompress in to out, returnn out size or error */
wolfSSL 0:d92f9d21154c 332 static int myDeCompress(WOLFSSL* ssl, byte* in,int inSz, byte* out,int outSz)
wolfSSL 0:d92f9d21154c 333 {
wolfSSL 0:d92f9d21154c 334 int err;
wolfSSL 0:d92f9d21154c 335 int currTotal = (int)ssl->d_stream.total_out;
wolfSSL 0:d92f9d21154c 336
wolfSSL 0:d92f9d21154c 337 ssl->d_stream.next_in = in;
wolfSSL 0:d92f9d21154c 338 ssl->d_stream.avail_in = inSz;
wolfSSL 0:d92f9d21154c 339 ssl->d_stream.next_out = out;
wolfSSL 0:d92f9d21154c 340 ssl->d_stream.avail_out = outSz;
wolfSSL 0:d92f9d21154c 341
wolfSSL 0:d92f9d21154c 342 err = inflate(&ssl->d_stream, Z_SYNC_FLUSH);
wolfSSL 0:d92f9d21154c 343 if (err != Z_OK && err != Z_STREAM_END) return ZLIB_DECOMPRESS_ERROR;
wolfSSL 0:d92f9d21154c 344
wolfSSL 0:d92f9d21154c 345 return (int)ssl->d_stream.total_out - currTotal;
wolfSSL 0:d92f9d21154c 346 }
wolfSSL 0:d92f9d21154c 347
wolfSSL 0:d92f9d21154c 348 #endif /* HAVE_LIBZ */
wolfSSL 0:d92f9d21154c 349
wolfSSL 0:d92f9d21154c 350
wolfSSL 0:d92f9d21154c 351 void InitSSL_Method(WOLFSSL_METHOD* method, ProtocolVersion pv)
wolfSSL 0:d92f9d21154c 352 {
wolfSSL 0:d92f9d21154c 353 method->version = pv;
wolfSSL 0:d92f9d21154c 354 method->side = WOLFSSL_CLIENT_END;
wolfSSL 0:d92f9d21154c 355 method->downgrade = 0;
wolfSSL 0:d92f9d21154c 356 }
wolfSSL 0:d92f9d21154c 357
wolfSSL 0:d92f9d21154c 358
wolfSSL 0:d92f9d21154c 359 /* Initialze SSL context, return 0 on success */
wolfSSL 0:d92f9d21154c 360 int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method)
wolfSSL 0:d92f9d21154c 361 {
wolfSSL 0:d92f9d21154c 362 XMEMSET(ctx, 0, sizeof(WOLFSSL_CTX));
wolfSSL 0:d92f9d21154c 363
wolfSSL 0:d92f9d21154c 364 ctx->method = method;
wolfSSL 0:d92f9d21154c 365 ctx->refCount = 1; /* so either CTX_free or SSL_free can release */
wolfSSL 0:d92f9d21154c 366 ctx->heap = ctx; /* defaults to self */
wolfSSL 0:d92f9d21154c 367 ctx->timeout = WOLFSSL_SESSION_TIMEOUT;
wolfSSL 0:d92f9d21154c 368 ctx->minDowngrade = TLSv1_MINOR; /* current default */
wolfSSL 0:d92f9d21154c 369
wolfSSL 0:d92f9d21154c 370 if (InitMutex(&ctx->countMutex) < 0) {
wolfSSL 0:d92f9d21154c 371 WOLFSSL_MSG("Mutex error on CTX init");
wolfSSL 0:d92f9d21154c 372 return BAD_MUTEX_E;
wolfSSL 0:d92f9d21154c 373 }
wolfSSL 0:d92f9d21154c 374
wolfSSL 0:d92f9d21154c 375 #ifndef NO_DH
wolfSSL 0:d92f9d21154c 376 ctx->minDhKeySz = MIN_DHKEY_SZ;
wolfSSL 0:d92f9d21154c 377 #endif
wolfSSL 0:d92f9d21154c 378
wolfSSL 0:d92f9d21154c 379 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 380 ctx->eccTempKeySz = ECDHE_SIZE;
wolfSSL 0:d92f9d21154c 381 #endif
wolfSSL 0:d92f9d21154c 382
wolfSSL 0:d92f9d21154c 383 #ifndef WOLFSSL_USER_IO
wolfSSL 0:d92f9d21154c 384 ctx->CBIORecv = EmbedReceive;
wolfSSL 0:d92f9d21154c 385 ctx->CBIOSend = EmbedSend;
wolfSSL 0:d92f9d21154c 386 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 387 if (method->version.major == DTLS_MAJOR) {
wolfSSL 0:d92f9d21154c 388 ctx->CBIORecv = EmbedReceiveFrom;
wolfSSL 0:d92f9d21154c 389 ctx->CBIOSend = EmbedSendTo;
wolfSSL 0:d92f9d21154c 390 ctx->CBIOCookie = EmbedGenerateCookie;
wolfSSL 0:d92f9d21154c 391 }
wolfSSL 0:d92f9d21154c 392 #endif
wolfSSL 0:d92f9d21154c 393 #endif /* WOLFSSL_USER_IO */
wolfSSL 0:d92f9d21154c 394
wolfSSL 0:d92f9d21154c 395 #ifdef HAVE_NETX
wolfSSL 0:d92f9d21154c 396 ctx->CBIORecv = NetX_Receive;
wolfSSL 0:d92f9d21154c 397 ctx->CBIOSend = NetX_Send;
wolfSSL 0:d92f9d21154c 398 #endif
wolfSSL 0:d92f9d21154c 399
wolfSSL 0:d92f9d21154c 400 #ifdef HAVE_NTRU
wolfSSL 0:d92f9d21154c 401 if (method->side == WOLFSSL_CLIENT_END)
wolfSSL 0:d92f9d21154c 402 ctx->haveNTRU = 1; /* always on cliet side */
wolfSSL 0:d92f9d21154c 403 /* server can turn on by loading key */
wolfSSL 0:d92f9d21154c 404 #endif
wolfSSL 0:d92f9d21154c 405 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 406 if (method->side == WOLFSSL_CLIENT_END) {
wolfSSL 0:d92f9d21154c 407 ctx->haveECDSAsig = 1; /* always on cliet side */
wolfSSL 0:d92f9d21154c 408 ctx->haveStaticECC = 1; /* server can turn on by loading key */
wolfSSL 0:d92f9d21154c 409 }
wolfSSL 0:d92f9d21154c 410 #endif
wolfSSL 0:d92f9d21154c 411
wolfSSL 0:d92f9d21154c 412 #ifdef HAVE_CAVIUM
wolfSSL 0:d92f9d21154c 413 ctx->devId = NO_CAVIUM_DEVICE;
wolfSSL 0:d92f9d21154c 414 #endif
wolfSSL 0:d92f9d21154c 415
wolfSSL 0:d92f9d21154c 416 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 417 ctx->cm = wolfSSL_CertManagerNew();
wolfSSL 0:d92f9d21154c 418 if (ctx->cm == NULL) {
wolfSSL 0:d92f9d21154c 419 WOLFSSL_MSG("Bad Cert Manager New");
wolfSSL 0:d92f9d21154c 420 return BAD_CERT_MANAGER_ERROR;
wolfSSL 0:d92f9d21154c 421 }
wolfSSL 0:d92f9d21154c 422 #endif
wolfSSL 0:d92f9d21154c 423
wolfSSL 0:d92f9d21154c 424 #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
wolfSSL 0:d92f9d21154c 425 ctx->ticketHint = SESSION_TICKET_HINT_DEFAULT;
wolfSSL 0:d92f9d21154c 426 #endif
wolfSSL 0:d92f9d21154c 427
wolfSSL 0:d92f9d21154c 428 return 0;
wolfSSL 0:d92f9d21154c 429 }
wolfSSL 0:d92f9d21154c 430
wolfSSL 0:d92f9d21154c 431
wolfSSL 0:d92f9d21154c 432 /* In case contexts are held in array and don't want to free actual ctx */
wolfSSL 0:d92f9d21154c 433 void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
wolfSSL 0:d92f9d21154c 434 {
wolfSSL 0:d92f9d21154c 435 XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
wolfSSL 0:d92f9d21154c 436 if (ctx->suites)
wolfSSL 0:d92f9d21154c 437 XFREE(ctx->suites, ctx->heap, DYNAMIC_TYPE_SUITES);
wolfSSL 0:d92f9d21154c 438
wolfSSL 0:d92f9d21154c 439 #ifndef NO_DH
wolfSSL 0:d92f9d21154c 440 XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 441 XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 442 #endif
wolfSSL 0:d92f9d21154c 443 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 444 XFREE(ctx->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
wolfSSL 0:d92f9d21154c 445 XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
wolfSSL 0:d92f9d21154c 446 XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
wolfSSL 0:d92f9d21154c 447 wolfSSL_CertManagerFree(ctx->cm);
wolfSSL 0:d92f9d21154c 448 #endif
wolfSSL 0:d92f9d21154c 449 #ifdef HAVE_TLS_EXTENSIONS
wolfSSL 0:d92f9d21154c 450 TLSX_FreeAll(ctx->extensions);
wolfSSL 0:d92f9d21154c 451 #endif
wolfSSL 0:d92f9d21154c 452 }
wolfSSL 0:d92f9d21154c 453
wolfSSL 0:d92f9d21154c 454
wolfSSL 0:d92f9d21154c 455 void FreeSSL_Ctx(WOLFSSL_CTX* ctx)
wolfSSL 0:d92f9d21154c 456 {
wolfSSL 0:d92f9d21154c 457 int doFree = 0;
wolfSSL 0:d92f9d21154c 458
wolfSSL 0:d92f9d21154c 459 if (LockMutex(&ctx->countMutex) != 0) {
wolfSSL 0:d92f9d21154c 460 WOLFSSL_MSG("Couldn't lock count mutex");
wolfSSL 0:d92f9d21154c 461 return;
wolfSSL 0:d92f9d21154c 462 }
wolfSSL 0:d92f9d21154c 463 ctx->refCount--;
wolfSSL 0:d92f9d21154c 464 if (ctx->refCount == 0)
wolfSSL 0:d92f9d21154c 465 doFree = 1;
wolfSSL 0:d92f9d21154c 466 UnLockMutex(&ctx->countMutex);
wolfSSL 0:d92f9d21154c 467
wolfSSL 0:d92f9d21154c 468 if (doFree) {
wolfSSL 0:d92f9d21154c 469 WOLFSSL_MSG("CTX ref count down to 0, doing full free");
wolfSSL 0:d92f9d21154c 470 SSL_CtxResourceFree(ctx);
wolfSSL 0:d92f9d21154c 471 FreeMutex(&ctx->countMutex);
wolfSSL 0:d92f9d21154c 472 XFREE(ctx, ctx->heap, DYNAMIC_TYPE_CTX);
wolfSSL 0:d92f9d21154c 473 }
wolfSSL 0:d92f9d21154c 474 else {
wolfSSL 0:d92f9d21154c 475 (void)ctx;
wolfSSL 0:d92f9d21154c 476 WOLFSSL_MSG("CTX ref count not 0 yet, no free");
wolfSSL 0:d92f9d21154c 477 }
wolfSSL 0:d92f9d21154c 478 }
wolfSSL 0:d92f9d21154c 479
wolfSSL 0:d92f9d21154c 480
wolfSSL 0:d92f9d21154c 481 /* Set cipher pointers to null */
wolfSSL 0:d92f9d21154c 482 void InitCiphers(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 483 {
wolfSSL 0:d92f9d21154c 484 #ifdef BUILD_ARC4
wolfSSL 0:d92f9d21154c 485 ssl->encrypt.arc4 = NULL;
wolfSSL 0:d92f9d21154c 486 ssl->decrypt.arc4 = NULL;
wolfSSL 0:d92f9d21154c 487 #endif
wolfSSL 0:d92f9d21154c 488 #ifdef BUILD_DES3
wolfSSL 0:d92f9d21154c 489 ssl->encrypt.des3 = NULL;
wolfSSL 0:d92f9d21154c 490 ssl->decrypt.des3 = NULL;
wolfSSL 0:d92f9d21154c 491 #endif
wolfSSL 0:d92f9d21154c 492 #ifdef BUILD_AES
wolfSSL 0:d92f9d21154c 493 ssl->encrypt.aes = NULL;
wolfSSL 0:d92f9d21154c 494 ssl->decrypt.aes = NULL;
wolfSSL 0:d92f9d21154c 495 #endif
wolfSSL 0:d92f9d21154c 496 #ifdef HAVE_CAMELLIA
wolfSSL 0:d92f9d21154c 497 ssl->encrypt.cam = NULL;
wolfSSL 0:d92f9d21154c 498 ssl->decrypt.cam = NULL;
wolfSSL 0:d92f9d21154c 499 #endif
wolfSSL 0:d92f9d21154c 500 #ifdef HAVE_HC128
wolfSSL 0:d92f9d21154c 501 ssl->encrypt.hc128 = NULL;
wolfSSL 0:d92f9d21154c 502 ssl->decrypt.hc128 = NULL;
wolfSSL 0:d92f9d21154c 503 #endif
wolfSSL 0:d92f9d21154c 504 #ifdef BUILD_RABBIT
wolfSSL 0:d92f9d21154c 505 ssl->encrypt.rabbit = NULL;
wolfSSL 0:d92f9d21154c 506 ssl->decrypt.rabbit = NULL;
wolfSSL 0:d92f9d21154c 507 #endif
wolfSSL 0:d92f9d21154c 508 #ifdef HAVE_CHACHA
wolfSSL 0:d92f9d21154c 509 ssl->encrypt.chacha = NULL;
wolfSSL 0:d92f9d21154c 510 ssl->decrypt.chacha = NULL;
wolfSSL 0:d92f9d21154c 511 #endif
wolfSSL 0:d92f9d21154c 512 #ifdef HAVE_POLY1305
wolfSSL 0:d92f9d21154c 513 ssl->auth.poly1305 = NULL;
wolfSSL 0:d92f9d21154c 514 #endif
wolfSSL 0:d92f9d21154c 515 ssl->encrypt.setup = 0;
wolfSSL 0:d92f9d21154c 516 ssl->decrypt.setup = 0;
wolfSSL 0:d92f9d21154c 517 #ifdef HAVE_ONE_TIME_AUTH
wolfSSL 0:d92f9d21154c 518 ssl->auth.setup = 0;
wolfSSL 0:d92f9d21154c 519 #endif
wolfSSL 0:d92f9d21154c 520 }
wolfSSL 0:d92f9d21154c 521
wolfSSL 0:d92f9d21154c 522
wolfSSL 0:d92f9d21154c 523 /* Free ciphers */
wolfSSL 0:d92f9d21154c 524 void FreeCiphers(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 525 {
wolfSSL 0:d92f9d21154c 526 (void)ssl;
wolfSSL 0:d92f9d21154c 527 #ifdef BUILD_ARC4
wolfSSL 0:d92f9d21154c 528 #ifdef HAVE_CAVIUM
wolfSSL 0:d92f9d21154c 529 if (ssl->devId != NO_CAVIUM_DEVICE) {
wolfSSL 0:d92f9d21154c 530 wc_Arc4FreeCavium(ssl->encrypt.arc4);
wolfSSL 0:d92f9d21154c 531 wc_Arc4FreeCavium(ssl->decrypt.arc4);
wolfSSL 0:d92f9d21154c 532 }
wolfSSL 0:d92f9d21154c 533 #endif
wolfSSL 0:d92f9d21154c 534 XFREE(ssl->encrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 535 XFREE(ssl->decrypt.arc4, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 536 #endif
wolfSSL 0:d92f9d21154c 537 #ifdef BUILD_DES3
wolfSSL 0:d92f9d21154c 538 #ifdef HAVE_CAVIUM
wolfSSL 0:d92f9d21154c 539 if (ssl->devId != NO_CAVIUM_DEVICE) {
wolfSSL 0:d92f9d21154c 540 wc_Des3_FreeCavium(ssl->encrypt.des3);
wolfSSL 0:d92f9d21154c 541 wc_Des3_FreeCavium(ssl->decrypt.des3);
wolfSSL 0:d92f9d21154c 542 }
wolfSSL 0:d92f9d21154c 543 #endif
wolfSSL 0:d92f9d21154c 544 XFREE(ssl->encrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 545 XFREE(ssl->decrypt.des3, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 546 #endif
wolfSSL 0:d92f9d21154c 547 #ifdef BUILD_AES
wolfSSL 0:d92f9d21154c 548 #ifdef HAVE_CAVIUM
wolfSSL 0:d92f9d21154c 549 if (ssl->devId != NO_CAVIUM_DEVICE) {
wolfSSL 0:d92f9d21154c 550 wc_AesFreeCavium(ssl->encrypt.aes);
wolfSSL 0:d92f9d21154c 551 wc_AesFreeCavium(ssl->decrypt.aes);
wolfSSL 0:d92f9d21154c 552 }
wolfSSL 0:d92f9d21154c 553 #endif
wolfSSL 0:d92f9d21154c 554 XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 555 XFREE(ssl->decrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 556 #endif
wolfSSL 0:d92f9d21154c 557 #ifdef HAVE_CAMELLIA
wolfSSL 0:d92f9d21154c 558 XFREE(ssl->encrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 559 XFREE(ssl->decrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 560 #endif
wolfSSL 0:d92f9d21154c 561 #ifdef HAVE_HC128
wolfSSL 0:d92f9d21154c 562 XFREE(ssl->encrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 563 XFREE(ssl->decrypt.hc128, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 564 #endif
wolfSSL 0:d92f9d21154c 565 #ifdef BUILD_RABBIT
wolfSSL 0:d92f9d21154c 566 XFREE(ssl->encrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 567 XFREE(ssl->decrypt.rabbit, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 568 #endif
wolfSSL 0:d92f9d21154c 569 #ifdef HAVE_CHACHA
wolfSSL 0:d92f9d21154c 570 XFREE(ssl->encrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 571 XFREE(ssl->decrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 572 #endif
wolfSSL 0:d92f9d21154c 573 #ifdef HAVE_POLY1305
wolfSSL 0:d92f9d21154c 574 XFREE(ssl->auth.poly1305, ssl->heap, DYNAMIC_TYPE_CIPHER);
wolfSSL 0:d92f9d21154c 575 #endif
wolfSSL 0:d92f9d21154c 576 }
wolfSSL 0:d92f9d21154c 577
wolfSSL 0:d92f9d21154c 578
wolfSSL 0:d92f9d21154c 579 void InitCipherSpecs(CipherSpecs* cs)
wolfSSL 0:d92f9d21154c 580 {
wolfSSL 0:d92f9d21154c 581 cs->bulk_cipher_algorithm = INVALID_BYTE;
wolfSSL 0:d92f9d21154c 582 cs->cipher_type = INVALID_BYTE;
wolfSSL 0:d92f9d21154c 583 cs->mac_algorithm = INVALID_BYTE;
wolfSSL 0:d92f9d21154c 584 cs->kea = INVALID_BYTE;
wolfSSL 0:d92f9d21154c 585 cs->sig_algo = INVALID_BYTE;
wolfSSL 0:d92f9d21154c 586
wolfSSL 0:d92f9d21154c 587 cs->hash_size = 0;
wolfSSL 0:d92f9d21154c 588 cs->static_ecdh = 0;
wolfSSL 0:d92f9d21154c 589 cs->key_size = 0;
wolfSSL 0:d92f9d21154c 590 cs->iv_size = 0;
wolfSSL 0:d92f9d21154c 591 cs->block_size = 0;
wolfSSL 0:d92f9d21154c 592 }
wolfSSL 0:d92f9d21154c 593
wolfSSL 0:d92f9d21154c 594 static void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig,
wolfSSL 0:d92f9d21154c 595 int haveRSAsig, int haveAnon)
wolfSSL 0:d92f9d21154c 596 {
wolfSSL 0:d92f9d21154c 597 int idx = 0;
wolfSSL 0:d92f9d21154c 598
wolfSSL 0:d92f9d21154c 599 if (haveECDSAsig) {
wolfSSL 0:d92f9d21154c 600 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 601 suites->hashSigAlgo[idx++] = sha512_mac;
wolfSSL 0:d92f9d21154c 602 suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
wolfSSL 0:d92f9d21154c 603 #endif
wolfSSL 0:d92f9d21154c 604 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 605 suites->hashSigAlgo[idx++] = sha384_mac;
wolfSSL 0:d92f9d21154c 606 suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
wolfSSL 0:d92f9d21154c 607 #endif
wolfSSL 0:d92f9d21154c 608 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 609 suites->hashSigAlgo[idx++] = sha256_mac;
wolfSSL 0:d92f9d21154c 610 suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
wolfSSL 0:d92f9d21154c 611 #endif
wolfSSL 0:d92f9d21154c 612 #ifndef NO_SHA
wolfSSL 0:d92f9d21154c 613 suites->hashSigAlgo[idx++] = sha_mac;
wolfSSL 0:d92f9d21154c 614 suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo;
wolfSSL 0:d92f9d21154c 615 #endif
wolfSSL 0:d92f9d21154c 616 }
wolfSSL 0:d92f9d21154c 617
wolfSSL 0:d92f9d21154c 618 if (haveRSAsig) {
wolfSSL 0:d92f9d21154c 619 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 620 suites->hashSigAlgo[idx++] = sha512_mac;
wolfSSL 0:d92f9d21154c 621 suites->hashSigAlgo[idx++] = rsa_sa_algo;
wolfSSL 0:d92f9d21154c 622 #endif
wolfSSL 0:d92f9d21154c 623 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 624 suites->hashSigAlgo[idx++] = sha384_mac;
wolfSSL 0:d92f9d21154c 625 suites->hashSigAlgo[idx++] = rsa_sa_algo;
wolfSSL 0:d92f9d21154c 626 #endif
wolfSSL 0:d92f9d21154c 627 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 628 suites->hashSigAlgo[idx++] = sha256_mac;
wolfSSL 0:d92f9d21154c 629 suites->hashSigAlgo[idx++] = rsa_sa_algo;
wolfSSL 0:d92f9d21154c 630 #endif
wolfSSL 0:d92f9d21154c 631 #ifndef NO_SHA
wolfSSL 0:d92f9d21154c 632 suites->hashSigAlgo[idx++] = sha_mac;
wolfSSL 0:d92f9d21154c 633 suites->hashSigAlgo[idx++] = rsa_sa_algo;
wolfSSL 0:d92f9d21154c 634 #endif
wolfSSL 0:d92f9d21154c 635 }
wolfSSL 0:d92f9d21154c 636
wolfSSL 0:d92f9d21154c 637 if (haveAnon) {
wolfSSL 0:d92f9d21154c 638 #ifdef HAVE_ANON
wolfSSL 0:d92f9d21154c 639 suites->hashSigAlgo[idx++] = sha_mac;
wolfSSL 0:d92f9d21154c 640 suites->hashSigAlgo[idx++] = anonymous_sa_algo;
wolfSSL 0:d92f9d21154c 641 #endif
wolfSSL 0:d92f9d21154c 642 }
wolfSSL 0:d92f9d21154c 643
wolfSSL 0:d92f9d21154c 644 suites->hashSigAlgoSz = (word16)idx;
wolfSSL 0:d92f9d21154c 645 }
wolfSSL 0:d92f9d21154c 646
wolfSSL 0:d92f9d21154c 647 void InitSuites(Suites* suites, ProtocolVersion pv, word16 haveRSA,
wolfSSL 0:d92f9d21154c 648 word16 havePSK, word16 haveDH, word16 haveNTRU,
wolfSSL 0:d92f9d21154c 649 word16 haveECDSAsig, word16 haveStaticECC, int side)
wolfSSL 0:d92f9d21154c 650 {
wolfSSL 0:d92f9d21154c 651 word16 idx = 0;
wolfSSL 0:d92f9d21154c 652 int tls = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR;
wolfSSL 0:d92f9d21154c 653 int tls1_2 = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_2_MINOR;
wolfSSL 0:d92f9d21154c 654 int haveRSAsig = 1;
wolfSSL 0:d92f9d21154c 655
wolfSSL 0:d92f9d21154c 656 (void)tls; /* shut up compiler */
wolfSSL 0:d92f9d21154c 657 (void)tls1_2;
wolfSSL 0:d92f9d21154c 658 (void)haveDH;
wolfSSL 0:d92f9d21154c 659 (void)havePSK;
wolfSSL 0:d92f9d21154c 660 (void)haveNTRU;
wolfSSL 0:d92f9d21154c 661 (void)haveStaticECC;
wolfSSL 0:d92f9d21154c 662
wolfSSL 0:d92f9d21154c 663 if (suites == NULL) {
wolfSSL 0:d92f9d21154c 664 WOLFSSL_MSG("InitSuites pointer error");
wolfSSL 0:d92f9d21154c 665 return;
wolfSSL 0:d92f9d21154c 666 }
wolfSSL 0:d92f9d21154c 667
wolfSSL 0:d92f9d21154c 668 if (suites->setSuites)
wolfSSL 0:d92f9d21154c 669 return; /* trust user settings, don't override */
wolfSSL 0:d92f9d21154c 670
wolfSSL 0:d92f9d21154c 671 if (side == WOLFSSL_SERVER_END && haveStaticECC) {
wolfSSL 0:d92f9d21154c 672 haveRSA = 0; /* can't do RSA with ECDSA key */
wolfSSL 0:d92f9d21154c 673 (void)haveRSA; /* some builds won't read */
wolfSSL 0:d92f9d21154c 674 }
wolfSSL 0:d92f9d21154c 675
wolfSSL 0:d92f9d21154c 676 if (side == WOLFSSL_SERVER_END && haveECDSAsig) {
wolfSSL 0:d92f9d21154c 677 haveRSAsig = 0; /* can't have RSA sig if signed by ECDSA */
wolfSSL 0:d92f9d21154c 678 (void)haveRSAsig; /* non ecc builds won't read */
wolfSSL 0:d92f9d21154c 679 }
wolfSSL 0:d92f9d21154c 680
wolfSSL 0:d92f9d21154c 681 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 682 if (pv.major == DTLS_MAJOR) {
wolfSSL 0:d92f9d21154c 683 tls = 1;
wolfSSL 0:d92f9d21154c 684 tls1_2 = pv.minor <= DTLSv1_2_MINOR;
wolfSSL 0:d92f9d21154c 685 }
wolfSSL 0:d92f9d21154c 686 #endif
wolfSSL 0:d92f9d21154c 687
wolfSSL 0:d92f9d21154c 688 #ifdef HAVE_RENEGOTIATION_INDICATION
wolfSSL 0:d92f9d21154c 689 if (side == WOLFSSL_CLIENT_END) {
wolfSSL 0:d92f9d21154c 690 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 691 suites->suites[idx++] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV;
wolfSSL 0:d92f9d21154c 692 }
wolfSSL 0:d92f9d21154c 693 #endif
wolfSSL 0:d92f9d21154c 694
wolfSSL 0:d92f9d21154c 695 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 696 if (tls && haveNTRU && haveRSA) {
wolfSSL 0:d92f9d21154c 697 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 698 suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_256_CBC_SHA;
wolfSSL 0:d92f9d21154c 699 }
wolfSSL 0:d92f9d21154c 700 #endif
wolfSSL 0:d92f9d21154c 701
wolfSSL 0:d92f9d21154c 702 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 703 if (tls && haveNTRU && haveRSA) {
wolfSSL 0:d92f9d21154c 704 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 705 suites->suites[idx++] = TLS_NTRU_RSA_WITH_AES_128_CBC_SHA;
wolfSSL 0:d92f9d21154c 706 }
wolfSSL 0:d92f9d21154c 707 #endif
wolfSSL 0:d92f9d21154c 708
wolfSSL 0:d92f9d21154c 709 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 710 if (tls && haveNTRU && haveRSA) {
wolfSSL 0:d92f9d21154c 711 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 712 suites->suites[idx++] = TLS_NTRU_RSA_WITH_RC4_128_SHA;
wolfSSL 0:d92f9d21154c 713 }
wolfSSL 0:d92f9d21154c 714 #endif
wolfSSL 0:d92f9d21154c 715
wolfSSL 0:d92f9d21154c 716 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 717 if (tls && haveNTRU && haveRSA) {
wolfSSL 0:d92f9d21154c 718 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 719 suites->suites[idx++] = TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA;
wolfSSL 0:d92f9d21154c 720 }
wolfSSL 0:d92f9d21154c 721 #endif
wolfSSL 0:d92f9d21154c 722
wolfSSL 0:d92f9d21154c 723 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 724 if (tls1_2 && haveECDSAsig) {
wolfSSL 0:d92f9d21154c 725 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 726 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
wolfSSL 0:d92f9d21154c 727 }
wolfSSL 0:d92f9d21154c 728 #endif
wolfSSL 0:d92f9d21154c 729
wolfSSL 0:d92f9d21154c 730 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 731 if (tls1_2 && haveECDSAsig) {
wolfSSL 0:d92f9d21154c 732 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 733 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
wolfSSL 0:d92f9d21154c 734 }
wolfSSL 0:d92f9d21154c 735 #endif
wolfSSL 0:d92f9d21154c 736
wolfSSL 0:d92f9d21154c 737 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 738 if (tls1_2 && haveRSA) {
wolfSSL 0:d92f9d21154c 739 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 740 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
wolfSSL 0:d92f9d21154c 741 }
wolfSSL 0:d92f9d21154c 742 #endif
wolfSSL 0:d92f9d21154c 743
wolfSSL 0:d92f9d21154c 744 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 745 if (tls1_2 && haveRSA) {
wolfSSL 0:d92f9d21154c 746 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 747 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
wolfSSL 0:d92f9d21154c 748 }
wolfSSL 0:d92f9d21154c 749 #endif
wolfSSL 0:d92f9d21154c 750
wolfSSL 0:d92f9d21154c 751 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 752 if (tls1_2 && haveDH && haveRSA) {
wolfSSL 0:d92f9d21154c 753 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 754 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
wolfSSL 0:d92f9d21154c 755 }
wolfSSL 0:d92f9d21154c 756 #endif
wolfSSL 0:d92f9d21154c 757
wolfSSL 0:d92f9d21154c 758 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 759 if (tls1_2 && haveDH && haveRSA) {
wolfSSL 0:d92f9d21154c 760 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 761 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
wolfSSL 0:d92f9d21154c 762 }
wolfSSL 0:d92f9d21154c 763 #endif
wolfSSL 0:d92f9d21154c 764
wolfSSL 0:d92f9d21154c 765 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 766 if (tls1_2 && haveRSA) {
wolfSSL 0:d92f9d21154c 767 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 768 suites->suites[idx++] = TLS_RSA_WITH_AES_256_GCM_SHA384;
wolfSSL 0:d92f9d21154c 769 }
wolfSSL 0:d92f9d21154c 770 #endif
wolfSSL 0:d92f9d21154c 771
wolfSSL 0:d92f9d21154c 772 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 773 if (tls1_2 && haveRSA) {
wolfSSL 0:d92f9d21154c 774 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 775 suites->suites[idx++] = TLS_RSA_WITH_AES_128_GCM_SHA256;
wolfSSL 0:d92f9d21154c 776 }
wolfSSL 0:d92f9d21154c 777 #endif
wolfSSL 0:d92f9d21154c 778
wolfSSL 0:d92f9d21154c 779 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 780 if (tls1_2 && haveECDSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 781 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 782 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
wolfSSL 0:d92f9d21154c 783 }
wolfSSL 0:d92f9d21154c 784 #endif
wolfSSL 0:d92f9d21154c 785
wolfSSL 0:d92f9d21154c 786 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 787 if (tls1_2 && haveECDSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 788 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 789 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
wolfSSL 0:d92f9d21154c 790 }
wolfSSL 0:d92f9d21154c 791 #endif
wolfSSL 0:d92f9d21154c 792
wolfSSL 0:d92f9d21154c 793 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 794 if (tls1_2 && haveRSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 795 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 796 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
wolfSSL 0:d92f9d21154c 797 }
wolfSSL 0:d92f9d21154c 798 #endif
wolfSSL 0:d92f9d21154c 799
wolfSSL 0:d92f9d21154c 800 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 801 if (tls1_2 && haveRSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 802 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 803 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
wolfSSL 0:d92f9d21154c 804 }
wolfSSL 0:d92f9d21154c 805 #endif
wolfSSL 0:d92f9d21154c 806
wolfSSL 0:d92f9d21154c 807 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 808 if (tls1_2 && haveDH && havePSK) {
wolfSSL 0:d92f9d21154c 809 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 810 suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_GCM_SHA384;
wolfSSL 0:d92f9d21154c 811 }
wolfSSL 0:d92f9d21154c 812 #endif
wolfSSL 0:d92f9d21154c 813
wolfSSL 0:d92f9d21154c 814 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 815 if (tls1_2 && haveDH && havePSK) {
wolfSSL 0:d92f9d21154c 816 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 817 suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_GCM_SHA256;
wolfSSL 0:d92f9d21154c 818 }
wolfSSL 0:d92f9d21154c 819 #endif
wolfSSL 0:d92f9d21154c 820
wolfSSL 0:d92f9d21154c 821 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 822 if (tls1_2 && havePSK) {
wolfSSL 0:d92f9d21154c 823 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 824 suites->suites[idx++] = TLS_PSK_WITH_AES_256_GCM_SHA384;
wolfSSL 0:d92f9d21154c 825 }
wolfSSL 0:d92f9d21154c 826 #endif
wolfSSL 0:d92f9d21154c 827
wolfSSL 0:d92f9d21154c 828 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 829 if (tls1_2 && havePSK) {
wolfSSL 0:d92f9d21154c 830 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 831 suites->suites[idx++] = TLS_PSK_WITH_AES_128_GCM_SHA256;
wolfSSL 0:d92f9d21154c 832 }
wolfSSL 0:d92f9d21154c 833 #endif
wolfSSL 0:d92f9d21154c 834
wolfSSL 0:d92f9d21154c 835 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
wolfSSL 0:d92f9d21154c 836 if (tls1_2 && haveECDSAsig) {
wolfSSL 0:d92f9d21154c 837 suites->suites[idx++] = CHACHA_BYTE;
wolfSSL 0:d92f9d21154c 838 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256;
wolfSSL 0:d92f9d21154c 839 }
wolfSSL 0:d92f9d21154c 840 #endif
wolfSSL 0:d92f9d21154c 841
wolfSSL 0:d92f9d21154c 842 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
wolfSSL 0:d92f9d21154c 843 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 844 suites->suites[idx++] = CHACHA_BYTE;
wolfSSL 0:d92f9d21154c 845 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
wolfSSL 0:d92f9d21154c 846 }
wolfSSL 0:d92f9d21154c 847 #endif
wolfSSL 0:d92f9d21154c 848
wolfSSL 0:d92f9d21154c 849 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
wolfSSL 0:d92f9d21154c 850 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 851 suites->suites[idx++] = CHACHA_BYTE;
wolfSSL 0:d92f9d21154c 852 suites->suites[idx++] = TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
wolfSSL 0:d92f9d21154c 853 }
wolfSSL 0:d92f9d21154c 854 #endif
wolfSSL 0:d92f9d21154c 855
wolfSSL 0:d92f9d21154c 856 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 857 if (tls1_2 && haveRSAsig) {
wolfSSL 0:d92f9d21154c 858 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 859 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256;
wolfSSL 0:d92f9d21154c 860 }
wolfSSL 0:d92f9d21154c 861 #endif
wolfSSL 0:d92f9d21154c 862
wolfSSL 0:d92f9d21154c 863 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 864 if (tls1_2 && haveECDSAsig) {
wolfSSL 0:d92f9d21154c 865 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 866 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
wolfSSL 0:d92f9d21154c 867 }
wolfSSL 0:d92f9d21154c 868 #endif
wolfSSL 0:d92f9d21154c 869
wolfSSL 0:d92f9d21154c 870 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 871 if (tls1_2 && haveRSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 872 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 873 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256;
wolfSSL 0:d92f9d21154c 874 }
wolfSSL 0:d92f9d21154c 875 #endif
wolfSSL 0:d92f9d21154c 876
wolfSSL 0:d92f9d21154c 877 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 878 if (tls1_2 && haveECDSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 879 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 880 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256;
wolfSSL 0:d92f9d21154c 881 }
wolfSSL 0:d92f9d21154c 882 #endif
wolfSSL 0:d92f9d21154c 883
wolfSSL 0:d92f9d21154c 884 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 885 if (tls1_2 && haveRSAsig) {
wolfSSL 0:d92f9d21154c 886 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 887 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384;
wolfSSL 0:d92f9d21154c 888 }
wolfSSL 0:d92f9d21154c 889 #endif
wolfSSL 0:d92f9d21154c 890
wolfSSL 0:d92f9d21154c 891 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 892 if (tls1_2 && haveECDSAsig) {
wolfSSL 0:d92f9d21154c 893 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 894 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
wolfSSL 0:d92f9d21154c 895 }
wolfSSL 0:d92f9d21154c 896 #endif
wolfSSL 0:d92f9d21154c 897
wolfSSL 0:d92f9d21154c 898 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 899 if (tls1_2 && haveRSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 900 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 901 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384;
wolfSSL 0:d92f9d21154c 902 }
wolfSSL 0:d92f9d21154c 903 #endif
wolfSSL 0:d92f9d21154c 904
wolfSSL 0:d92f9d21154c 905 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 906 if (tls1_2 && haveECDSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 907 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 908 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384;
wolfSSL 0:d92f9d21154c 909 }
wolfSSL 0:d92f9d21154c 910 #endif
wolfSSL 0:d92f9d21154c 911
wolfSSL 0:d92f9d21154c 912 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 913 if (tls && haveECDSAsig) {
wolfSSL 0:d92f9d21154c 914 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 915 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
wolfSSL 0:d92f9d21154c 916 }
wolfSSL 0:d92f9d21154c 917 #endif
wolfSSL 0:d92f9d21154c 918
wolfSSL 0:d92f9d21154c 919 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 920 if (tls && haveECDSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 921 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 922 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA;
wolfSSL 0:d92f9d21154c 923 }
wolfSSL 0:d92f9d21154c 924 #endif
wolfSSL 0:d92f9d21154c 925
wolfSSL 0:d92f9d21154c 926 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 927 if (tls && haveECDSAsig) {
wolfSSL 0:d92f9d21154c 928 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 929 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA;
wolfSSL 0:d92f9d21154c 930 }
wolfSSL 0:d92f9d21154c 931 #endif
wolfSSL 0:d92f9d21154c 932
wolfSSL 0:d92f9d21154c 933 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 934 if (tls && haveECDSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 935 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 936 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA;
wolfSSL 0:d92f9d21154c 937 }
wolfSSL 0:d92f9d21154c 938 #endif
wolfSSL 0:d92f9d21154c 939
wolfSSL 0:d92f9d21154c 940 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 941 if (tls && haveECDSAsig) {
wolfSSL 0:d92f9d21154c 942 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 943 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA;
wolfSSL 0:d92f9d21154c 944 }
wolfSSL 0:d92f9d21154c 945 #endif
wolfSSL 0:d92f9d21154c 946
wolfSSL 0:d92f9d21154c 947 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 948 if (tls && haveECDSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 949 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 950 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA;
wolfSSL 0:d92f9d21154c 951 }
wolfSSL 0:d92f9d21154c 952 #endif
wolfSSL 0:d92f9d21154c 953
wolfSSL 0:d92f9d21154c 954 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 955 if (tls && haveECDSAsig) {
wolfSSL 0:d92f9d21154c 956 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 957 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA;
wolfSSL 0:d92f9d21154c 958 }
wolfSSL 0:d92f9d21154c 959 #endif
wolfSSL 0:d92f9d21154c 960
wolfSSL 0:d92f9d21154c 961 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 962 if (tls && haveECDSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 963 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 964 suites->suites[idx++] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA;
wolfSSL 0:d92f9d21154c 965 }
wolfSSL 0:d92f9d21154c 966 #endif
wolfSSL 0:d92f9d21154c 967
wolfSSL 0:d92f9d21154c 968 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 969 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 970 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 971 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
wolfSSL 0:d92f9d21154c 972 }
wolfSSL 0:d92f9d21154c 973 #endif
wolfSSL 0:d92f9d21154c 974
wolfSSL 0:d92f9d21154c 975 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 976 if (tls && haveRSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 977 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 978 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA;
wolfSSL 0:d92f9d21154c 979 }
wolfSSL 0:d92f9d21154c 980 #endif
wolfSSL 0:d92f9d21154c 981
wolfSSL 0:d92f9d21154c 982 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 983 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 984 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 985 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
wolfSSL 0:d92f9d21154c 986 }
wolfSSL 0:d92f9d21154c 987 #endif
wolfSSL 0:d92f9d21154c 988
wolfSSL 0:d92f9d21154c 989 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 990 if (tls && haveRSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 991 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 992 suites->suites[idx++] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA;
wolfSSL 0:d92f9d21154c 993 }
wolfSSL 0:d92f9d21154c 994 #endif
wolfSSL 0:d92f9d21154c 995
wolfSSL 0:d92f9d21154c 996 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 997 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 998 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 999 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_RC4_128_SHA;
wolfSSL 0:d92f9d21154c 1000 }
wolfSSL 0:d92f9d21154c 1001 #endif
wolfSSL 0:d92f9d21154c 1002
wolfSSL 0:d92f9d21154c 1003 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 1004 if (tls && haveRSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 1005 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 1006 suites->suites[idx++] = TLS_ECDH_RSA_WITH_RC4_128_SHA;
wolfSSL 0:d92f9d21154c 1007 }
wolfSSL 0:d92f9d21154c 1008 #endif
wolfSSL 0:d92f9d21154c 1009
wolfSSL 0:d92f9d21154c 1010 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 1011 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1012 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 1013 suites->suites[idx++] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA;
wolfSSL 0:d92f9d21154c 1014 }
wolfSSL 0:d92f9d21154c 1015 #endif
wolfSSL 0:d92f9d21154c 1016
wolfSSL 0:d92f9d21154c 1017 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 1018 if (tls && haveRSAsig && haveStaticECC) {
wolfSSL 0:d92f9d21154c 1019 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 1020 suites->suites[idx++] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA;
wolfSSL 0:d92f9d21154c 1021 }
wolfSSL 0:d92f9d21154c 1022 #endif
wolfSSL 0:d92f9d21154c 1023
wolfSSL 0:d92f9d21154c 1024 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
wolfSSL 0:d92f9d21154c 1025 if (tls1_2 && haveECDSAsig) {
wolfSSL 0:d92f9d21154c 1026 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 1027 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
wolfSSL 0:d92f9d21154c 1028 }
wolfSSL 0:d92f9d21154c 1029 #endif
wolfSSL 0:d92f9d21154c 1030
wolfSSL 0:d92f9d21154c 1031 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
wolfSSL 0:d92f9d21154c 1032 if (tls1_2 && haveECDSAsig) {
wolfSSL 0:d92f9d21154c 1033 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 1034 suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8;
wolfSSL 0:d92f9d21154c 1035 }
wolfSSL 0:d92f9d21154c 1036 #endif
wolfSSL 0:d92f9d21154c 1037
wolfSSL 0:d92f9d21154c 1038 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
wolfSSL 0:d92f9d21154c 1039 if (tls1_2 && haveRSA) {
wolfSSL 0:d92f9d21154c 1040 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 1041 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CCM_8;
wolfSSL 0:d92f9d21154c 1042 }
wolfSSL 0:d92f9d21154c 1043 #endif
wolfSSL 0:d92f9d21154c 1044
wolfSSL 0:d92f9d21154c 1045 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
wolfSSL 0:d92f9d21154c 1046 if (tls1_2 && haveRSA) {
wolfSSL 0:d92f9d21154c 1047 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 1048 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CCM_8;
wolfSSL 0:d92f9d21154c 1049 }
wolfSSL 0:d92f9d21154c 1050 #endif
wolfSSL 0:d92f9d21154c 1051
wolfSSL 0:d92f9d21154c 1052 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
wolfSSL 0:d92f9d21154c 1053 if (tls1_2 && haveDH && haveRSA) {
wolfSSL 0:d92f9d21154c 1054 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1055 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
wolfSSL 0:d92f9d21154c 1056 }
wolfSSL 0:d92f9d21154c 1057 #endif
wolfSSL 0:d92f9d21154c 1058
wolfSSL 0:d92f9d21154c 1059 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 1060 if (tls1_2 && haveDH && haveRSA) {
wolfSSL 0:d92f9d21154c 1061 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1062 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
wolfSSL 0:d92f9d21154c 1063 }
wolfSSL 0:d92f9d21154c 1064 #endif
wolfSSL 0:d92f9d21154c 1065
wolfSSL 0:d92f9d21154c 1066 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 1067 if (tls && haveDH && haveRSA) {
wolfSSL 0:d92f9d21154c 1068 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1069 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
wolfSSL 0:d92f9d21154c 1070 }
wolfSSL 0:d92f9d21154c 1071 #endif
wolfSSL 0:d92f9d21154c 1072
wolfSSL 0:d92f9d21154c 1073 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 1074 if (tls && haveDH && haveRSA) {
wolfSSL 0:d92f9d21154c 1075 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1076 suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
wolfSSL 0:d92f9d21154c 1077 }
wolfSSL 0:d92f9d21154c 1078 #endif
wolfSSL 0:d92f9d21154c 1079
wolfSSL 0:d92f9d21154c 1080 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
wolfSSL 0:d92f9d21154c 1081 if (tls1_2 && haveRSA) {
wolfSSL 0:d92f9d21154c 1082 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1083 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
wolfSSL 0:d92f9d21154c 1084 }
wolfSSL 0:d92f9d21154c 1085 #endif
wolfSSL 0:d92f9d21154c 1086
wolfSSL 0:d92f9d21154c 1087 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 1088 if (tls1_2 && haveRSA) {
wolfSSL 0:d92f9d21154c 1089 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1090 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
wolfSSL 0:d92f9d21154c 1091 }
wolfSSL 0:d92f9d21154c 1092 #endif
wolfSSL 0:d92f9d21154c 1093
wolfSSL 0:d92f9d21154c 1094 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 1095 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1096 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1097 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_SHA;
wolfSSL 0:d92f9d21154c 1098 }
wolfSSL 0:d92f9d21154c 1099 #endif
wolfSSL 0:d92f9d21154c 1100
wolfSSL 0:d92f9d21154c 1101 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 1102 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1103 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1104 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_SHA;
wolfSSL 0:d92f9d21154c 1105 }
wolfSSL 0:d92f9d21154c 1106 #endif
wolfSSL 0:d92f9d21154c 1107
wolfSSL 0:d92f9d21154c 1108 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
wolfSSL 0:d92f9d21154c 1109 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1110 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1111 suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA;
wolfSSL 0:d92f9d21154c 1112 }
wolfSSL 0:d92f9d21154c 1113 #endif
wolfSSL 0:d92f9d21154c 1114
wolfSSL 0:d92f9d21154c 1115 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
wolfSSL 0:d92f9d21154c 1116 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1117 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1118 suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA256;
wolfSSL 0:d92f9d21154c 1119 }
wolfSSL 0:d92f9d21154c 1120 #endif
wolfSSL 0:d92f9d21154c 1121
wolfSSL 0:d92f9d21154c 1122 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 1123 if (tls && havePSK) {
wolfSSL 0:d92f9d21154c 1124 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1125 suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA;
wolfSSL 0:d92f9d21154c 1126 }
wolfSSL 0:d92f9d21154c 1127 #endif
wolfSSL 0:d92f9d21154c 1128
wolfSSL 0:d92f9d21154c 1129 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 1130 if (tls && haveDH && havePSK) {
wolfSSL 0:d92f9d21154c 1131 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1132 suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA384;
wolfSSL 0:d92f9d21154c 1133 }
wolfSSL 0:d92f9d21154c 1134 #endif
wolfSSL 0:d92f9d21154c 1135
wolfSSL 0:d92f9d21154c 1136 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 1137 if (tls && havePSK) {
wolfSSL 0:d92f9d21154c 1138 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1139 suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA384;
wolfSSL 0:d92f9d21154c 1140 }
wolfSSL 0:d92f9d21154c 1141 #endif
wolfSSL 0:d92f9d21154c 1142
wolfSSL 0:d92f9d21154c 1143 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 1144 if (tls && haveDH && havePSK) {
wolfSSL 0:d92f9d21154c 1145 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1146 suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA256;
wolfSSL 0:d92f9d21154c 1147 }
wolfSSL 0:d92f9d21154c 1148 #endif
wolfSSL 0:d92f9d21154c 1149
wolfSSL 0:d92f9d21154c 1150 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 1151 if (tls && havePSK) {
wolfSSL 0:d92f9d21154c 1152 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1153 suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA256;
wolfSSL 0:d92f9d21154c 1154 }
wolfSSL 0:d92f9d21154c 1155 #endif
wolfSSL 0:d92f9d21154c 1156
wolfSSL 0:d92f9d21154c 1157 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 1158 if (tls && havePSK) {
wolfSSL 0:d92f9d21154c 1159 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1160 suites->suites[idx++] = TLS_PSK_WITH_AES_128_CBC_SHA;
wolfSSL 0:d92f9d21154c 1161 }
wolfSSL 0:d92f9d21154c 1162 #endif
wolfSSL 0:d92f9d21154c 1163
wolfSSL 0:d92f9d21154c 1164 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
wolfSSL 0:d92f9d21154c 1165 if (tls && haveDH && havePSK) {
wolfSSL 0:d92f9d21154c 1166 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 1167 suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CCM;
wolfSSL 0:d92f9d21154c 1168 }
wolfSSL 0:d92f9d21154c 1169 #endif
wolfSSL 0:d92f9d21154c 1170
wolfSSL 0:d92f9d21154c 1171 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
wolfSSL 0:d92f9d21154c 1172 if (tls && haveDH && havePSK) {
wolfSSL 0:d92f9d21154c 1173 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 1174 suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CCM;
wolfSSL 0:d92f9d21154c 1175 }
wolfSSL 0:d92f9d21154c 1176 #endif
wolfSSL 0:d92f9d21154c 1177
wolfSSL 0:d92f9d21154c 1178 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
wolfSSL 0:d92f9d21154c 1179 if (tls && havePSK) {
wolfSSL 0:d92f9d21154c 1180 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 1181 suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM;
wolfSSL 0:d92f9d21154c 1182 }
wolfSSL 0:d92f9d21154c 1183 #endif
wolfSSL 0:d92f9d21154c 1184
wolfSSL 0:d92f9d21154c 1185 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
wolfSSL 0:d92f9d21154c 1186 if (tls && havePSK) {
wolfSSL 0:d92f9d21154c 1187 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 1188 suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM;
wolfSSL 0:d92f9d21154c 1189 }
wolfSSL 0:d92f9d21154c 1190 #endif
wolfSSL 0:d92f9d21154c 1191
wolfSSL 0:d92f9d21154c 1192 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
wolfSSL 0:d92f9d21154c 1193 if (tls && havePSK) {
wolfSSL 0:d92f9d21154c 1194 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 1195 suites->suites[idx++] = TLS_PSK_WITH_AES_128_CCM_8;
wolfSSL 0:d92f9d21154c 1196 }
wolfSSL 0:d92f9d21154c 1197 #endif
wolfSSL 0:d92f9d21154c 1198
wolfSSL 0:d92f9d21154c 1199 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
wolfSSL 0:d92f9d21154c 1200 if (tls && havePSK) {
wolfSSL 0:d92f9d21154c 1201 suites->suites[idx++] = ECC_BYTE;
wolfSSL 0:d92f9d21154c 1202 suites->suites[idx++] = TLS_PSK_WITH_AES_256_CCM_8;
wolfSSL 0:d92f9d21154c 1203 }
wolfSSL 0:d92f9d21154c 1204 #endif
wolfSSL 0:d92f9d21154c 1205
wolfSSL 0:d92f9d21154c 1206 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
wolfSSL 0:d92f9d21154c 1207 if (tls && haveDH && havePSK) {
wolfSSL 0:d92f9d21154c 1208 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1209 suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA384;
wolfSSL 0:d92f9d21154c 1210 }
wolfSSL 0:d92f9d21154c 1211 #endif
wolfSSL 0:d92f9d21154c 1212
wolfSSL 0:d92f9d21154c 1213 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
wolfSSL 0:d92f9d21154c 1214 if (tls && havePSK) {
wolfSSL 0:d92f9d21154c 1215 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1216 suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA384;
wolfSSL 0:d92f9d21154c 1217 }
wolfSSL 0:d92f9d21154c 1218 #endif
wolfSSL 0:d92f9d21154c 1219
wolfSSL 0:d92f9d21154c 1220 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
wolfSSL 0:d92f9d21154c 1221 if (tls && haveDH && havePSK) {
wolfSSL 0:d92f9d21154c 1222 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1223 suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA256;
wolfSSL 0:d92f9d21154c 1224 }
wolfSSL 0:d92f9d21154c 1225 #endif
wolfSSL 0:d92f9d21154c 1226
wolfSSL 0:d92f9d21154c 1227 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
wolfSSL 0:d92f9d21154c 1228 if (tls && havePSK) {
wolfSSL 0:d92f9d21154c 1229 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1230 suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA256;
wolfSSL 0:d92f9d21154c 1231 }
wolfSSL 0:d92f9d21154c 1232 #endif
wolfSSL 0:d92f9d21154c 1233
wolfSSL 0:d92f9d21154c 1234 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
wolfSSL 0:d92f9d21154c 1235 if (tls && havePSK) {
wolfSSL 0:d92f9d21154c 1236 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1237 suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA;
wolfSSL 0:d92f9d21154c 1238 }
wolfSSL 0:d92f9d21154c 1239 #endif
wolfSSL 0:d92f9d21154c 1240
wolfSSL 0:d92f9d21154c 1241 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 1242 if (haveRSA ) {
wolfSSL 0:d92f9d21154c 1243 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1244 suites->suites[idx++] = SSL_RSA_WITH_RC4_128_SHA;
wolfSSL 0:d92f9d21154c 1245 }
wolfSSL 0:d92f9d21154c 1246 #endif
wolfSSL 0:d92f9d21154c 1247
wolfSSL 0:d92f9d21154c 1248 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
wolfSSL 0:d92f9d21154c 1249 if (haveRSA ) {
wolfSSL 0:d92f9d21154c 1250 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1251 suites->suites[idx++] = SSL_RSA_WITH_RC4_128_MD5;
wolfSSL 0:d92f9d21154c 1252 }
wolfSSL 0:d92f9d21154c 1253 #endif
wolfSSL 0:d92f9d21154c 1254
wolfSSL 0:d92f9d21154c 1255 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 1256 if (haveRSA ) {
wolfSSL 0:d92f9d21154c 1257 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1258 suites->suites[idx++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
wolfSSL 0:d92f9d21154c 1259 }
wolfSSL 0:d92f9d21154c 1260 #endif
wolfSSL 0:d92f9d21154c 1261
wolfSSL 0:d92f9d21154c 1262 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
wolfSSL 0:d92f9d21154c 1263 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1264 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1265 suites->suites[idx++] = TLS_RSA_WITH_HC_128_MD5;
wolfSSL 0:d92f9d21154c 1266 }
wolfSSL 0:d92f9d21154c 1267 #endif
wolfSSL 0:d92f9d21154c 1268
wolfSSL 0:d92f9d21154c 1269 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
wolfSSL 0:d92f9d21154c 1270 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1271 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1272 suites->suites[idx++] = TLS_RSA_WITH_HC_128_SHA;
wolfSSL 0:d92f9d21154c 1273 }
wolfSSL 0:d92f9d21154c 1274 #endif
wolfSSL 0:d92f9d21154c 1275
wolfSSL 0:d92f9d21154c 1276 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
wolfSSL 0:d92f9d21154c 1277 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1278 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1279 suites->suites[idx++] = TLS_RSA_WITH_HC_128_B2B256;
wolfSSL 0:d92f9d21154c 1280 }
wolfSSL 0:d92f9d21154c 1281 #endif
wolfSSL 0:d92f9d21154c 1282
wolfSSL 0:d92f9d21154c 1283 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
wolfSSL 0:d92f9d21154c 1284 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1285 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1286 suites->suites[idx++] = TLS_RSA_WITH_AES_128_CBC_B2B256;
wolfSSL 0:d92f9d21154c 1287 }
wolfSSL 0:d92f9d21154c 1288 #endif
wolfSSL 0:d92f9d21154c 1289
wolfSSL 0:d92f9d21154c 1290 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
wolfSSL 0:d92f9d21154c 1291 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1292 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1293 suites->suites[idx++] = TLS_RSA_WITH_AES_256_CBC_B2B256;
wolfSSL 0:d92f9d21154c 1294 }
wolfSSL 0:d92f9d21154c 1295 #endif
wolfSSL 0:d92f9d21154c 1296
wolfSSL 0:d92f9d21154c 1297 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
wolfSSL 0:d92f9d21154c 1298 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1299 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1300 suites->suites[idx++] = TLS_RSA_WITH_RABBIT_SHA;
wolfSSL 0:d92f9d21154c 1301 }
wolfSSL 0:d92f9d21154c 1302 #endif
wolfSSL 0:d92f9d21154c 1303
wolfSSL 0:d92f9d21154c 1304 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
wolfSSL 0:d92f9d21154c 1305 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1306 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1307 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA;
wolfSSL 0:d92f9d21154c 1308 }
wolfSSL 0:d92f9d21154c 1309 #endif
wolfSSL 0:d92f9d21154c 1310
wolfSSL 0:d92f9d21154c 1311 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
wolfSSL 0:d92f9d21154c 1312 if (tls && haveDH && haveRSA) {
wolfSSL 0:d92f9d21154c 1313 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1314 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA;
wolfSSL 0:d92f9d21154c 1315 }
wolfSSL 0:d92f9d21154c 1316 #endif
wolfSSL 0:d92f9d21154c 1317
wolfSSL 0:d92f9d21154c 1318 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
wolfSSL 0:d92f9d21154c 1319 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1320 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1321 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA;
wolfSSL 0:d92f9d21154c 1322 }
wolfSSL 0:d92f9d21154c 1323 #endif
wolfSSL 0:d92f9d21154c 1324
wolfSSL 0:d92f9d21154c 1325 #ifdef BUILD_TLS_DHE_WITH_RSA_CAMELLIA_256_CBC_SHA
wolfSSL 0:d92f9d21154c 1326 if (tls && haveDH && haveRSA) {
wolfSSL 0:d92f9d21154c 1327 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1328 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA;
wolfSSL 0:d92f9d21154c 1329 }
wolfSSL 0:d92f9d21154c 1330 #endif
wolfSSL 0:d92f9d21154c 1331
wolfSSL 0:d92f9d21154c 1332 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 1333 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1334 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1335 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256;
wolfSSL 0:d92f9d21154c 1336 }
wolfSSL 0:d92f9d21154c 1337 #endif
wolfSSL 0:d92f9d21154c 1338
wolfSSL 0:d92f9d21154c 1339 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 1340 if (tls && haveDH && haveRSA) {
wolfSSL 0:d92f9d21154c 1341 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1342 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256;
wolfSSL 0:d92f9d21154c 1343 }
wolfSSL 0:d92f9d21154c 1344 #endif
wolfSSL 0:d92f9d21154c 1345
wolfSSL 0:d92f9d21154c 1346 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
wolfSSL 0:d92f9d21154c 1347 if (tls && haveRSA) {
wolfSSL 0:d92f9d21154c 1348 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1349 suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256;
wolfSSL 0:d92f9d21154c 1350 }
wolfSSL 0:d92f9d21154c 1351 #endif
wolfSSL 0:d92f9d21154c 1352
wolfSSL 0:d92f9d21154c 1353 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
wolfSSL 0:d92f9d21154c 1354 if (tls && haveDH && haveRSA) {
wolfSSL 0:d92f9d21154c 1355 suites->suites[idx++] = 0;
wolfSSL 0:d92f9d21154c 1356 suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256;
wolfSSL 0:d92f9d21154c 1357 }
wolfSSL 0:d92f9d21154c 1358 #endif
wolfSSL 0:d92f9d21154c 1359
wolfSSL 0:d92f9d21154c 1360 suites->suiteSz = idx;
wolfSSL 0:d92f9d21154c 1361
wolfSSL 0:d92f9d21154c 1362 InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, 0);
wolfSSL 0:d92f9d21154c 1363 }
wolfSSL 0:d92f9d21154c 1364
wolfSSL 0:d92f9d21154c 1365
wolfSSL 0:d92f9d21154c 1366 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 1367
wolfSSL 0:d92f9d21154c 1368
wolfSSL 0:d92f9d21154c 1369 void InitX509Name(WOLFSSL_X509_NAME* name, int dynamicFlag)
wolfSSL 0:d92f9d21154c 1370 {
wolfSSL 0:d92f9d21154c 1371 (void)dynamicFlag;
wolfSSL 0:d92f9d21154c 1372
wolfSSL 0:d92f9d21154c 1373 if (name != NULL) {
wolfSSL 0:d92f9d21154c 1374 name->name = name->staticName;
wolfSSL 0:d92f9d21154c 1375 name->dynamicName = 0;
wolfSSL 0:d92f9d21154c 1376 #ifdef OPENSSL_EXTRA
wolfSSL 0:d92f9d21154c 1377 XMEMSET(&name->fullName, 0, sizeof(DecodedName));
wolfSSL 0:d92f9d21154c 1378 #endif /* OPENSSL_EXTRA */
wolfSSL 0:d92f9d21154c 1379 }
wolfSSL 0:d92f9d21154c 1380 }
wolfSSL 0:d92f9d21154c 1381
wolfSSL 0:d92f9d21154c 1382
wolfSSL 0:d92f9d21154c 1383 void FreeX509Name(WOLFSSL_X509_NAME* name)
wolfSSL 0:d92f9d21154c 1384 {
wolfSSL 0:d92f9d21154c 1385 if (name != NULL) {
wolfSSL 0:d92f9d21154c 1386 if (name->dynamicName)
wolfSSL 0:d92f9d21154c 1387 XFREE(name->name, NULL, DYNAMIC_TYPE_SUBJECT_CN);
wolfSSL 0:d92f9d21154c 1388 #ifdef OPENSSL_EXTRA
wolfSSL 0:d92f9d21154c 1389 if (name->fullName.fullName != NULL)
wolfSSL 0:d92f9d21154c 1390 XFREE(name->fullName.fullName, NULL, DYNAMIC_TYPE_X509);
wolfSSL 0:d92f9d21154c 1391 #endif /* OPENSSL_EXTRA */
wolfSSL 0:d92f9d21154c 1392 }
wolfSSL 0:d92f9d21154c 1393 }
wolfSSL 0:d92f9d21154c 1394
wolfSSL 0:d92f9d21154c 1395
wolfSSL 0:d92f9d21154c 1396 /* Initialize wolfSSL X509 type */
wolfSSL 0:d92f9d21154c 1397 void InitX509(WOLFSSL_X509* x509, int dynamicFlag)
wolfSSL 0:d92f9d21154c 1398 {
wolfSSL 0:d92f9d21154c 1399 InitX509Name(&x509->issuer, 0);
wolfSSL 0:d92f9d21154c 1400 InitX509Name(&x509->subject, 0);
wolfSSL 0:d92f9d21154c 1401 x509->version = 0;
wolfSSL 0:d92f9d21154c 1402 x509->pubKey.buffer = NULL;
wolfSSL 0:d92f9d21154c 1403 x509->sig.buffer = NULL;
wolfSSL 0:d92f9d21154c 1404 x509->derCert.buffer = NULL;
wolfSSL 0:d92f9d21154c 1405 x509->altNames = NULL;
wolfSSL 0:d92f9d21154c 1406 x509->altNamesNext = NULL;
wolfSSL 0:d92f9d21154c 1407 x509->dynamicMemory = (byte)dynamicFlag;
wolfSSL 0:d92f9d21154c 1408 x509->isCa = 0;
wolfSSL 0:d92f9d21154c 1409 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 1410 x509->pkCurveOID = 0;
wolfSSL 0:d92f9d21154c 1411 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 1412 #ifdef OPENSSL_EXTRA
wolfSSL 0:d92f9d21154c 1413 x509->pathLength = 0;
wolfSSL 0:d92f9d21154c 1414 x509->basicConstSet = 0;
wolfSSL 0:d92f9d21154c 1415 x509->basicConstCrit = 0;
wolfSSL 0:d92f9d21154c 1416 x509->basicConstPlSet = 0;
wolfSSL 0:d92f9d21154c 1417 x509->subjAltNameSet = 0;
wolfSSL 0:d92f9d21154c 1418 x509->subjAltNameCrit = 0;
wolfSSL 0:d92f9d21154c 1419 x509->authKeyIdSet = 0;
wolfSSL 0:d92f9d21154c 1420 x509->authKeyIdCrit = 0;
wolfSSL 0:d92f9d21154c 1421 x509->authKeyId = NULL;
wolfSSL 0:d92f9d21154c 1422 x509->authKeyIdSz = 0;
wolfSSL 0:d92f9d21154c 1423 x509->subjKeyIdSet = 0;
wolfSSL 0:d92f9d21154c 1424 x509->subjKeyIdCrit = 0;
wolfSSL 0:d92f9d21154c 1425 x509->subjKeyId = NULL;
wolfSSL 0:d92f9d21154c 1426 x509->subjKeyIdSz = 0;
wolfSSL 0:d92f9d21154c 1427 x509->keyUsageSet = 0;
wolfSSL 0:d92f9d21154c 1428 x509->keyUsageCrit = 0;
wolfSSL 0:d92f9d21154c 1429 x509->keyUsage = 0;
wolfSSL 0:d92f9d21154c 1430 #ifdef WOLFSSL_SEP
wolfSSL 0:d92f9d21154c 1431 x509->certPolicySet = 0;
wolfSSL 0:d92f9d21154c 1432 x509->certPolicyCrit = 0;
wolfSSL 0:d92f9d21154c 1433 #endif /* WOLFSSL_SEP */
wolfSSL 0:d92f9d21154c 1434 #endif /* OPENSSL_EXTRA */
wolfSSL 0:d92f9d21154c 1435 }
wolfSSL 0:d92f9d21154c 1436
wolfSSL 0:d92f9d21154c 1437
wolfSSL 0:d92f9d21154c 1438 /* Free wolfSSL X509 type */
wolfSSL 0:d92f9d21154c 1439 void FreeX509(WOLFSSL_X509* x509)
wolfSSL 0:d92f9d21154c 1440 {
wolfSSL 0:d92f9d21154c 1441 if (x509 == NULL)
wolfSSL 0:d92f9d21154c 1442 return;
wolfSSL 0:d92f9d21154c 1443
wolfSSL 0:d92f9d21154c 1444 FreeX509Name(&x509->issuer);
wolfSSL 0:d92f9d21154c 1445 FreeX509Name(&x509->subject);
wolfSSL 0:d92f9d21154c 1446 if (x509->pubKey.buffer)
wolfSSL 0:d92f9d21154c 1447 XFREE(x509->pubKey.buffer, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 0:d92f9d21154c 1448 XFREE(x509->derCert.buffer, NULL, DYNAMIC_TYPE_SUBJECT_CN);
wolfSSL 0:d92f9d21154c 1449 XFREE(x509->sig.buffer, NULL, DYNAMIC_TYPE_SIGNATURE);
wolfSSL 0:d92f9d21154c 1450 #ifdef OPENSSL_EXTRA
wolfSSL 0:d92f9d21154c 1451 XFREE(x509->authKeyId, NULL, 0);
wolfSSL 0:d92f9d21154c 1452 XFREE(x509->subjKeyId, NULL, 0);
wolfSSL 0:d92f9d21154c 1453 #endif /* OPENSSL_EXTRA */
wolfSSL 0:d92f9d21154c 1454 if (x509->altNames)
wolfSSL 0:d92f9d21154c 1455 FreeAltNames(x509->altNames, NULL);
wolfSSL 0:d92f9d21154c 1456 if (x509->dynamicMemory)
wolfSSL 0:d92f9d21154c 1457 XFREE(x509, NULL, DYNAMIC_TYPE_X509);
wolfSSL 0:d92f9d21154c 1458 }
wolfSSL 0:d92f9d21154c 1459
wolfSSL 0:d92f9d21154c 1460 #endif /* NO_CERTS */
wolfSSL 0:d92f9d21154c 1461
wolfSSL 0:d92f9d21154c 1462
wolfSSL 0:d92f9d21154c 1463 /* init everything to 0, NULL, default values before calling anything that may
wolfSSL 0:d92f9d21154c 1464 fail so that desctructor has a "good" state to cleanup */
wolfSSL 0:d92f9d21154c 1465 int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
wolfSSL 0:d92f9d21154c 1466 {
wolfSSL 0:d92f9d21154c 1467 int ret;
wolfSSL 0:d92f9d21154c 1468 byte haveRSA = 0;
wolfSSL 0:d92f9d21154c 1469 byte havePSK = 0;
wolfSSL 0:d92f9d21154c 1470 byte haveAnon = 0;
wolfSSL 0:d92f9d21154c 1471
wolfSSL 0:d92f9d21154c 1472 (void) haveAnon;
wolfSSL 0:d92f9d21154c 1473
wolfSSL 0:d92f9d21154c 1474 XMEMSET(ssl, 0, sizeof(WOLFSSL));
wolfSSL 0:d92f9d21154c 1475
wolfSSL 0:d92f9d21154c 1476 ssl->ctx = ctx; /* only for passing to calls, options could change */
wolfSSL 0:d92f9d21154c 1477 ssl->version = ctx->method->version;
wolfSSL 0:d92f9d21154c 1478
wolfSSL 0:d92f9d21154c 1479 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 1480 haveRSA = 1;
wolfSSL 0:d92f9d21154c 1481 #endif
wolfSSL 0:d92f9d21154c 1482
wolfSSL 0:d92f9d21154c 1483 ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
wolfSSL 0:d92f9d21154c 1484 ssl->buffers.inputBuffer.bufferSize = STATIC_BUFFER_LEN;
wolfSSL 0:d92f9d21154c 1485
wolfSSL 0:d92f9d21154c 1486 ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
wolfSSL 0:d92f9d21154c 1487 ssl->buffers.outputBuffer.bufferSize = STATIC_BUFFER_LEN;
wolfSSL 0:d92f9d21154c 1488
wolfSSL 0:d92f9d21154c 1489 #ifdef KEEP_PEER_CERT
wolfSSL 0:d92f9d21154c 1490 InitX509(&ssl->peerCert, 0);
wolfSSL 0:d92f9d21154c 1491 #endif
wolfSSL 0:d92f9d21154c 1492
wolfSSL 0:d92f9d21154c 1493 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 1494 ssl->eccTempKeySz = ctx->eccTempKeySz;
wolfSSL 0:d92f9d21154c 1495 ssl->pkCurveOID = ctx->pkCurveOID;
wolfSSL 0:d92f9d21154c 1496 #endif
wolfSSL 0:d92f9d21154c 1497
wolfSSL 0:d92f9d21154c 1498 ssl->timeout = ctx->timeout;
wolfSSL 0:d92f9d21154c 1499 ssl->rfd = -1; /* set to invalid descriptor */
wolfSSL 0:d92f9d21154c 1500 ssl->wfd = -1;
wolfSSL 0:d92f9d21154c 1501
wolfSSL 0:d92f9d21154c 1502 ssl->IOCB_ReadCtx = &ssl->rfd; /* prevent invalid pointer access if not */
wolfSSL 0:d92f9d21154c 1503 ssl->IOCB_WriteCtx = &ssl->wfd; /* correctly set */
wolfSSL 0:d92f9d21154c 1504
wolfSSL 0:d92f9d21154c 1505 #ifdef HAVE_NETX
wolfSSL 0:d92f9d21154c 1506 ssl->IOCB_ReadCtx = &ssl->nxCtx; /* default NetX IO ctx, same for read */
wolfSSL 0:d92f9d21154c 1507 ssl->IOCB_WriteCtx = &ssl->nxCtx; /* and write */
wolfSSL 0:d92f9d21154c 1508 #endif
wolfSSL 0:d92f9d21154c 1509 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 1510 ssl->dtls_expected_rx = MAX_MTU;
wolfSSL 0:d92f9d21154c 1511 #endif
wolfSSL 0:d92f9d21154c 1512
wolfSSL 0:d92f9d21154c 1513 ssl->verifyCallback = ctx->verifyCallback;
wolfSSL 0:d92f9d21154c 1514 ssl->options.side = ctx->method->side;
wolfSSL 0:d92f9d21154c 1515 ssl->options.downgrade = ctx->method->downgrade;
wolfSSL 0:d92f9d21154c 1516 ssl->options.minDowngrade = ctx->minDowngrade;
wolfSSL 0:d92f9d21154c 1517
wolfSSL 0:d92f9d21154c 1518 if (ssl->options.side == WOLFSSL_SERVER_END)
wolfSSL 0:d92f9d21154c 1519 ssl->options.haveDH = ctx->haveDH;
wolfSSL 0:d92f9d21154c 1520
wolfSSL 0:d92f9d21154c 1521 ssl->options.haveNTRU = ctx->haveNTRU;
wolfSSL 0:d92f9d21154c 1522 ssl->options.haveECDSAsig = ctx->haveECDSAsig;
wolfSSL 0:d92f9d21154c 1523 ssl->options.haveStaticECC = ctx->haveStaticECC;
wolfSSL 0:d92f9d21154c 1524
wolfSSL 0:d92f9d21154c 1525 #ifndef NO_PSK
wolfSSL 0:d92f9d21154c 1526 havePSK = ctx->havePSK;
wolfSSL 0:d92f9d21154c 1527 ssl->options.havePSK = ctx->havePSK;
wolfSSL 0:d92f9d21154c 1528 ssl->options.client_psk_cb = ctx->client_psk_cb;
wolfSSL 0:d92f9d21154c 1529 ssl->options.server_psk_cb = ctx->server_psk_cb;
wolfSSL 0:d92f9d21154c 1530 #endif /* NO_PSK */
wolfSSL 0:d92f9d21154c 1531
wolfSSL 0:d92f9d21154c 1532 #ifdef HAVE_ANON
wolfSSL 0:d92f9d21154c 1533 haveAnon = ctx->haveAnon;
wolfSSL 0:d92f9d21154c 1534 ssl->options.haveAnon = ctx->haveAnon;
wolfSSL 0:d92f9d21154c 1535 #endif
wolfSSL 0:d92f9d21154c 1536
wolfSSL 0:d92f9d21154c 1537 ssl->options.serverState = NULL_STATE;
wolfSSL 0:d92f9d21154c 1538 ssl->options.clientState = NULL_STATE;
wolfSSL 0:d92f9d21154c 1539 ssl->options.connectState = CONNECT_BEGIN;
wolfSSL 0:d92f9d21154c 1540 ssl->options.acceptState = ACCEPT_BEGIN;
wolfSSL 0:d92f9d21154c 1541 ssl->options.handShakeState = NULL_STATE;
wolfSSL 0:d92f9d21154c 1542 ssl->options.processReply = doProcessInit;
wolfSSL 0:d92f9d21154c 1543
wolfSSL 0:d92f9d21154c 1544 #ifndef NO_DH
wolfSSL 0:d92f9d21154c 1545 ssl->options.minDhKeySz = ctx->minDhKeySz;
wolfSSL 0:d92f9d21154c 1546 #endif
wolfSSL 0:d92f9d21154c 1547
wolfSSL 0:d92f9d21154c 1548 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 1549 ssl->dtls_timeout_init = DTLS_TIMEOUT_INIT;
wolfSSL 0:d92f9d21154c 1550 ssl->dtls_timeout_max = DTLS_TIMEOUT_MAX;
wolfSSL 0:d92f9d21154c 1551 ssl->dtls_timeout = ssl->dtls_timeout_init;
wolfSSL 0:d92f9d21154c 1552 #endif
wolfSSL 0:d92f9d21154c 1553
wolfSSL 0:d92f9d21154c 1554 ssl->options.sessionCacheOff = ctx->sessionCacheOff;
wolfSSL 0:d92f9d21154c 1555 ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
wolfSSL 0:d92f9d21154c 1556
wolfSSL 0:d92f9d21154c 1557 ssl->options.verifyPeer = ctx->verifyPeer;
wolfSSL 0:d92f9d21154c 1558 ssl->options.verifyNone = ctx->verifyNone;
wolfSSL 0:d92f9d21154c 1559 ssl->options.failNoCert = ctx->failNoCert;
wolfSSL 0:d92f9d21154c 1560 ssl->options.sendVerify = ctx->sendVerify;
wolfSSL 0:d92f9d21154c 1561
wolfSSL 0:d92f9d21154c 1562 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 1563 ssl->hmac = SSL_hmac; /* default to SSLv3 */
wolfSSL 0:d92f9d21154c 1564 #else
wolfSSL 0:d92f9d21154c 1565 ssl->hmac = TLS_hmac;
wolfSSL 0:d92f9d21154c 1566 #endif
wolfSSL 0:d92f9d21154c 1567
wolfSSL 0:d92f9d21154c 1568 ssl->heap = ctx->heap; /* defaults to self */
wolfSSL 0:d92f9d21154c 1569
wolfSSL 0:d92f9d21154c 1570 ssl->options.dtls = ssl->version.major == DTLS_MAJOR;
wolfSSL 0:d92f9d21154c 1571 ssl->options.partialWrite = ctx->partialWrite;
wolfSSL 0:d92f9d21154c 1572 ssl->options.quietShutdown = ctx->quietShutdown;
wolfSSL 0:d92f9d21154c 1573 ssl->options.groupMessages = ctx->groupMessages;
wolfSSL 0:d92f9d21154c 1574
wolfSSL 0:d92f9d21154c 1575 #ifndef NO_DH
wolfSSL 0:d92f9d21154c 1576 if (ssl->options.side == WOLFSSL_SERVER_END) {
wolfSSL 0:d92f9d21154c 1577 ssl->buffers.serverDH_P = ctx->serverDH_P;
wolfSSL 0:d92f9d21154c 1578 ssl->buffers.serverDH_G = ctx->serverDH_G;
wolfSSL 0:d92f9d21154c 1579 }
wolfSSL 0:d92f9d21154c 1580 #endif
wolfSSL 0:d92f9d21154c 1581 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 1582 /* ctx still owns certificate, certChain, key, dh, and cm */
wolfSSL 0:d92f9d21154c 1583 ssl->buffers.certificate = ctx->certificate;
wolfSSL 0:d92f9d21154c 1584 ssl->buffers.certChain = ctx->certChain;
wolfSSL 0:d92f9d21154c 1585 ssl->buffers.key = ctx->privateKey;
wolfSSL 0:d92f9d21154c 1586 #endif
wolfSSL 0:d92f9d21154c 1587
wolfSSL 0:d92f9d21154c 1588 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 1589 ssl->buffers.dtlsCtx.fd = -1;
wolfSSL 0:d92f9d21154c 1590 #endif
wolfSSL 0:d92f9d21154c 1591
wolfSSL 0:d92f9d21154c 1592 ssl->cipher.ssl = ssl;
wolfSSL 0:d92f9d21154c 1593
wolfSSL 0:d92f9d21154c 1594 #ifdef HAVE_CAVIUM
wolfSSL 0:d92f9d21154c 1595 ssl->devId = ctx->devId;
wolfSSL 0:d92f9d21154c 1596 #endif
wolfSSL 0:d92f9d21154c 1597
wolfSSL 0:d92f9d21154c 1598 #ifdef HAVE_TLS_EXTENSIONS
wolfSSL 0:d92f9d21154c 1599 #ifdef HAVE_MAX_FRAGMENT
wolfSSL 0:d92f9d21154c 1600 ssl->max_fragment = MAX_RECORD_SIZE;
wolfSSL 0:d92f9d21154c 1601 #endif
wolfSSL 0:d92f9d21154c 1602 #endif
wolfSSL 0:d92f9d21154c 1603
wolfSSL 0:d92f9d21154c 1604 /* default alert state (none) */
wolfSSL 0:d92f9d21154c 1605 ssl->alert_history.last_rx.code = -1;
wolfSSL 0:d92f9d21154c 1606 ssl->alert_history.last_rx.level = -1;
wolfSSL 0:d92f9d21154c 1607 ssl->alert_history.last_tx.code = -1;
wolfSSL 0:d92f9d21154c 1608 ssl->alert_history.last_tx.level = -1;
wolfSSL 0:d92f9d21154c 1609
wolfSSL 0:d92f9d21154c 1610 InitCiphers(ssl);
wolfSSL 0:d92f9d21154c 1611 InitCipherSpecs(&ssl->specs);
wolfSSL 0:d92f9d21154c 1612
wolfSSL 0:d92f9d21154c 1613 /* all done with init, now can return errors, call other stuff */
wolfSSL 0:d92f9d21154c 1614
wolfSSL 0:d92f9d21154c 1615 /* hsHashes */
wolfSSL 0:d92f9d21154c 1616 ssl->hsHashes = (HS_Hashes*)XMALLOC(sizeof(HS_Hashes), ssl->heap,
wolfSSL 0:d92f9d21154c 1617 DYNAMIC_TYPE_HASHES);
wolfSSL 0:d92f9d21154c 1618 if (ssl->hsHashes == NULL) {
wolfSSL 0:d92f9d21154c 1619 WOLFSSL_MSG("HS_Hashes Memory error");
wolfSSL 0:d92f9d21154c 1620 return MEMORY_E;
wolfSSL 0:d92f9d21154c 1621 }
wolfSSL 0:d92f9d21154c 1622
wolfSSL 0:d92f9d21154c 1623 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 1624 #ifndef NO_MD5
wolfSSL 0:d92f9d21154c 1625 wc_InitMd5(&ssl->hsHashes->hashMd5);
wolfSSL 0:d92f9d21154c 1626 #endif
wolfSSL 0:d92f9d21154c 1627 #ifndef NO_SHA
wolfSSL 0:d92f9d21154c 1628 ret = wc_InitSha(&ssl->hsHashes->hashSha);
wolfSSL 0:d92f9d21154c 1629 if (ret != 0) {
wolfSSL 0:d92f9d21154c 1630 return ret;
wolfSSL 0:d92f9d21154c 1631 }
wolfSSL 0:d92f9d21154c 1632 #endif
wolfSSL 0:d92f9d21154c 1633 #endif
wolfSSL 0:d92f9d21154c 1634 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 1635 ret = wc_InitSha256(&ssl->hsHashes->hashSha256);
wolfSSL 0:d92f9d21154c 1636 if (ret != 0) {
wolfSSL 0:d92f9d21154c 1637 return ret;
wolfSSL 0:d92f9d21154c 1638 }
wolfSSL 0:d92f9d21154c 1639 #endif
wolfSSL 0:d92f9d21154c 1640 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 1641 ret = wc_InitSha384(&ssl->hsHashes->hashSha384);
wolfSSL 0:d92f9d21154c 1642 if (ret != 0) {
wolfSSL 0:d92f9d21154c 1643 return ret;
wolfSSL 0:d92f9d21154c 1644 }
wolfSSL 0:d92f9d21154c 1645 #endif
wolfSSL 0:d92f9d21154c 1646 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 1647 ret = wc_InitSha512(&ssl->hsHashes->hashSha512);
wolfSSL 0:d92f9d21154c 1648 if (ret != 0) {
wolfSSL 0:d92f9d21154c 1649 return ret;
wolfSSL 0:d92f9d21154c 1650 }
wolfSSL 0:d92f9d21154c 1651 #endif
wolfSSL 0:d92f9d21154c 1652
wolfSSL 0:d92f9d21154c 1653 /* increment CTX reference count */
wolfSSL 0:d92f9d21154c 1654 if (LockMutex(&ctx->countMutex) != 0) {
wolfSSL 0:d92f9d21154c 1655 WOLFSSL_MSG("Couldn't lock CTX count mutex");
wolfSSL 0:d92f9d21154c 1656 return BAD_MUTEX_E;
wolfSSL 0:d92f9d21154c 1657 }
wolfSSL 0:d92f9d21154c 1658 ctx->refCount++;
wolfSSL 0:d92f9d21154c 1659 UnLockMutex(&ctx->countMutex);
wolfSSL 0:d92f9d21154c 1660
wolfSSL 0:d92f9d21154c 1661 /* arrays */
wolfSSL 0:d92f9d21154c 1662 ssl->arrays = (Arrays*)XMALLOC(sizeof(Arrays), ssl->heap,
wolfSSL 0:d92f9d21154c 1663 DYNAMIC_TYPE_ARRAYS);
wolfSSL 0:d92f9d21154c 1664 if (ssl->arrays == NULL) {
wolfSSL 0:d92f9d21154c 1665 WOLFSSL_MSG("Arrays Memory error");
wolfSSL 0:d92f9d21154c 1666 return MEMORY_E;
wolfSSL 0:d92f9d21154c 1667 }
wolfSSL 0:d92f9d21154c 1668 XMEMSET(ssl->arrays, 0, sizeof(Arrays));
wolfSSL 0:d92f9d21154c 1669
wolfSSL 0:d92f9d21154c 1670 #ifndef NO_PSK
wolfSSL 0:d92f9d21154c 1671 if (ctx->server_hint[0]) { /* set in CTX */
wolfSSL 0:d92f9d21154c 1672 XSTRNCPY(ssl->arrays->server_hint, ctx->server_hint, MAX_PSK_ID_LEN);
wolfSSL 0:d92f9d21154c 1673 ssl->arrays->server_hint[MAX_PSK_ID_LEN - 1] = '\0';
wolfSSL 0:d92f9d21154c 1674 }
wolfSSL 0:d92f9d21154c 1675 #endif /* NO_PSK */
wolfSSL 0:d92f9d21154c 1676
wolfSSL 0:d92f9d21154c 1677 /* RNG */
wolfSSL 0:d92f9d21154c 1678 ssl->rng = (RNG*)XMALLOC(sizeof(RNG), ssl->heap, DYNAMIC_TYPE_RNG);
wolfSSL 0:d92f9d21154c 1679 if (ssl->rng == NULL) {
wolfSSL 0:d92f9d21154c 1680 WOLFSSL_MSG("RNG Memory error");
wolfSSL 0:d92f9d21154c 1681 return MEMORY_E;
wolfSSL 0:d92f9d21154c 1682 }
wolfSSL 0:d92f9d21154c 1683
wolfSSL 0:d92f9d21154c 1684 if ( (ret = wc_InitRng(ssl->rng)) != 0) {
wolfSSL 0:d92f9d21154c 1685 WOLFSSL_MSG("RNG Init error");
wolfSSL 0:d92f9d21154c 1686 return ret;
wolfSSL 0:d92f9d21154c 1687 }
wolfSSL 0:d92f9d21154c 1688
wolfSSL 0:d92f9d21154c 1689 /* suites */
wolfSSL 0:d92f9d21154c 1690 ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
wolfSSL 0:d92f9d21154c 1691 DYNAMIC_TYPE_SUITES);
wolfSSL 0:d92f9d21154c 1692 if (ssl->suites == NULL) {
wolfSSL 0:d92f9d21154c 1693 WOLFSSL_MSG("Suites Memory error");
wolfSSL 0:d92f9d21154c 1694 return MEMORY_E;
wolfSSL 0:d92f9d21154c 1695 }
wolfSSL 0:d92f9d21154c 1696 if (ctx->suites)
wolfSSL 0:d92f9d21154c 1697 *ssl->suites = *ctx->suites;
wolfSSL 0:d92f9d21154c 1698 else
wolfSSL 0:d92f9d21154c 1699 XMEMSET(ssl->suites, 0, sizeof(Suites));
wolfSSL 0:d92f9d21154c 1700
wolfSSL 0:d92f9d21154c 1701
wolfSSL 0:d92f9d21154c 1702 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 1703 /* make sure server has cert and key unless using PSK or Anon */
wolfSSL 0:d92f9d21154c 1704 if (ssl->options.side == WOLFSSL_SERVER_END && !havePSK && !haveAnon)
wolfSSL 0:d92f9d21154c 1705 if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer) {
wolfSSL 0:d92f9d21154c 1706 WOLFSSL_MSG("Server missing certificate and/or private key");
wolfSSL 0:d92f9d21154c 1707 return NO_PRIVATE_KEY;
wolfSSL 0:d92f9d21154c 1708 }
wolfSSL 0:d92f9d21154c 1709 #endif
wolfSSL 0:d92f9d21154c 1710 #ifdef HAVE_SECRET_CALLBACK
wolfSSL 0:d92f9d21154c 1711 ssl->sessionSecretCb = NULL;
wolfSSL 0:d92f9d21154c 1712 ssl->sessionSecretCtx = NULL;
wolfSSL 0:d92f9d21154c 1713 #endif
wolfSSL 0:d92f9d21154c 1714
wolfSSL 0:d92f9d21154c 1715 /* make sure server has DH parms, and add PSK if there, add NTRU too */
wolfSSL 0:d92f9d21154c 1716 if (ssl->options.side == WOLFSSL_SERVER_END)
wolfSSL 0:d92f9d21154c 1717 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
wolfSSL 0:d92f9d21154c 1718 ssl->options.haveDH, ssl->options.haveNTRU,
wolfSSL 0:d92f9d21154c 1719 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
wolfSSL 0:d92f9d21154c 1720 ssl->options.side);
wolfSSL 0:d92f9d21154c 1721 else
wolfSSL 0:d92f9d21154c 1722 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, TRUE,
wolfSSL 0:d92f9d21154c 1723 ssl->options.haveNTRU, ssl->options.haveECDSAsig,
wolfSSL 0:d92f9d21154c 1724 ssl->options.haveStaticECC, ssl->options.side);
wolfSSL 0:d92f9d21154c 1725
wolfSSL 0:d92f9d21154c 1726 return 0;
wolfSSL 0:d92f9d21154c 1727 }
wolfSSL 0:d92f9d21154c 1728
wolfSSL 0:d92f9d21154c 1729
wolfSSL 0:d92f9d21154c 1730 /* free use of temporary arrays */
wolfSSL 0:d92f9d21154c 1731 void FreeArrays(WOLFSSL* ssl, int keep)
wolfSSL 0:d92f9d21154c 1732 {
wolfSSL 0:d92f9d21154c 1733 if (ssl->arrays && keep) {
wolfSSL 0:d92f9d21154c 1734 /* keeps session id for user retrieval */
wolfSSL 0:d92f9d21154c 1735 XMEMCPY(ssl->session.sessionID, ssl->arrays->sessionID, ID_LEN);
wolfSSL 0:d92f9d21154c 1736 ssl->session.sessionIDSz = ssl->arrays->sessionIDSz;
wolfSSL 0:d92f9d21154c 1737 }
wolfSSL 0:d92f9d21154c 1738 XFREE(ssl->arrays, ssl->heap, DYNAMIC_TYPE_ARRAYS);
wolfSSL 0:d92f9d21154c 1739 ssl->arrays = NULL;
wolfSSL 0:d92f9d21154c 1740 }
wolfSSL 0:d92f9d21154c 1741
wolfSSL 0:d92f9d21154c 1742
wolfSSL 0:d92f9d21154c 1743 /* In case holding SSL object in array and don't want to free actual ssl */
wolfSSL 0:d92f9d21154c 1744 void SSL_ResourceFree(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 1745 {
wolfSSL 0:d92f9d21154c 1746 /* Note: any resources used during the handshake should be released in the
wolfSSL 0:d92f9d21154c 1747 * function FreeHandshakeResources(). Be careful with the special cases
wolfSSL 0:d92f9d21154c 1748 * like the RNG which may optionally be kept for the whole session. (For
wolfSSL 0:d92f9d21154c 1749 * example with the RNG, it isn't used beyond the handshake except when
wolfSSL 0:d92f9d21154c 1750 * using stream ciphers where it is retained. */
wolfSSL 0:d92f9d21154c 1751
wolfSSL 0:d92f9d21154c 1752 FreeCiphers(ssl);
wolfSSL 0:d92f9d21154c 1753 FreeArrays(ssl, 0);
wolfSSL 0:d92f9d21154c 1754 wc_FreeRng(ssl->rng);
wolfSSL 0:d92f9d21154c 1755 XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
wolfSSL 0:d92f9d21154c 1756 XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
wolfSSL 0:d92f9d21154c 1757 XFREE(ssl->hsHashes, ssl->heap, DYNAMIC_TYPE_HASHES);
wolfSSL 0:d92f9d21154c 1758 XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
wolfSSL 0:d92f9d21154c 1759
wolfSSL 0:d92f9d21154c 1760 #ifndef NO_DH
wolfSSL 0:d92f9d21154c 1761 XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 1762 XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 1763 /* parameters (p,g) may be owned by ctx */
wolfSSL 0:d92f9d21154c 1764 if (ssl->buffers.weOwnDH || ssl->options.side == WOLFSSL_CLIENT_END) {
wolfSSL 0:d92f9d21154c 1765 XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 1766 XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 1767 }
wolfSSL 0:d92f9d21154c 1768 #endif
wolfSSL 0:d92f9d21154c 1769 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 1770 if (ssl->buffers.weOwnCert)
wolfSSL 0:d92f9d21154c 1771 XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
wolfSSL 0:d92f9d21154c 1772 if (ssl->buffers.weOwnCertChain)
wolfSSL 0:d92f9d21154c 1773 XFREE(ssl->buffers.certChain.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
wolfSSL 0:d92f9d21154c 1774 if (ssl->buffers.weOwnKey)
wolfSSL 0:d92f9d21154c 1775 XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
wolfSSL 0:d92f9d21154c 1776 #endif
wolfSSL 0:d92f9d21154c 1777 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 1778 if (ssl->peerRsaKey) {
wolfSSL 0:d92f9d21154c 1779 wc_FreeRsaKey(ssl->peerRsaKey);
wolfSSL 0:d92f9d21154c 1780 XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
wolfSSL 0:d92f9d21154c 1781 }
wolfSSL 0:d92f9d21154c 1782 #endif
wolfSSL 0:d92f9d21154c 1783 if (ssl->buffers.inputBuffer.dynamicFlag)
wolfSSL 0:d92f9d21154c 1784 ShrinkInputBuffer(ssl, FORCED_FREE);
wolfSSL 0:d92f9d21154c 1785 if (ssl->buffers.outputBuffer.dynamicFlag)
wolfSSL 0:d92f9d21154c 1786 ShrinkOutputBuffer(ssl);
wolfSSL 0:d92f9d21154c 1787 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 1788 if (ssl->dtls_pool != NULL) {
wolfSSL 0:d92f9d21154c 1789 DtlsPoolReset(ssl);
wolfSSL 0:d92f9d21154c 1790 XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_NONE);
wolfSSL 0:d92f9d21154c 1791 }
wolfSSL 0:d92f9d21154c 1792 if (ssl->dtls_msg_list != NULL) {
wolfSSL 0:d92f9d21154c 1793 DtlsMsgListDelete(ssl->dtls_msg_list, ssl->heap);
wolfSSL 0:d92f9d21154c 1794 ssl->dtls_msg_list = NULL;
wolfSSL 0:d92f9d21154c 1795 }
wolfSSL 0:d92f9d21154c 1796 XFREE(ssl->buffers.dtlsCtx.peer.sa, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
wolfSSL 0:d92f9d21154c 1797 ssl->buffers.dtlsCtx.peer.sa = NULL;
wolfSSL 0:d92f9d21154c 1798 #endif
wolfSSL 0:d92f9d21154c 1799 #if defined(KEEP_PEER_CERT) || defined(GOAHEAD_WS)
wolfSSL 0:d92f9d21154c 1800 FreeX509(&ssl->peerCert);
wolfSSL 0:d92f9d21154c 1801 #endif
wolfSSL 0:d92f9d21154c 1802 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
wolfSSL 0:d92f9d21154c 1803 wolfSSL_BIO_free(ssl->biord);
wolfSSL 0:d92f9d21154c 1804 if (ssl->biord != ssl->biowr) /* in case same as write */
wolfSSL 0:d92f9d21154c 1805 wolfSSL_BIO_free(ssl->biowr);
wolfSSL 0:d92f9d21154c 1806 #endif
wolfSSL 0:d92f9d21154c 1807 #ifdef HAVE_LIBZ
wolfSSL 0:d92f9d21154c 1808 FreeStreams(ssl);
wolfSSL 0:d92f9d21154c 1809 #endif
wolfSSL 0:d92f9d21154c 1810 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 1811 if (ssl->peerEccKey) {
wolfSSL 0:d92f9d21154c 1812 if (ssl->peerEccKeyPresent)
wolfSSL 0:d92f9d21154c 1813 wc_ecc_free(ssl->peerEccKey);
wolfSSL 0:d92f9d21154c 1814 XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
wolfSSL 0:d92f9d21154c 1815 }
wolfSSL 0:d92f9d21154c 1816 if (ssl->peerEccDsaKey) {
wolfSSL 0:d92f9d21154c 1817 if (ssl->peerEccDsaKeyPresent)
wolfSSL 0:d92f9d21154c 1818 wc_ecc_free(ssl->peerEccDsaKey);
wolfSSL 0:d92f9d21154c 1819 XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
wolfSSL 0:d92f9d21154c 1820 }
wolfSSL 0:d92f9d21154c 1821 if (ssl->eccTempKey) {
wolfSSL 0:d92f9d21154c 1822 if (ssl->eccTempKeyPresent)
wolfSSL 0:d92f9d21154c 1823 wc_ecc_free(ssl->eccTempKey);
wolfSSL 0:d92f9d21154c 1824 XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
wolfSSL 0:d92f9d21154c 1825 }
wolfSSL 0:d92f9d21154c 1826 #endif
wolfSSL 0:d92f9d21154c 1827 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 1828 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 1829 XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
wolfSSL 0:d92f9d21154c 1830 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 1831 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 1832 XFREE(ssl->buffers.peerRsaKey.buffer, ssl->heap, DYNAMIC_TYPE_RSA);
wolfSSL 0:d92f9d21154c 1833 #endif /* NO_RSA */
wolfSSL 0:d92f9d21154c 1834 #endif /* HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 1835 #ifdef HAVE_TLS_EXTENSIONS
wolfSSL 0:d92f9d21154c 1836 TLSX_FreeAll(ssl->extensions);
wolfSSL 0:d92f9d21154c 1837 #endif
wolfSSL 0:d92f9d21154c 1838 #ifdef HAVE_NETX
wolfSSL 0:d92f9d21154c 1839 if (ssl->nxCtx.nxPacket)
wolfSSL 0:d92f9d21154c 1840 nx_packet_release(ssl->nxCtx.nxPacket);
wolfSSL 0:d92f9d21154c 1841 #endif
wolfSSL 0:d92f9d21154c 1842 }
wolfSSL 0:d92f9d21154c 1843
wolfSSL 0:d92f9d21154c 1844 #ifdef WOLFSSL_TI_HASH
wolfSSL 0:d92f9d21154c 1845 static void HashFinal(WOLFSSL * ssl) {
wolfSSL 0:d92f9d21154c 1846 byte dummyHash[32] ;
wolfSSL 0:d92f9d21154c 1847 #ifndef NO_MD5
wolfSSL 0:d92f9d21154c 1848 wc_Md5Final(&(ssl->hsHashes->hashMd5), dummyHash) ;
wolfSSL 0:d92f9d21154c 1849 #endif
wolfSSL 0:d92f9d21154c 1850 #ifndef NO_SHA
wolfSSL 0:d92f9d21154c 1851 wc_ShaFinal(&(ssl->hsHashes->hashSha), dummyHash) ;
wolfSSL 0:d92f9d21154c 1852 #endif
wolfSSL 0:d92f9d21154c 1853 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 1854 wc_Sha256Final(&(ssl->hsHashes->hashSha256), dummyHash) ;
wolfSSL 0:d92f9d21154c 1855 #endif
wolfSSL 0:d92f9d21154c 1856 }
wolfSSL 0:d92f9d21154c 1857 #else
wolfSSL 0:d92f9d21154c 1858
wolfSSL 0:d92f9d21154c 1859 #define HashFinal(ssl)
wolfSSL 0:d92f9d21154c 1860
wolfSSL 0:d92f9d21154c 1861 #endif
wolfSSL 0:d92f9d21154c 1862
wolfSSL 0:d92f9d21154c 1863 /* Free any handshake resources no longer needed */
wolfSSL 0:d92f9d21154c 1864 void FreeHandshakeResources(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 1865 {
wolfSSL 0:d92f9d21154c 1866
wolfSSL 0:d92f9d21154c 1867 HashFinal(ssl) ;
wolfSSL 0:d92f9d21154c 1868 #ifdef HAVE_SECURE_RENEGOTIATION
wolfSSL 0:d92f9d21154c 1869 if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
wolfSSL 0:d92f9d21154c 1870 WOLFSSL_MSG("Secure Renegotiation needs to retain handshake resources");
wolfSSL 0:d92f9d21154c 1871 return;
wolfSSL 0:d92f9d21154c 1872 }
wolfSSL 0:d92f9d21154c 1873 #endif
wolfSSL 0:d92f9d21154c 1874
wolfSSL 0:d92f9d21154c 1875 /* input buffer */
wolfSSL 0:d92f9d21154c 1876 if (ssl->buffers.inputBuffer.dynamicFlag)
wolfSSL 0:d92f9d21154c 1877 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
wolfSSL 0:d92f9d21154c 1878
wolfSSL 0:d92f9d21154c 1879 /* suites */
wolfSSL 0:d92f9d21154c 1880 XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES);
wolfSSL 0:d92f9d21154c 1881 ssl->suites = NULL;
wolfSSL 0:d92f9d21154c 1882
wolfSSL 0:d92f9d21154c 1883 /* hsHashes */
wolfSSL 0:d92f9d21154c 1884 XFREE(ssl->hsHashes, ssl->heap, DYNAMIC_TYPE_HASHES);
wolfSSL 0:d92f9d21154c 1885 ssl->hsHashes = NULL;
wolfSSL 0:d92f9d21154c 1886
wolfSSL 0:d92f9d21154c 1887 /* RNG */
wolfSSL 0:d92f9d21154c 1888 if (ssl->specs.cipher_type == stream || ssl->options.tls1_1 == 0) {
wolfSSL 0:d92f9d21154c 1889 wc_FreeRng(ssl->rng);
wolfSSL 0:d92f9d21154c 1890 XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
wolfSSL 0:d92f9d21154c 1891 ssl->rng = NULL;
wolfSSL 0:d92f9d21154c 1892 }
wolfSSL 0:d92f9d21154c 1893
wolfSSL 0:d92f9d21154c 1894 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 1895 /* DTLS_POOL */
wolfSSL 0:d92f9d21154c 1896 if (ssl->options.dtls && ssl->dtls_pool != NULL) {
wolfSSL 0:d92f9d21154c 1897 DtlsPoolReset(ssl);
wolfSSL 0:d92f9d21154c 1898 XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
wolfSSL 0:d92f9d21154c 1899 ssl->dtls_pool = NULL;
wolfSSL 0:d92f9d21154c 1900 }
wolfSSL 0:d92f9d21154c 1901 #endif
wolfSSL 0:d92f9d21154c 1902
wolfSSL 0:d92f9d21154c 1903 /* arrays */
wolfSSL 0:d92f9d21154c 1904 if (ssl->options.saveArrays == 0)
wolfSSL 0:d92f9d21154c 1905 FreeArrays(ssl, 1);
wolfSSL 0:d92f9d21154c 1906
wolfSSL 0:d92f9d21154c 1907 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 1908 /* peerRsaKey */
wolfSSL 0:d92f9d21154c 1909 if (ssl->peerRsaKey) {
wolfSSL 0:d92f9d21154c 1910 wc_FreeRsaKey(ssl->peerRsaKey);
wolfSSL 0:d92f9d21154c 1911 XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA);
wolfSSL 0:d92f9d21154c 1912 ssl->peerRsaKey = NULL;
wolfSSL 0:d92f9d21154c 1913 }
wolfSSL 0:d92f9d21154c 1914 #endif
wolfSSL 0:d92f9d21154c 1915
wolfSSL 0:d92f9d21154c 1916 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 1917 if (ssl->peerEccKey)
wolfSSL 0:d92f9d21154c 1918 {
wolfSSL 0:d92f9d21154c 1919 if (ssl->peerEccKeyPresent) {
wolfSSL 0:d92f9d21154c 1920 wc_ecc_free(ssl->peerEccKey);
wolfSSL 0:d92f9d21154c 1921 ssl->peerEccKeyPresent = 0;
wolfSSL 0:d92f9d21154c 1922 }
wolfSSL 0:d92f9d21154c 1923 XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
wolfSSL 0:d92f9d21154c 1924 ssl->peerEccKey = NULL;
wolfSSL 0:d92f9d21154c 1925 }
wolfSSL 0:d92f9d21154c 1926 if (ssl->peerEccDsaKey)
wolfSSL 0:d92f9d21154c 1927 {
wolfSSL 0:d92f9d21154c 1928 if (ssl->peerEccDsaKeyPresent) {
wolfSSL 0:d92f9d21154c 1929 wc_ecc_free(ssl->peerEccDsaKey);
wolfSSL 0:d92f9d21154c 1930 ssl->peerEccDsaKeyPresent = 0;
wolfSSL 0:d92f9d21154c 1931 }
wolfSSL 0:d92f9d21154c 1932 XFREE(ssl->peerEccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
wolfSSL 0:d92f9d21154c 1933 ssl->peerEccDsaKey = NULL;
wolfSSL 0:d92f9d21154c 1934 }
wolfSSL 0:d92f9d21154c 1935 if (ssl->eccTempKey)
wolfSSL 0:d92f9d21154c 1936 {
wolfSSL 0:d92f9d21154c 1937 if (ssl->eccTempKeyPresent) {
wolfSSL 0:d92f9d21154c 1938 wc_ecc_free(ssl->eccTempKey);
wolfSSL 0:d92f9d21154c 1939 ssl->eccTempKeyPresent = 0;
wolfSSL 0:d92f9d21154c 1940 }
wolfSSL 0:d92f9d21154c 1941 XFREE(ssl->eccTempKey, ssl->heap, DYNAMIC_TYPE_ECC);
wolfSSL 0:d92f9d21154c 1942 ssl->eccTempKey = NULL;
wolfSSL 0:d92f9d21154c 1943 }
wolfSSL 0:d92f9d21154c 1944 #endif
wolfSSL 0:d92f9d21154c 1945 #ifndef NO_DH
wolfSSL 0:d92f9d21154c 1946 XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 1947 ssl->buffers.serverDH_Priv.buffer = NULL;
wolfSSL 0:d92f9d21154c 1948 XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 1949 ssl->buffers.serverDH_Pub.buffer = NULL;
wolfSSL 0:d92f9d21154c 1950 /* parameters (p,g) may be owned by ctx */
wolfSSL 0:d92f9d21154c 1951 if (ssl->buffers.weOwnDH || ssl->options.side == WOLFSSL_CLIENT_END) {
wolfSSL 0:d92f9d21154c 1952 XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 1953 ssl->buffers.serverDH_G.buffer = NULL;
wolfSSL 0:d92f9d21154c 1954 XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 1955 ssl->buffers.serverDH_P.buffer = NULL;
wolfSSL 0:d92f9d21154c 1956 }
wolfSSL 0:d92f9d21154c 1957 #endif
wolfSSL 0:d92f9d21154c 1958 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 1959 if (ssl->buffers.weOwnCert) {
wolfSSL 0:d92f9d21154c 1960 XFREE(ssl->buffers.certificate.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
wolfSSL 0:d92f9d21154c 1961 ssl->buffers.certificate.buffer = NULL;
wolfSSL 0:d92f9d21154c 1962 }
wolfSSL 0:d92f9d21154c 1963 if (ssl->buffers.weOwnCertChain) {
wolfSSL 0:d92f9d21154c 1964 XFREE(ssl->buffers.certChain.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
wolfSSL 0:d92f9d21154c 1965 ssl->buffers.certChain.buffer = NULL;
wolfSSL 0:d92f9d21154c 1966 }
wolfSSL 0:d92f9d21154c 1967 if (ssl->buffers.weOwnKey) {
wolfSSL 0:d92f9d21154c 1968 XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY);
wolfSSL 0:d92f9d21154c 1969 ssl->buffers.key.buffer = NULL;
wolfSSL 0:d92f9d21154c 1970 }
wolfSSL 0:d92f9d21154c 1971 #endif
wolfSSL 0:d92f9d21154c 1972 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 1973 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 1974 XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
wolfSSL 0:d92f9d21154c 1975 ssl->buffers.peerEccDsaKey.buffer = NULL;
wolfSSL 0:d92f9d21154c 1976 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 1977 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 1978 XFREE(ssl->buffers.peerRsaKey.buffer, ssl->heap, DYNAMIC_TYPE_RSA);
wolfSSL 0:d92f9d21154c 1979 ssl->buffers.peerRsaKey.buffer = NULL;
wolfSSL 0:d92f9d21154c 1980 #endif /* NO_RSA */
wolfSSL 0:d92f9d21154c 1981 #endif /* HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 1982 }
wolfSSL 0:d92f9d21154c 1983
wolfSSL 0:d92f9d21154c 1984
wolfSSL 0:d92f9d21154c 1985 void FreeSSL(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 1986 {
wolfSSL 0:d92f9d21154c 1987 FreeSSL_Ctx(ssl->ctx); /* will decrement and free underyling CTX if 0 */
wolfSSL 0:d92f9d21154c 1988 SSL_ResourceFree(ssl);
wolfSSL 0:d92f9d21154c 1989 XFREE(ssl, ssl->heap, DYNAMIC_TYPE_SSL);
wolfSSL 0:d92f9d21154c 1990 }
wolfSSL 0:d92f9d21154c 1991
wolfSSL 0:d92f9d21154c 1992
wolfSSL 0:d92f9d21154c 1993 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 1994
wolfSSL 0:d92f9d21154c 1995 int DtlsPoolInit(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 1996 {
wolfSSL 0:d92f9d21154c 1997 if (ssl->dtls_pool == NULL) {
wolfSSL 0:d92f9d21154c 1998 DtlsPool *pool = (DtlsPool*)XMALLOC(sizeof(DtlsPool),
wolfSSL 0:d92f9d21154c 1999 ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
wolfSSL 0:d92f9d21154c 2000 if (pool == NULL) {
wolfSSL 0:d92f9d21154c 2001 WOLFSSL_MSG("DTLS Buffer Pool Memory error");
wolfSSL 0:d92f9d21154c 2002 return MEMORY_E;
wolfSSL 0:d92f9d21154c 2003 }
wolfSSL 0:d92f9d21154c 2004 else {
wolfSSL 0:d92f9d21154c 2005 int i;
wolfSSL 0:d92f9d21154c 2006
wolfSSL 0:d92f9d21154c 2007 for (i = 0; i < DTLS_POOL_SZ; i++) {
wolfSSL 0:d92f9d21154c 2008 pool->buf[i].length = 0;
wolfSSL 0:d92f9d21154c 2009 pool->buf[i].buffer = NULL;
wolfSSL 0:d92f9d21154c 2010 }
wolfSSL 0:d92f9d21154c 2011 pool->used = 0;
wolfSSL 0:d92f9d21154c 2012 ssl->dtls_pool = pool;
wolfSSL 0:d92f9d21154c 2013 }
wolfSSL 0:d92f9d21154c 2014 }
wolfSSL 0:d92f9d21154c 2015 return 0;
wolfSSL 0:d92f9d21154c 2016 }
wolfSSL 0:d92f9d21154c 2017
wolfSSL 0:d92f9d21154c 2018
wolfSSL 0:d92f9d21154c 2019 int DtlsPoolSave(WOLFSSL* ssl, const byte *src, int sz)
wolfSSL 0:d92f9d21154c 2020 {
wolfSSL 0:d92f9d21154c 2021 DtlsPool *pool = ssl->dtls_pool;
wolfSSL 0:d92f9d21154c 2022 if (pool != NULL && pool->used < DTLS_POOL_SZ) {
wolfSSL 0:d92f9d21154c 2023 buffer *pBuf = &pool->buf[pool->used];
wolfSSL 0:d92f9d21154c 2024 pBuf->buffer = (byte*)XMALLOC(sz, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
wolfSSL 0:d92f9d21154c 2025 if (pBuf->buffer == NULL) {
wolfSSL 0:d92f9d21154c 2026 WOLFSSL_MSG("DTLS Buffer Memory error");
wolfSSL 0:d92f9d21154c 2027 return MEMORY_ERROR;
wolfSSL 0:d92f9d21154c 2028 }
wolfSSL 0:d92f9d21154c 2029 XMEMCPY(pBuf->buffer, src, sz);
wolfSSL 0:d92f9d21154c 2030 pBuf->length = (word32)sz;
wolfSSL 0:d92f9d21154c 2031 pool->used++;
wolfSSL 0:d92f9d21154c 2032 }
wolfSSL 0:d92f9d21154c 2033 return 0;
wolfSSL 0:d92f9d21154c 2034 }
wolfSSL 0:d92f9d21154c 2035
wolfSSL 0:d92f9d21154c 2036
wolfSSL 0:d92f9d21154c 2037 void DtlsPoolReset(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 2038 {
wolfSSL 0:d92f9d21154c 2039 DtlsPool *pool = ssl->dtls_pool;
wolfSSL 0:d92f9d21154c 2040 if (pool != NULL) {
wolfSSL 0:d92f9d21154c 2041 buffer *pBuf;
wolfSSL 0:d92f9d21154c 2042 int i, used;
wolfSSL 0:d92f9d21154c 2043
wolfSSL 0:d92f9d21154c 2044 used = pool->used;
wolfSSL 0:d92f9d21154c 2045 for (i = 0, pBuf = &pool->buf[0]; i < used; i++, pBuf++) {
wolfSSL 0:d92f9d21154c 2046 XFREE(pBuf->buffer, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
wolfSSL 0:d92f9d21154c 2047 pBuf->buffer = NULL;
wolfSSL 0:d92f9d21154c 2048 pBuf->length = 0;
wolfSSL 0:d92f9d21154c 2049 }
wolfSSL 0:d92f9d21154c 2050 pool->used = 0;
wolfSSL 0:d92f9d21154c 2051 }
wolfSSL 0:d92f9d21154c 2052 ssl->dtls_timeout = ssl->dtls_timeout_init;
wolfSSL 0:d92f9d21154c 2053 }
wolfSSL 0:d92f9d21154c 2054
wolfSSL 0:d92f9d21154c 2055
wolfSSL 0:d92f9d21154c 2056 int DtlsPoolTimeout(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 2057 {
wolfSSL 0:d92f9d21154c 2058 int result = -1;
wolfSSL 0:d92f9d21154c 2059 if (ssl->dtls_timeout < ssl->dtls_timeout_max) {
wolfSSL 0:d92f9d21154c 2060 ssl->dtls_timeout *= DTLS_TIMEOUT_MULTIPLIER;
wolfSSL 0:d92f9d21154c 2061 result = 0;
wolfSSL 0:d92f9d21154c 2062 }
wolfSSL 0:d92f9d21154c 2063 return result;
wolfSSL 0:d92f9d21154c 2064 }
wolfSSL 0:d92f9d21154c 2065
wolfSSL 0:d92f9d21154c 2066
wolfSSL 0:d92f9d21154c 2067 int DtlsPoolSend(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 2068 {
wolfSSL 0:d92f9d21154c 2069 int ret;
wolfSSL 0:d92f9d21154c 2070 DtlsPool *pool = ssl->dtls_pool;
wolfSSL 0:d92f9d21154c 2071
wolfSSL 0:d92f9d21154c 2072 if (pool != NULL && pool->used > 0) {
wolfSSL 0:d92f9d21154c 2073 int i;
wolfSSL 0:d92f9d21154c 2074 for (i = 0; i < pool->used; i++) {
wolfSSL 0:d92f9d21154c 2075 int sendResult;
wolfSSL 0:d92f9d21154c 2076 buffer* buf = &pool->buf[i];
wolfSSL 0:d92f9d21154c 2077
wolfSSL 0:d92f9d21154c 2078 DtlsRecordLayerHeader* dtls = (DtlsRecordLayerHeader*)buf->buffer;
wolfSSL 0:d92f9d21154c 2079
wolfSSL 0:d92f9d21154c 2080 word16 message_epoch;
wolfSSL 0:d92f9d21154c 2081 ato16(dtls->epoch, &message_epoch);
wolfSSL 0:d92f9d21154c 2082 if (message_epoch == ssl->keys.dtls_epoch) {
wolfSSL 0:d92f9d21154c 2083 /* Increment record sequence number on retransmitted handshake
wolfSSL 0:d92f9d21154c 2084 * messages */
wolfSSL 0:d92f9d21154c 2085 c32to48(ssl->keys.dtls_sequence_number, dtls->sequence_number);
wolfSSL 0:d92f9d21154c 2086 ssl->keys.dtls_sequence_number++;
wolfSSL 0:d92f9d21154c 2087 }
wolfSSL 0:d92f9d21154c 2088 else {
wolfSSL 0:d92f9d21154c 2089 /* The Finished message is sent with the next epoch, keep its
wolfSSL 0:d92f9d21154c 2090 * sequence number */
wolfSSL 0:d92f9d21154c 2091 }
wolfSSL 0:d92f9d21154c 2092
wolfSSL 0:d92f9d21154c 2093 if ((ret = CheckAvailableSize(ssl, buf->length)) != 0)
wolfSSL 0:d92f9d21154c 2094 return ret;
wolfSSL 0:d92f9d21154c 2095
wolfSSL 0:d92f9d21154c 2096 XMEMCPY(ssl->buffers.outputBuffer.buffer, buf->buffer, buf->length);
wolfSSL 0:d92f9d21154c 2097 ssl->buffers.outputBuffer.idx = 0;
wolfSSL 0:d92f9d21154c 2098 ssl->buffers.outputBuffer.length = buf->length;
wolfSSL 0:d92f9d21154c 2099
wolfSSL 0:d92f9d21154c 2100 sendResult = SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 2101 if (sendResult < 0) {
wolfSSL 0:d92f9d21154c 2102 return sendResult;
wolfSSL 0:d92f9d21154c 2103 }
wolfSSL 0:d92f9d21154c 2104 }
wolfSSL 0:d92f9d21154c 2105 }
wolfSSL 0:d92f9d21154c 2106 return 0;
wolfSSL 0:d92f9d21154c 2107 }
wolfSSL 0:d92f9d21154c 2108
wolfSSL 0:d92f9d21154c 2109
wolfSSL 0:d92f9d21154c 2110 /* functions for managing DTLS datagram reordering */
wolfSSL 0:d92f9d21154c 2111
wolfSSL 0:d92f9d21154c 2112 /* Need to allocate space for the handshake message header. The hashing
wolfSSL 0:d92f9d21154c 2113 * routines assume the message pointer is still within the buffer that
wolfSSL 0:d92f9d21154c 2114 * has the headers, and will include those headers in the hash. The store
wolfSSL 0:d92f9d21154c 2115 * routines need to take that into account as well. New will allocate
wolfSSL 0:d92f9d21154c 2116 * extra space for the headers. */
wolfSSL 0:d92f9d21154c 2117 DtlsMsg* DtlsMsgNew(word32 sz, void* heap)
wolfSSL 0:d92f9d21154c 2118 {
wolfSSL 0:d92f9d21154c 2119 DtlsMsg* msg = NULL;
wolfSSL 0:d92f9d21154c 2120
wolfSSL 0:d92f9d21154c 2121 msg = (DtlsMsg*)XMALLOC(sizeof(DtlsMsg), heap, DYNAMIC_TYPE_DTLS_MSG);
wolfSSL 0:d92f9d21154c 2122
wolfSSL 0:d92f9d21154c 2123 if (msg != NULL) {
wolfSSL 0:d92f9d21154c 2124 msg->buf = (byte*)XMALLOC(sz + DTLS_HANDSHAKE_HEADER_SZ,
wolfSSL 0:d92f9d21154c 2125 heap, DYNAMIC_TYPE_NONE);
wolfSSL 0:d92f9d21154c 2126 if (msg->buf != NULL) {
wolfSSL 0:d92f9d21154c 2127 msg->next = NULL;
wolfSSL 0:d92f9d21154c 2128 msg->seq = 0;
wolfSSL 0:d92f9d21154c 2129 msg->sz = sz;
wolfSSL 0:d92f9d21154c 2130 msg->fragSz = 0;
wolfSSL 0:d92f9d21154c 2131 msg->msg = msg->buf + DTLS_HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 2132 }
wolfSSL 0:d92f9d21154c 2133 else {
wolfSSL 0:d92f9d21154c 2134 XFREE(msg, heap, DYNAMIC_TYPE_DTLS_MSG);
wolfSSL 0:d92f9d21154c 2135 msg = NULL;
wolfSSL 0:d92f9d21154c 2136 }
wolfSSL 0:d92f9d21154c 2137 }
wolfSSL 0:d92f9d21154c 2138
wolfSSL 0:d92f9d21154c 2139 return msg;
wolfSSL 0:d92f9d21154c 2140 }
wolfSSL 0:d92f9d21154c 2141
wolfSSL 0:d92f9d21154c 2142 void DtlsMsgDelete(DtlsMsg* item, void* heap)
wolfSSL 0:d92f9d21154c 2143 {
wolfSSL 0:d92f9d21154c 2144 (void)heap;
wolfSSL 0:d92f9d21154c 2145
wolfSSL 0:d92f9d21154c 2146 if (item != NULL) {
wolfSSL 0:d92f9d21154c 2147 if (item->buf != NULL)
wolfSSL 0:d92f9d21154c 2148 XFREE(item->buf, heap, DYNAMIC_TYPE_NONE);
wolfSSL 0:d92f9d21154c 2149 XFREE(item, heap, DYNAMIC_TYPE_DTLS_MSG);
wolfSSL 0:d92f9d21154c 2150 }
wolfSSL 0:d92f9d21154c 2151 }
wolfSSL 0:d92f9d21154c 2152
wolfSSL 0:d92f9d21154c 2153
wolfSSL 0:d92f9d21154c 2154 void DtlsMsgListDelete(DtlsMsg* head, void* heap)
wolfSSL 0:d92f9d21154c 2155 {
wolfSSL 0:d92f9d21154c 2156 DtlsMsg* next;
wolfSSL 0:d92f9d21154c 2157 while (head) {
wolfSSL 0:d92f9d21154c 2158 next = head->next;
wolfSSL 0:d92f9d21154c 2159 DtlsMsgDelete(head, heap);
wolfSSL 0:d92f9d21154c 2160 head = next;
wolfSSL 0:d92f9d21154c 2161 }
wolfSSL 0:d92f9d21154c 2162 }
wolfSSL 0:d92f9d21154c 2163
wolfSSL 0:d92f9d21154c 2164
wolfSSL 0:d92f9d21154c 2165 void DtlsMsgSet(DtlsMsg* msg, word32 seq, const byte* data, byte type,
wolfSSL 0:d92f9d21154c 2166 word32 fragOffset, word32 fragSz)
wolfSSL 0:d92f9d21154c 2167 {
wolfSSL 0:d92f9d21154c 2168 if (msg != NULL && data != NULL && msg->fragSz <= msg->sz &&
wolfSSL 0:d92f9d21154c 2169 fragOffset <= msg->sz && (fragOffset + fragSz) <= msg->sz) {
wolfSSL 0:d92f9d21154c 2170
wolfSSL 0:d92f9d21154c 2171 msg->seq = seq;
wolfSSL 0:d92f9d21154c 2172 msg->type = type;
wolfSSL 0:d92f9d21154c 2173 msg->fragSz += fragSz;
wolfSSL 0:d92f9d21154c 2174 /* If fragOffset is zero, this is either a full message that is out
wolfSSL 0:d92f9d21154c 2175 * of order, or the first fragment of a fragmented message. Copy the
wolfSSL 0:d92f9d21154c 2176 * handshake message header with the message data. Zero length messages
wolfSSL 0:d92f9d21154c 2177 * like Server Hello Done should be saved as well. */
wolfSSL 0:d92f9d21154c 2178 if (fragOffset == 0)
wolfSSL 0:d92f9d21154c 2179 XMEMCPY(msg->buf, data - DTLS_HANDSHAKE_HEADER_SZ,
wolfSSL 0:d92f9d21154c 2180 fragSz + DTLS_HANDSHAKE_HEADER_SZ);
wolfSSL 0:d92f9d21154c 2181 else {
wolfSSL 0:d92f9d21154c 2182 /* If fragOffet is non-zero, this is an additional fragment that
wolfSSL 0:d92f9d21154c 2183 * needs to be copied to its location in the message buffer. Also
wolfSSL 0:d92f9d21154c 2184 * copy the total size of the message over the fragment size. The
wolfSSL 0:d92f9d21154c 2185 * hash routines look at a defragmented message if it had actually
wolfSSL 0:d92f9d21154c 2186 * come across as a single handshake message. */
wolfSSL 0:d92f9d21154c 2187 XMEMCPY(msg->msg + fragOffset, data, fragSz);
wolfSSL 0:d92f9d21154c 2188 }
wolfSSL 0:d92f9d21154c 2189 c32to24(msg->sz, msg->msg - DTLS_HANDSHAKE_FRAG_SZ);
wolfSSL 0:d92f9d21154c 2190 }
wolfSSL 0:d92f9d21154c 2191 }
wolfSSL 0:d92f9d21154c 2192
wolfSSL 0:d92f9d21154c 2193
wolfSSL 0:d92f9d21154c 2194 DtlsMsg* DtlsMsgFind(DtlsMsg* head, word32 seq)
wolfSSL 0:d92f9d21154c 2195 {
wolfSSL 0:d92f9d21154c 2196 while (head != NULL && head->seq != seq) {
wolfSSL 0:d92f9d21154c 2197 head = head->next;
wolfSSL 0:d92f9d21154c 2198 }
wolfSSL 0:d92f9d21154c 2199 return head;
wolfSSL 0:d92f9d21154c 2200 }
wolfSSL 0:d92f9d21154c 2201
wolfSSL 0:d92f9d21154c 2202
wolfSSL 0:d92f9d21154c 2203 DtlsMsg* DtlsMsgStore(DtlsMsg* head, word32 seq, const byte* data,
wolfSSL 0:d92f9d21154c 2204 word32 dataSz, byte type, word32 fragOffset, word32 fragSz, void* heap)
wolfSSL 0:d92f9d21154c 2205 {
wolfSSL 0:d92f9d21154c 2206
wolfSSL 0:d92f9d21154c 2207 /* See if seq exists in the list. If it isn't in the list, make
wolfSSL 0:d92f9d21154c 2208 * a new item of size dataSz, copy fragSz bytes from data to msg->msg
wolfSSL 0:d92f9d21154c 2209 * starting at offset fragOffset, and add fragSz to msg->fragSz. If
wolfSSL 0:d92f9d21154c 2210 * the seq is in the list and it isn't full, copy fragSz bytes from
wolfSSL 0:d92f9d21154c 2211 * data to msg->msg starting at offset fragOffset, and add fragSz to
wolfSSL 0:d92f9d21154c 2212 * msg->fragSz. The new item should be inserted into the list in its
wolfSSL 0:d92f9d21154c 2213 * proper position.
wolfSSL 0:d92f9d21154c 2214 *
wolfSSL 0:d92f9d21154c 2215 * 1. Find seq in list, or where seq should go in list. If seq not in
wolfSSL 0:d92f9d21154c 2216 * list, create new item and insert into list. Either case, keep
wolfSSL 0:d92f9d21154c 2217 * pointer to item.
wolfSSL 0:d92f9d21154c 2218 * 2. If msg->fragSz + fragSz < sz, copy data to msg->msg at offset
wolfSSL 0:d92f9d21154c 2219 * fragOffset. Add fragSz to msg->fragSz.
wolfSSL 0:d92f9d21154c 2220 */
wolfSSL 0:d92f9d21154c 2221
wolfSSL 0:d92f9d21154c 2222 if (head != NULL) {
wolfSSL 0:d92f9d21154c 2223 DtlsMsg* cur = DtlsMsgFind(head, seq);
wolfSSL 0:d92f9d21154c 2224 if (cur == NULL) {
wolfSSL 0:d92f9d21154c 2225 cur = DtlsMsgNew(dataSz, heap);
wolfSSL 0:d92f9d21154c 2226 if (cur != NULL) {
wolfSSL 0:d92f9d21154c 2227 DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz);
wolfSSL 0:d92f9d21154c 2228 head = DtlsMsgInsert(head, cur);
wolfSSL 0:d92f9d21154c 2229 }
wolfSSL 0:d92f9d21154c 2230 }
wolfSSL 0:d92f9d21154c 2231 else {
wolfSSL 0:d92f9d21154c 2232 DtlsMsgSet(cur, seq, data, type, fragOffset, fragSz);
wolfSSL 0:d92f9d21154c 2233 }
wolfSSL 0:d92f9d21154c 2234 }
wolfSSL 0:d92f9d21154c 2235 else {
wolfSSL 0:d92f9d21154c 2236 head = DtlsMsgNew(dataSz, heap);
wolfSSL 0:d92f9d21154c 2237 DtlsMsgSet(head, seq, data, type, fragOffset, fragSz);
wolfSSL 0:d92f9d21154c 2238 }
wolfSSL 0:d92f9d21154c 2239
wolfSSL 0:d92f9d21154c 2240 return head;
wolfSSL 0:d92f9d21154c 2241 }
wolfSSL 0:d92f9d21154c 2242
wolfSSL 0:d92f9d21154c 2243
wolfSSL 0:d92f9d21154c 2244 /* DtlsMsgInsert() is an in-order insert. */
wolfSSL 0:d92f9d21154c 2245 DtlsMsg* DtlsMsgInsert(DtlsMsg* head, DtlsMsg* item)
wolfSSL 0:d92f9d21154c 2246 {
wolfSSL 0:d92f9d21154c 2247 if (head == NULL || item->seq < head->seq) {
wolfSSL 0:d92f9d21154c 2248 item->next = head;
wolfSSL 0:d92f9d21154c 2249 head = item;
wolfSSL 0:d92f9d21154c 2250 }
wolfSSL 0:d92f9d21154c 2251 else if (head->next == NULL) {
wolfSSL 0:d92f9d21154c 2252 head->next = item;
wolfSSL 0:d92f9d21154c 2253 }
wolfSSL 0:d92f9d21154c 2254 else {
wolfSSL 0:d92f9d21154c 2255 DtlsMsg* cur = head->next;
wolfSSL 0:d92f9d21154c 2256 DtlsMsg* prev = head;
wolfSSL 0:d92f9d21154c 2257 while (cur) {
wolfSSL 0:d92f9d21154c 2258 if (item->seq < cur->seq) {
wolfSSL 0:d92f9d21154c 2259 item->next = cur;
wolfSSL 0:d92f9d21154c 2260 prev->next = item;
wolfSSL 0:d92f9d21154c 2261 break;
wolfSSL 0:d92f9d21154c 2262 }
wolfSSL 0:d92f9d21154c 2263 prev = cur;
wolfSSL 0:d92f9d21154c 2264 cur = cur->next;
wolfSSL 0:d92f9d21154c 2265 }
wolfSSL 0:d92f9d21154c 2266 if (cur == NULL) {
wolfSSL 0:d92f9d21154c 2267 prev->next = item;
wolfSSL 0:d92f9d21154c 2268 }
wolfSSL 0:d92f9d21154c 2269 }
wolfSSL 0:d92f9d21154c 2270
wolfSSL 0:d92f9d21154c 2271 return head;
wolfSSL 0:d92f9d21154c 2272 }
wolfSSL 0:d92f9d21154c 2273
wolfSSL 0:d92f9d21154c 2274 #endif /* WOLFSSL_DTLS */
wolfSSL 0:d92f9d21154c 2275
wolfSSL 0:d92f9d21154c 2276 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 2277
wolfSSL 0:d92f9d21154c 2278 ProtocolVersion MakeSSLv3(void)
wolfSSL 0:d92f9d21154c 2279 {
wolfSSL 0:d92f9d21154c 2280 ProtocolVersion pv;
wolfSSL 0:d92f9d21154c 2281 pv.major = SSLv3_MAJOR;
wolfSSL 0:d92f9d21154c 2282 pv.minor = SSLv3_MINOR;
wolfSSL 0:d92f9d21154c 2283
wolfSSL 0:d92f9d21154c 2284 return pv;
wolfSSL 0:d92f9d21154c 2285 }
wolfSSL 0:d92f9d21154c 2286
wolfSSL 0:d92f9d21154c 2287 #endif /* NO_OLD_TLS */
wolfSSL 0:d92f9d21154c 2288
wolfSSL 0:d92f9d21154c 2289
wolfSSL 0:d92f9d21154c 2290 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 2291
wolfSSL 0:d92f9d21154c 2292 ProtocolVersion MakeDTLSv1(void)
wolfSSL 0:d92f9d21154c 2293 {
wolfSSL 0:d92f9d21154c 2294 ProtocolVersion pv;
wolfSSL 0:d92f9d21154c 2295 pv.major = DTLS_MAJOR;
wolfSSL 0:d92f9d21154c 2296 pv.minor = DTLS_MINOR;
wolfSSL 0:d92f9d21154c 2297
wolfSSL 0:d92f9d21154c 2298 return pv;
wolfSSL 0:d92f9d21154c 2299 }
wolfSSL 0:d92f9d21154c 2300
wolfSSL 0:d92f9d21154c 2301 ProtocolVersion MakeDTLSv1_2(void)
wolfSSL 0:d92f9d21154c 2302 {
wolfSSL 0:d92f9d21154c 2303 ProtocolVersion pv;
wolfSSL 0:d92f9d21154c 2304 pv.major = DTLS_MAJOR;
wolfSSL 0:d92f9d21154c 2305 pv.minor = DTLSv1_2_MINOR;
wolfSSL 0:d92f9d21154c 2306
wolfSSL 0:d92f9d21154c 2307 return pv;
wolfSSL 0:d92f9d21154c 2308 }
wolfSSL 0:d92f9d21154c 2309
wolfSSL 0:d92f9d21154c 2310 #endif /* WOLFSSL_DTLS */
wolfSSL 0:d92f9d21154c 2311
wolfSSL 0:d92f9d21154c 2312
wolfSSL 0:d92f9d21154c 2313
wolfSSL 0:d92f9d21154c 2314
wolfSSL 0:d92f9d21154c 2315 #ifdef USE_WINDOWS_API
wolfSSL 0:d92f9d21154c 2316
wolfSSL 0:d92f9d21154c 2317 word32 LowResTimer(void)
wolfSSL 0:d92f9d21154c 2318 {
wolfSSL 0:d92f9d21154c 2319 static int init = 0;
wolfSSL 0:d92f9d21154c 2320 static LARGE_INTEGER freq;
wolfSSL 0:d92f9d21154c 2321 LARGE_INTEGER count;
wolfSSL 0:d92f9d21154c 2322
wolfSSL 0:d92f9d21154c 2323 if (!init) {
wolfSSL 0:d92f9d21154c 2324 QueryPerformanceFrequency(&freq);
wolfSSL 0:d92f9d21154c 2325 init = 1;
wolfSSL 0:d92f9d21154c 2326 }
wolfSSL 0:d92f9d21154c 2327
wolfSSL 0:d92f9d21154c 2328 QueryPerformanceCounter(&count);
wolfSSL 0:d92f9d21154c 2329
wolfSSL 0:d92f9d21154c 2330 return (word32)(count.QuadPart / freq.QuadPart);
wolfSSL 0:d92f9d21154c 2331 }
wolfSSL 0:d92f9d21154c 2332
wolfSSL 0:d92f9d21154c 2333 #elif defined(HAVE_RTP_SYS)
wolfSSL 0:d92f9d21154c 2334
wolfSSL 0:d92f9d21154c 2335 #include "rtptime.h"
wolfSSL 0:d92f9d21154c 2336
wolfSSL 0:d92f9d21154c 2337 word32 LowResTimer(void)
wolfSSL 0:d92f9d21154c 2338 {
wolfSSL 0:d92f9d21154c 2339 return (word32)rtp_get_system_sec();
wolfSSL 0:d92f9d21154c 2340 }
wolfSSL 0:d92f9d21154c 2341
wolfSSL 0:d92f9d21154c 2342
wolfSSL 0:d92f9d21154c 2343 #elif defined(MICRIUM)
wolfSSL 0:d92f9d21154c 2344
wolfSSL 0:d92f9d21154c 2345 word32 LowResTimer(void)
wolfSSL 0:d92f9d21154c 2346 {
wolfSSL 0:d92f9d21154c 2347 NET_SECURE_OS_TICK clk;
wolfSSL 0:d92f9d21154c 2348
wolfSSL 0:d92f9d21154c 2349 #if (NET_SECURE_MGR_CFG_EN == DEF_ENABLED)
wolfSSL 0:d92f9d21154c 2350 clk = NetSecure_OS_TimeGet();
wolfSSL 0:d92f9d21154c 2351 #endif
wolfSSL 0:d92f9d21154c 2352 return (word32)clk;
wolfSSL 0:d92f9d21154c 2353 }
wolfSSL 0:d92f9d21154c 2354
wolfSSL 0:d92f9d21154c 2355
wolfSSL 0:d92f9d21154c 2356 #elif defined(MICROCHIP_TCPIP_V5)
wolfSSL 0:d92f9d21154c 2357
wolfSSL 0:d92f9d21154c 2358 word32 LowResTimer(void)
wolfSSL 0:d92f9d21154c 2359 {
wolfSSL 0:d92f9d21154c 2360 return (word32) TickGet();
wolfSSL 0:d92f9d21154c 2361 }
wolfSSL 0:d92f9d21154c 2362
wolfSSL 0:d92f9d21154c 2363
wolfSSL 0:d92f9d21154c 2364 #elif defined(MICROCHIP_TCPIP)
wolfSSL 0:d92f9d21154c 2365
wolfSSL 0:d92f9d21154c 2366 #if defined(MICROCHIP_MPLAB_HARMONY)
wolfSSL 0:d92f9d21154c 2367
wolfSSL 0:d92f9d21154c 2368 #include <system/tmr/sys_tmr.h>
wolfSSL 0:d92f9d21154c 2369
wolfSSL 0:d92f9d21154c 2370 word32 LowResTimer(void)
wolfSSL 0:d92f9d21154c 2371 {
wolfSSL 0:d92f9d21154c 2372 return (word32) SYS_TMR_TickCountGet();
wolfSSL 0:d92f9d21154c 2373 }
wolfSSL 0:d92f9d21154c 2374
wolfSSL 0:d92f9d21154c 2375 #else
wolfSSL 0:d92f9d21154c 2376
wolfSSL 0:d92f9d21154c 2377 word32 LowResTimer(void)
wolfSSL 0:d92f9d21154c 2378 {
wolfSSL 0:d92f9d21154c 2379 return (word32) SYS_TICK_Get();
wolfSSL 0:d92f9d21154c 2380 }
wolfSSL 0:d92f9d21154c 2381
wolfSSL 0:d92f9d21154c 2382 #endif
wolfSSL 0:d92f9d21154c 2383
wolfSSL 0:d92f9d21154c 2384 #elif defined(FREESCALE_MQX)
wolfSSL 0:d92f9d21154c 2385
wolfSSL 0:d92f9d21154c 2386 word32 LowResTimer(void)
wolfSSL 0:d92f9d21154c 2387 {
wolfSSL 0:d92f9d21154c 2388 TIME_STRUCT mqxTime;
wolfSSL 0:d92f9d21154c 2389
wolfSSL 0:d92f9d21154c 2390 _time_get_elapsed(&mqxTime);
wolfSSL 0:d92f9d21154c 2391
wolfSSL 0:d92f9d21154c 2392 return (word32) mqxTime.SECONDS;
wolfSSL 0:d92f9d21154c 2393 }
wolfSSL 0:d92f9d21154c 2394
wolfSSL 0:d92f9d21154c 2395 #elif defined(WOLFSSL_TIRTOS)
wolfSSL 0:d92f9d21154c 2396
wolfSSL 0:d92f9d21154c 2397 word32 LowResTimer(void)
wolfSSL 0:d92f9d21154c 2398 {
wolfSSL 0:d92f9d21154c 2399 return (word32) Seconds_get();
wolfSSL 0:d92f9d21154c 2400 }
wolfSSL 0:d92f9d21154c 2401
wolfSSL 0:d92f9d21154c 2402 #elif defined(USER_TICKS)
wolfSSL 0:d92f9d21154c 2403 #if 0
wolfSSL 0:d92f9d21154c 2404 word32 LowResTimer(void)
wolfSSL 0:d92f9d21154c 2405 {
wolfSSL 0:d92f9d21154c 2406 /*
wolfSSL 0:d92f9d21154c 2407 write your own clock tick function if don't want time(0)
wolfSSL 0:d92f9d21154c 2408 needs second accuracy but doesn't have to correlated to EPOCH
wolfSSL 0:d92f9d21154c 2409 */
wolfSSL 0:d92f9d21154c 2410 }
wolfSSL 0:d92f9d21154c 2411 #endif
wolfSSL 0:d92f9d21154c 2412
wolfSSL 0:d92f9d21154c 2413 #elif defined(TIME_OVERRIDES)
wolfSSL 0:d92f9d21154c 2414
wolfSSL 0:d92f9d21154c 2415 /* use same asn time overrides unless user wants tick override above */
wolfSSL 0:d92f9d21154c 2416
wolfSSL 0:d92f9d21154c 2417 #ifndef HAVE_TIME_T_TYPE
wolfSSL 0:d92f9d21154c 2418 typedef long time_t;
wolfSSL 0:d92f9d21154c 2419 #endif
wolfSSL 0:d92f9d21154c 2420 extern time_t XTIME(time_t * timer);
wolfSSL 0:d92f9d21154c 2421
wolfSSL 0:d92f9d21154c 2422 word32 LowResTimer(void)
wolfSSL 0:d92f9d21154c 2423 {
wolfSSL 0:d92f9d21154c 2424 return (word32) XTIME(0);
wolfSSL 0:d92f9d21154c 2425 }
wolfSSL 0:d92f9d21154c 2426
wolfSSL 0:d92f9d21154c 2427 #else /* !USE_WINDOWS_API && !HAVE_RTP_SYS && !MICRIUM && !USER_TICKS */
wolfSSL 0:d92f9d21154c 2428
wolfSSL 0:d92f9d21154c 2429 #include <time.h>
wolfSSL 0:d92f9d21154c 2430
wolfSSL 0:d92f9d21154c 2431 word32 LowResTimer(void)
wolfSSL 0:d92f9d21154c 2432 {
wolfSSL 0:d92f9d21154c 2433 return (word32)time(0);
wolfSSL 0:d92f9d21154c 2434 }
wolfSSL 0:d92f9d21154c 2435
wolfSSL 0:d92f9d21154c 2436
wolfSSL 0:d92f9d21154c 2437 #endif /* USE_WINDOWS_API */
wolfSSL 0:d92f9d21154c 2438
wolfSSL 0:d92f9d21154c 2439
wolfSSL 0:d92f9d21154c 2440 /* add output to md5 and sha handshake hashes, exclude record header */
wolfSSL 0:d92f9d21154c 2441 static int HashOutput(WOLFSSL* ssl, const byte* output, int sz, int ivSz)
wolfSSL 0:d92f9d21154c 2442 {
wolfSSL 0:d92f9d21154c 2443 const byte* adj = output + RECORD_HEADER_SZ + ivSz;
wolfSSL 0:d92f9d21154c 2444 sz -= RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 2445
wolfSSL 0:d92f9d21154c 2446 #ifdef HAVE_FUZZER
wolfSSL 0:d92f9d21154c 2447 if (ssl->fuzzerCb)
wolfSSL 0:d92f9d21154c 2448 ssl->fuzzerCb(ssl, output, sz, FUZZ_HASH, ssl->fuzzerCtx);
wolfSSL 0:d92f9d21154c 2449 #endif
wolfSSL 0:d92f9d21154c 2450 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 2451 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 2452 adj += DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 2453 sz -= DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 2454 }
wolfSSL 0:d92f9d21154c 2455 #endif
wolfSSL 0:d92f9d21154c 2456 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 2457 #ifndef NO_SHA
wolfSSL 0:d92f9d21154c 2458 wc_ShaUpdate(&ssl->hsHashes->hashSha, adj, sz);
wolfSSL 0:d92f9d21154c 2459 #endif
wolfSSL 0:d92f9d21154c 2460 #ifndef NO_MD5
wolfSSL 0:d92f9d21154c 2461 wc_Md5Update(&ssl->hsHashes->hashMd5, adj, sz);
wolfSSL 0:d92f9d21154c 2462 #endif
wolfSSL 0:d92f9d21154c 2463 #endif
wolfSSL 0:d92f9d21154c 2464
wolfSSL 0:d92f9d21154c 2465 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 2466 int ret;
wolfSSL 0:d92f9d21154c 2467
wolfSSL 0:d92f9d21154c 2468 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 2469 ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, adj, sz);
wolfSSL 0:d92f9d21154c 2470 if (ret != 0)
wolfSSL 0:d92f9d21154c 2471 return ret;
wolfSSL 0:d92f9d21154c 2472 #endif
wolfSSL 0:d92f9d21154c 2473 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 2474 ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, adj, sz);
wolfSSL 0:d92f9d21154c 2475 if (ret != 0)
wolfSSL 0:d92f9d21154c 2476 return ret;
wolfSSL 0:d92f9d21154c 2477 #endif
wolfSSL 0:d92f9d21154c 2478 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 2479 ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, adj, sz);
wolfSSL 0:d92f9d21154c 2480 if (ret != 0)
wolfSSL 0:d92f9d21154c 2481 return ret;
wolfSSL 0:d92f9d21154c 2482 #endif
wolfSSL 0:d92f9d21154c 2483 }
wolfSSL 0:d92f9d21154c 2484
wolfSSL 0:d92f9d21154c 2485 return 0;
wolfSSL 0:d92f9d21154c 2486 }
wolfSSL 0:d92f9d21154c 2487
wolfSSL 0:d92f9d21154c 2488
wolfSSL 0:d92f9d21154c 2489 /* add input to md5 and sha handshake hashes, include handshake header */
wolfSSL 0:d92f9d21154c 2490 static int HashInput(WOLFSSL* ssl, const byte* input, int sz)
wolfSSL 0:d92f9d21154c 2491 {
wolfSSL 0:d92f9d21154c 2492 const byte* adj = input - HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 2493 sz += HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 2494
wolfSSL 0:d92f9d21154c 2495 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 2496 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 2497 adj -= DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 2498 sz += DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 2499 }
wolfSSL 0:d92f9d21154c 2500 #endif
wolfSSL 0:d92f9d21154c 2501
wolfSSL 0:d92f9d21154c 2502 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 2503 #ifndef NO_SHA
wolfSSL 0:d92f9d21154c 2504 wc_ShaUpdate(&ssl->hsHashes->hashSha, adj, sz);
wolfSSL 0:d92f9d21154c 2505 #endif
wolfSSL 0:d92f9d21154c 2506 #ifndef NO_MD5
wolfSSL 0:d92f9d21154c 2507 wc_Md5Update(&ssl->hsHashes->hashMd5, adj, sz);
wolfSSL 0:d92f9d21154c 2508 #endif
wolfSSL 0:d92f9d21154c 2509 #endif
wolfSSL 0:d92f9d21154c 2510
wolfSSL 0:d92f9d21154c 2511 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 2512 int ret;
wolfSSL 0:d92f9d21154c 2513
wolfSSL 0:d92f9d21154c 2514 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 2515 ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, adj, sz);
wolfSSL 0:d92f9d21154c 2516 if (ret != 0)
wolfSSL 0:d92f9d21154c 2517 return ret;
wolfSSL 0:d92f9d21154c 2518 #endif
wolfSSL 0:d92f9d21154c 2519 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 2520 ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, adj, sz);
wolfSSL 0:d92f9d21154c 2521 if (ret != 0)
wolfSSL 0:d92f9d21154c 2522 return ret;
wolfSSL 0:d92f9d21154c 2523 #endif
wolfSSL 0:d92f9d21154c 2524 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 2525 ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, adj, sz);
wolfSSL 0:d92f9d21154c 2526 if (ret != 0)
wolfSSL 0:d92f9d21154c 2527 return ret;
wolfSSL 0:d92f9d21154c 2528 #endif
wolfSSL 0:d92f9d21154c 2529 }
wolfSSL 0:d92f9d21154c 2530
wolfSSL 0:d92f9d21154c 2531 return 0;
wolfSSL 0:d92f9d21154c 2532 }
wolfSSL 0:d92f9d21154c 2533
wolfSSL 0:d92f9d21154c 2534
wolfSSL 0:d92f9d21154c 2535 /* add record layer header for message */
wolfSSL 0:d92f9d21154c 2536 static void AddRecordHeader(byte* output, word32 length, byte type, WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 2537 {
wolfSSL 0:d92f9d21154c 2538 RecordLayerHeader* rl;
wolfSSL 0:d92f9d21154c 2539
wolfSSL 0:d92f9d21154c 2540 /* record layer header */
wolfSSL 0:d92f9d21154c 2541 rl = (RecordLayerHeader*)output;
wolfSSL 0:d92f9d21154c 2542 rl->type = type;
wolfSSL 0:d92f9d21154c 2543 rl->pvMajor = ssl->version.major; /* type and version same in each */
wolfSSL 0:d92f9d21154c 2544 rl->pvMinor = ssl->version.minor;
wolfSSL 0:d92f9d21154c 2545
wolfSSL 0:d92f9d21154c 2546 if (!ssl->options.dtls)
wolfSSL 0:d92f9d21154c 2547 c16toa((word16)length, rl->length);
wolfSSL 0:d92f9d21154c 2548 else {
wolfSSL 0:d92f9d21154c 2549 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 2550 DtlsRecordLayerHeader* dtls;
wolfSSL 0:d92f9d21154c 2551
wolfSSL 0:d92f9d21154c 2552 /* dtls record layer header extensions */
wolfSSL 0:d92f9d21154c 2553 dtls = (DtlsRecordLayerHeader*)output;
wolfSSL 0:d92f9d21154c 2554 c16toa(ssl->keys.dtls_epoch, dtls->epoch);
wolfSSL 0:d92f9d21154c 2555 c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
wolfSSL 0:d92f9d21154c 2556 c16toa((word16)length, dtls->length);
wolfSSL 0:d92f9d21154c 2557 #endif
wolfSSL 0:d92f9d21154c 2558 }
wolfSSL 0:d92f9d21154c 2559 }
wolfSSL 0:d92f9d21154c 2560
wolfSSL 0:d92f9d21154c 2561
wolfSSL 0:d92f9d21154c 2562 /* add handshake header for message */
wolfSSL 0:d92f9d21154c 2563 static void AddHandShakeHeader(byte* output, word32 length, byte type,
wolfSSL 0:d92f9d21154c 2564 WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 2565 {
wolfSSL 0:d92f9d21154c 2566 HandShakeHeader* hs;
wolfSSL 0:d92f9d21154c 2567 (void)ssl;
wolfSSL 0:d92f9d21154c 2568
wolfSSL 0:d92f9d21154c 2569 /* handshake header */
wolfSSL 0:d92f9d21154c 2570 hs = (HandShakeHeader*)output;
wolfSSL 0:d92f9d21154c 2571 hs->type = type;
wolfSSL 0:d92f9d21154c 2572 c32to24(length, hs->length); /* type and length same for each */
wolfSSL 0:d92f9d21154c 2573 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 2574 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 2575 DtlsHandShakeHeader* dtls;
wolfSSL 0:d92f9d21154c 2576
wolfSSL 0:d92f9d21154c 2577 /* dtls handshake header extensions */
wolfSSL 0:d92f9d21154c 2578 dtls = (DtlsHandShakeHeader*)output;
wolfSSL 0:d92f9d21154c 2579 c16toa(ssl->keys.dtls_handshake_number++, dtls->message_seq);
wolfSSL 0:d92f9d21154c 2580 c32to24(0, dtls->fragment_offset);
wolfSSL 0:d92f9d21154c 2581 c32to24(length, dtls->fragment_length);
wolfSSL 0:d92f9d21154c 2582 }
wolfSSL 0:d92f9d21154c 2583 #endif
wolfSSL 0:d92f9d21154c 2584 }
wolfSSL 0:d92f9d21154c 2585
wolfSSL 0:d92f9d21154c 2586
wolfSSL 0:d92f9d21154c 2587 /* add both headers for handshake message */
wolfSSL 0:d92f9d21154c 2588 static void AddHeaders(byte* output, word32 length, byte type, WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 2589 {
wolfSSL 0:d92f9d21154c 2590 if (!ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 2591 AddRecordHeader(output, length + HANDSHAKE_HEADER_SZ, handshake, ssl);
wolfSSL 0:d92f9d21154c 2592 AddHandShakeHeader(output + RECORD_HEADER_SZ, length, type, ssl);
wolfSSL 0:d92f9d21154c 2593 }
wolfSSL 0:d92f9d21154c 2594 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 2595 else {
wolfSSL 0:d92f9d21154c 2596 AddRecordHeader(output, length+DTLS_HANDSHAKE_HEADER_SZ, handshake,ssl);
wolfSSL 0:d92f9d21154c 2597 AddHandShakeHeader(output + DTLS_RECORD_HEADER_SZ, length, type, ssl);
wolfSSL 0:d92f9d21154c 2598 }
wolfSSL 0:d92f9d21154c 2599 #endif
wolfSSL 0:d92f9d21154c 2600 }
wolfSSL 0:d92f9d21154c 2601
wolfSSL 0:d92f9d21154c 2602
wolfSSL 0:d92f9d21154c 2603 /* return bytes received, -1 on error */
wolfSSL 0:d92f9d21154c 2604 static int Receive(WOLFSSL* ssl, byte* buf, word32 sz)
wolfSSL 0:d92f9d21154c 2605 {
wolfSSL 0:d92f9d21154c 2606 int recvd;
wolfSSL 0:d92f9d21154c 2607
wolfSSL 0:d92f9d21154c 2608 if (ssl->ctx->CBIORecv == NULL) {
wolfSSL 0:d92f9d21154c 2609 WOLFSSL_MSG("Your IO Recv callback is null, please set");
wolfSSL 0:d92f9d21154c 2610 return -1;
wolfSSL 0:d92f9d21154c 2611 }
wolfSSL 0:d92f9d21154c 2612
wolfSSL 0:d92f9d21154c 2613 retry:
wolfSSL 0:d92f9d21154c 2614 recvd = ssl->ctx->CBIORecv(ssl, (char *)buf, (int)sz, ssl->IOCB_ReadCtx);
wolfSSL 0:d92f9d21154c 2615 if (recvd < 0)
wolfSSL 0:d92f9d21154c 2616 switch (recvd) {
wolfSSL 0:d92f9d21154c 2617 case WOLFSSL_CBIO_ERR_GENERAL: /* general/unknown error */
wolfSSL 0:d92f9d21154c 2618 return -1;
wolfSSL 0:d92f9d21154c 2619
wolfSSL 0:d92f9d21154c 2620 case WOLFSSL_CBIO_ERR_WANT_READ: /* want read, would block */
wolfSSL 0:d92f9d21154c 2621 return WANT_READ;
wolfSSL 0:d92f9d21154c 2622
wolfSSL 0:d92f9d21154c 2623 case WOLFSSL_CBIO_ERR_CONN_RST: /* connection reset */
wolfSSL 0:d92f9d21154c 2624 #ifdef USE_WINDOWS_API
wolfSSL 0:d92f9d21154c 2625 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 2626 goto retry;
wolfSSL 0:d92f9d21154c 2627 }
wolfSSL 0:d92f9d21154c 2628 #endif
wolfSSL 0:d92f9d21154c 2629 ssl->options.connReset = 1;
wolfSSL 0:d92f9d21154c 2630 return -1;
wolfSSL 0:d92f9d21154c 2631
wolfSSL 0:d92f9d21154c 2632 case WOLFSSL_CBIO_ERR_ISR: /* interrupt */
wolfSSL 0:d92f9d21154c 2633 /* see if we got our timeout */
wolfSSL 0:d92f9d21154c 2634 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 2635 if (ssl->toInfoOn) {
wolfSSL 0:d92f9d21154c 2636 struct itimerval timeout;
wolfSSL 0:d92f9d21154c 2637 getitimer(ITIMER_REAL, &timeout);
wolfSSL 0:d92f9d21154c 2638 if (timeout.it_value.tv_sec == 0 &&
wolfSSL 0:d92f9d21154c 2639 timeout.it_value.tv_usec == 0) {
wolfSSL 0:d92f9d21154c 2640 XSTRNCPY(ssl->timeoutInfo.timeoutName,
wolfSSL 0:d92f9d21154c 2641 "recv() timeout", MAX_TIMEOUT_NAME_SZ);
wolfSSL 0:d92f9d21154c 2642 WOLFSSL_MSG("Got our timeout");
wolfSSL 0:d92f9d21154c 2643 return WANT_READ;
wolfSSL 0:d92f9d21154c 2644 }
wolfSSL 0:d92f9d21154c 2645 }
wolfSSL 0:d92f9d21154c 2646 #endif
wolfSSL 0:d92f9d21154c 2647 goto retry;
wolfSSL 0:d92f9d21154c 2648
wolfSSL 0:d92f9d21154c 2649 case WOLFSSL_CBIO_ERR_CONN_CLOSE: /* peer closed connection */
wolfSSL 0:d92f9d21154c 2650 ssl->options.isClosed = 1;
wolfSSL 0:d92f9d21154c 2651 return -1;
wolfSSL 0:d92f9d21154c 2652
wolfSSL 0:d92f9d21154c 2653 case WOLFSSL_CBIO_ERR_TIMEOUT:
wolfSSL 0:d92f9d21154c 2654 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 2655 if (DtlsPoolTimeout(ssl) == 0 && DtlsPoolSend(ssl) == 0)
wolfSSL 0:d92f9d21154c 2656 goto retry;
wolfSSL 0:d92f9d21154c 2657 else
wolfSSL 0:d92f9d21154c 2658 #endif
wolfSSL 0:d92f9d21154c 2659 return -1;
wolfSSL 0:d92f9d21154c 2660
wolfSSL 0:d92f9d21154c 2661 default:
wolfSSL 0:d92f9d21154c 2662 return recvd;
wolfSSL 0:d92f9d21154c 2663 }
wolfSSL 0:d92f9d21154c 2664
wolfSSL 0:d92f9d21154c 2665 return recvd;
wolfSSL 0:d92f9d21154c 2666 }
wolfSSL 0:d92f9d21154c 2667
wolfSSL 0:d92f9d21154c 2668
wolfSSL 0:d92f9d21154c 2669 /* Switch dynamic output buffer back to static, buffer is assumed clear */
wolfSSL 0:d92f9d21154c 2670 void ShrinkOutputBuffer(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 2671 {
wolfSSL 0:d92f9d21154c 2672 WOLFSSL_MSG("Shrinking output buffer\n");
wolfSSL 0:d92f9d21154c 2673 XFREE(ssl->buffers.outputBuffer.buffer - ssl->buffers.outputBuffer.offset,
wolfSSL 0:d92f9d21154c 2674 ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
wolfSSL 0:d92f9d21154c 2675 ssl->buffers.outputBuffer.buffer = ssl->buffers.outputBuffer.staticBuffer;
wolfSSL 0:d92f9d21154c 2676 ssl->buffers.outputBuffer.bufferSize = STATIC_BUFFER_LEN;
wolfSSL 0:d92f9d21154c 2677 ssl->buffers.outputBuffer.dynamicFlag = 0;
wolfSSL 0:d92f9d21154c 2678 ssl->buffers.outputBuffer.offset = 0;
wolfSSL 0:d92f9d21154c 2679 }
wolfSSL 0:d92f9d21154c 2680
wolfSSL 0:d92f9d21154c 2681
wolfSSL 0:d92f9d21154c 2682 /* Switch dynamic input buffer back to static, keep any remaining input */
wolfSSL 0:d92f9d21154c 2683 /* forced free means cleaning up */
wolfSSL 0:d92f9d21154c 2684 void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree)
wolfSSL 0:d92f9d21154c 2685 {
wolfSSL 0:d92f9d21154c 2686 int usedLength = ssl->buffers.inputBuffer.length -
wolfSSL 0:d92f9d21154c 2687 ssl->buffers.inputBuffer.idx;
wolfSSL 0:d92f9d21154c 2688 if (!forcedFree && usedLength > STATIC_BUFFER_LEN)
wolfSSL 0:d92f9d21154c 2689 return;
wolfSSL 0:d92f9d21154c 2690
wolfSSL 0:d92f9d21154c 2691 WOLFSSL_MSG("Shrinking input buffer\n");
wolfSSL 0:d92f9d21154c 2692
wolfSSL 0:d92f9d21154c 2693 if (!forcedFree && usedLength)
wolfSSL 0:d92f9d21154c 2694 XMEMCPY(ssl->buffers.inputBuffer.staticBuffer,
wolfSSL 0:d92f9d21154c 2695 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
wolfSSL 0:d92f9d21154c 2696 usedLength);
wolfSSL 0:d92f9d21154c 2697
wolfSSL 0:d92f9d21154c 2698 XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
wolfSSL 0:d92f9d21154c 2699 ssl->heap, DYNAMIC_TYPE_IN_BUFFER);
wolfSSL 0:d92f9d21154c 2700 ssl->buffers.inputBuffer.buffer = ssl->buffers.inputBuffer.staticBuffer;
wolfSSL 0:d92f9d21154c 2701 ssl->buffers.inputBuffer.bufferSize = STATIC_BUFFER_LEN;
wolfSSL 0:d92f9d21154c 2702 ssl->buffers.inputBuffer.dynamicFlag = 0;
wolfSSL 0:d92f9d21154c 2703 ssl->buffers.inputBuffer.offset = 0;
wolfSSL 0:d92f9d21154c 2704 ssl->buffers.inputBuffer.idx = 0;
wolfSSL 0:d92f9d21154c 2705 ssl->buffers.inputBuffer.length = usedLength;
wolfSSL 0:d92f9d21154c 2706 }
wolfSSL 0:d92f9d21154c 2707
wolfSSL 0:d92f9d21154c 2708 int SendBuffered(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 2709 {
wolfSSL 0:d92f9d21154c 2710 if (ssl->ctx->CBIOSend == NULL) {
wolfSSL 0:d92f9d21154c 2711 WOLFSSL_MSG("Your IO Send callback is null, please set");
wolfSSL 0:d92f9d21154c 2712 return SOCKET_ERROR_E;
wolfSSL 0:d92f9d21154c 2713 }
wolfSSL 0:d92f9d21154c 2714
wolfSSL 0:d92f9d21154c 2715 while (ssl->buffers.outputBuffer.length > 0) {
wolfSSL 0:d92f9d21154c 2716 int sent = ssl->ctx->CBIOSend(ssl,
wolfSSL 0:d92f9d21154c 2717 (char*)ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 2718 ssl->buffers.outputBuffer.idx,
wolfSSL 0:d92f9d21154c 2719 (int)ssl->buffers.outputBuffer.length,
wolfSSL 0:d92f9d21154c 2720 ssl->IOCB_WriteCtx);
wolfSSL 0:d92f9d21154c 2721 if (sent < 0) {
wolfSSL 0:d92f9d21154c 2722 switch (sent) {
wolfSSL 0:d92f9d21154c 2723
wolfSSL 0:d92f9d21154c 2724 case WOLFSSL_CBIO_ERR_WANT_WRITE: /* would block */
wolfSSL 0:d92f9d21154c 2725 return WANT_WRITE;
wolfSSL 0:d92f9d21154c 2726
wolfSSL 0:d92f9d21154c 2727 case WOLFSSL_CBIO_ERR_CONN_RST: /* connection reset */
wolfSSL 0:d92f9d21154c 2728 ssl->options.connReset = 1;
wolfSSL 0:d92f9d21154c 2729 break;
wolfSSL 0:d92f9d21154c 2730
wolfSSL 0:d92f9d21154c 2731 case WOLFSSL_CBIO_ERR_ISR: /* interrupt */
wolfSSL 0:d92f9d21154c 2732 /* see if we got our timeout */
wolfSSL 0:d92f9d21154c 2733 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 2734 if (ssl->toInfoOn) {
wolfSSL 0:d92f9d21154c 2735 struct itimerval timeout;
wolfSSL 0:d92f9d21154c 2736 getitimer(ITIMER_REAL, &timeout);
wolfSSL 0:d92f9d21154c 2737 if (timeout.it_value.tv_sec == 0 &&
wolfSSL 0:d92f9d21154c 2738 timeout.it_value.tv_usec == 0) {
wolfSSL 0:d92f9d21154c 2739 XSTRNCPY(ssl->timeoutInfo.timeoutName,
wolfSSL 0:d92f9d21154c 2740 "send() timeout", MAX_TIMEOUT_NAME_SZ);
wolfSSL 0:d92f9d21154c 2741 WOLFSSL_MSG("Got our timeout");
wolfSSL 0:d92f9d21154c 2742 return WANT_WRITE;
wolfSSL 0:d92f9d21154c 2743 }
wolfSSL 0:d92f9d21154c 2744 }
wolfSSL 0:d92f9d21154c 2745 #endif
wolfSSL 0:d92f9d21154c 2746 continue;
wolfSSL 0:d92f9d21154c 2747
wolfSSL 0:d92f9d21154c 2748 case WOLFSSL_CBIO_ERR_CONN_CLOSE: /* epipe / conn closed */
wolfSSL 0:d92f9d21154c 2749 ssl->options.connReset = 1; /* treat same as reset */
wolfSSL 0:d92f9d21154c 2750 break;
wolfSSL 0:d92f9d21154c 2751
wolfSSL 0:d92f9d21154c 2752 default:
wolfSSL 0:d92f9d21154c 2753 return SOCKET_ERROR_E;
wolfSSL 0:d92f9d21154c 2754 }
wolfSSL 0:d92f9d21154c 2755
wolfSSL 0:d92f9d21154c 2756 return SOCKET_ERROR_E;
wolfSSL 0:d92f9d21154c 2757 }
wolfSSL 0:d92f9d21154c 2758
wolfSSL 0:d92f9d21154c 2759 if (sent > (int)ssl->buffers.outputBuffer.length) {
wolfSSL 0:d92f9d21154c 2760 WOLFSSL_MSG("SendBuffered() out of bounds read");
wolfSSL 0:d92f9d21154c 2761 return SEND_OOB_READ_E;
wolfSSL 0:d92f9d21154c 2762 }
wolfSSL 0:d92f9d21154c 2763
wolfSSL 0:d92f9d21154c 2764 ssl->buffers.outputBuffer.idx += sent;
wolfSSL 0:d92f9d21154c 2765 ssl->buffers.outputBuffer.length -= sent;
wolfSSL 0:d92f9d21154c 2766 }
wolfSSL 0:d92f9d21154c 2767
wolfSSL 0:d92f9d21154c 2768 ssl->buffers.outputBuffer.idx = 0;
wolfSSL 0:d92f9d21154c 2769
wolfSSL 0:d92f9d21154c 2770 if (ssl->buffers.outputBuffer.dynamicFlag)
wolfSSL 0:d92f9d21154c 2771 ShrinkOutputBuffer(ssl);
wolfSSL 0:d92f9d21154c 2772
wolfSSL 0:d92f9d21154c 2773 return 0;
wolfSSL 0:d92f9d21154c 2774 }
wolfSSL 0:d92f9d21154c 2775
wolfSSL 0:d92f9d21154c 2776
wolfSSL 0:d92f9d21154c 2777 /* Grow the output buffer */
wolfSSL 0:d92f9d21154c 2778 static INLINE int GrowOutputBuffer(WOLFSSL* ssl, int size)
wolfSSL 0:d92f9d21154c 2779 {
wolfSSL 0:d92f9d21154c 2780 byte* tmp;
wolfSSL 0:d92f9d21154c 2781 byte hdrSz = ssl->options.dtls ? DTLS_RECORD_HEADER_SZ :
wolfSSL 0:d92f9d21154c 2782 RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 2783 byte align = WOLFSSL_GENERAL_ALIGNMENT;
wolfSSL 0:d92f9d21154c 2784 /* the encrypted data will be offset from the front of the buffer by
wolfSSL 0:d92f9d21154c 2785 the header, if the user wants encrypted alignment they need
wolfSSL 0:d92f9d21154c 2786 to define their alignment requirement */
wolfSSL 0:d92f9d21154c 2787
wolfSSL 0:d92f9d21154c 2788 if (align) {
wolfSSL 0:d92f9d21154c 2789 while (align < hdrSz)
wolfSSL 0:d92f9d21154c 2790 align *= 2;
wolfSSL 0:d92f9d21154c 2791 }
wolfSSL 0:d92f9d21154c 2792
wolfSSL 0:d92f9d21154c 2793 tmp = (byte*) XMALLOC(size + ssl->buffers.outputBuffer.length + align,
wolfSSL 0:d92f9d21154c 2794 ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
wolfSSL 0:d92f9d21154c 2795 WOLFSSL_MSG("growing output buffer\n");
wolfSSL 0:d92f9d21154c 2796
wolfSSL 0:d92f9d21154c 2797 if (!tmp) return MEMORY_E;
wolfSSL 0:d92f9d21154c 2798 if (align)
wolfSSL 0:d92f9d21154c 2799 tmp += align - hdrSz;
wolfSSL 0:d92f9d21154c 2800
wolfSSL 0:d92f9d21154c 2801 if (ssl->buffers.outputBuffer.length)
wolfSSL 0:d92f9d21154c 2802 XMEMCPY(tmp, ssl->buffers.outputBuffer.buffer,
wolfSSL 0:d92f9d21154c 2803 ssl->buffers.outputBuffer.length);
wolfSSL 0:d92f9d21154c 2804
wolfSSL 0:d92f9d21154c 2805 if (ssl->buffers.outputBuffer.dynamicFlag)
wolfSSL 0:d92f9d21154c 2806 XFREE(ssl->buffers.outputBuffer.buffer -
wolfSSL 0:d92f9d21154c 2807 ssl->buffers.outputBuffer.offset, ssl->heap,
wolfSSL 0:d92f9d21154c 2808 DYNAMIC_TYPE_OUT_BUFFER);
wolfSSL 0:d92f9d21154c 2809 ssl->buffers.outputBuffer.dynamicFlag = 1;
wolfSSL 0:d92f9d21154c 2810 if (align)
wolfSSL 0:d92f9d21154c 2811 ssl->buffers.outputBuffer.offset = align - hdrSz;
wolfSSL 0:d92f9d21154c 2812 else
wolfSSL 0:d92f9d21154c 2813 ssl->buffers.outputBuffer.offset = 0;
wolfSSL 0:d92f9d21154c 2814 ssl->buffers.outputBuffer.buffer = tmp;
wolfSSL 0:d92f9d21154c 2815 ssl->buffers.outputBuffer.bufferSize = size +
wolfSSL 0:d92f9d21154c 2816 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 2817 return 0;
wolfSSL 0:d92f9d21154c 2818 }
wolfSSL 0:d92f9d21154c 2819
wolfSSL 0:d92f9d21154c 2820
wolfSSL 0:d92f9d21154c 2821 /* Grow the input buffer, should only be to read cert or big app data */
wolfSSL 0:d92f9d21154c 2822 int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength)
wolfSSL 0:d92f9d21154c 2823 {
wolfSSL 0:d92f9d21154c 2824 byte* tmp;
wolfSSL 0:d92f9d21154c 2825 byte hdrSz = DTLS_RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 2826 byte align = ssl->options.dtls ? WOLFSSL_GENERAL_ALIGNMENT : 0;
wolfSSL 0:d92f9d21154c 2827 /* the encrypted data will be offset from the front of the buffer by
wolfSSL 0:d92f9d21154c 2828 the dtls record header, if the user wants encrypted alignment they need
wolfSSL 0:d92f9d21154c 2829 to define their alignment requirement. in tls we read record header
wolfSSL 0:d92f9d21154c 2830 to get size of record and put actual data back at front, so don't need */
wolfSSL 0:d92f9d21154c 2831
wolfSSL 0:d92f9d21154c 2832 if (align) {
wolfSSL 0:d92f9d21154c 2833 while (align < hdrSz)
wolfSSL 0:d92f9d21154c 2834 align *= 2;
wolfSSL 0:d92f9d21154c 2835 }
wolfSSL 0:d92f9d21154c 2836 tmp = (byte*) XMALLOC(size + usedLength + align, ssl->heap,
wolfSSL 0:d92f9d21154c 2837 DYNAMIC_TYPE_IN_BUFFER);
wolfSSL 0:d92f9d21154c 2838 WOLFSSL_MSG("growing input buffer\n");
wolfSSL 0:d92f9d21154c 2839
wolfSSL 0:d92f9d21154c 2840 if (!tmp) return MEMORY_E;
wolfSSL 0:d92f9d21154c 2841 if (align)
wolfSSL 0:d92f9d21154c 2842 tmp += align - hdrSz;
wolfSSL 0:d92f9d21154c 2843
wolfSSL 0:d92f9d21154c 2844 if (usedLength)
wolfSSL 0:d92f9d21154c 2845 XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer +
wolfSSL 0:d92f9d21154c 2846 ssl->buffers.inputBuffer.idx, usedLength);
wolfSSL 0:d92f9d21154c 2847
wolfSSL 0:d92f9d21154c 2848 if (ssl->buffers.inputBuffer.dynamicFlag)
wolfSSL 0:d92f9d21154c 2849 XFREE(ssl->buffers.inputBuffer.buffer - ssl->buffers.inputBuffer.offset,
wolfSSL 0:d92f9d21154c 2850 ssl->heap,DYNAMIC_TYPE_IN_BUFFER);
wolfSSL 0:d92f9d21154c 2851
wolfSSL 0:d92f9d21154c 2852 ssl->buffers.inputBuffer.dynamicFlag = 1;
wolfSSL 0:d92f9d21154c 2853 if (align)
wolfSSL 0:d92f9d21154c 2854 ssl->buffers.inputBuffer.offset = align - hdrSz;
wolfSSL 0:d92f9d21154c 2855 else
wolfSSL 0:d92f9d21154c 2856 ssl->buffers.inputBuffer.offset = 0;
wolfSSL 0:d92f9d21154c 2857 ssl->buffers.inputBuffer.buffer = tmp;
wolfSSL 0:d92f9d21154c 2858 ssl->buffers.inputBuffer.bufferSize = size + usedLength;
wolfSSL 0:d92f9d21154c 2859 ssl->buffers.inputBuffer.idx = 0;
wolfSSL 0:d92f9d21154c 2860 ssl->buffers.inputBuffer.length = usedLength;
wolfSSL 0:d92f9d21154c 2861
wolfSSL 0:d92f9d21154c 2862 return 0;
wolfSSL 0:d92f9d21154c 2863 }
wolfSSL 0:d92f9d21154c 2864
wolfSSL 0:d92f9d21154c 2865
wolfSSL 0:d92f9d21154c 2866 /* check available size into output buffer, make room if needed */
wolfSSL 0:d92f9d21154c 2867 int CheckAvailableSize(WOLFSSL *ssl, int size)
wolfSSL 0:d92f9d21154c 2868 {
wolfSSL 0:d92f9d21154c 2869
wolfSSL 0:d92f9d21154c 2870 if (size < 0) {
wolfSSL 0:d92f9d21154c 2871 WOLFSSL_MSG("CheckAvailableSize() called with negative number");
wolfSSL 0:d92f9d21154c 2872 return BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 2873 }
wolfSSL 0:d92f9d21154c 2874
wolfSSL 0:d92f9d21154c 2875 if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
wolfSSL 0:d92f9d21154c 2876 < (word32)size) {
wolfSSL 0:d92f9d21154c 2877 if (GrowOutputBuffer(ssl, size) < 0)
wolfSSL 0:d92f9d21154c 2878 return MEMORY_E;
wolfSSL 0:d92f9d21154c 2879 }
wolfSSL 0:d92f9d21154c 2880
wolfSSL 0:d92f9d21154c 2881 return 0;
wolfSSL 0:d92f9d21154c 2882 }
wolfSSL 0:d92f9d21154c 2883
wolfSSL 0:d92f9d21154c 2884
wolfSSL 0:d92f9d21154c 2885 /* do all verify and sanity checks on record header */
wolfSSL 0:d92f9d21154c 2886 static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
wolfSSL 0:d92f9d21154c 2887 RecordLayerHeader* rh, word16 *size)
wolfSSL 0:d92f9d21154c 2888 {
wolfSSL 0:d92f9d21154c 2889 if (!ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 2890 #ifdef HAVE_FUZZER
wolfSSL 0:d92f9d21154c 2891 if (ssl->fuzzerCb)
wolfSSL 0:d92f9d21154c 2892 ssl->fuzzerCb(ssl, input + *inOutIdx, RECORD_HEADER_SZ, FUZZ_HEAD,
wolfSSL 0:d92f9d21154c 2893 ssl->fuzzerCtx);
wolfSSL 0:d92f9d21154c 2894 #endif
wolfSSL 0:d92f9d21154c 2895 XMEMCPY(rh, input + *inOutIdx, RECORD_HEADER_SZ);
wolfSSL 0:d92f9d21154c 2896 *inOutIdx += RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 2897 ato16(rh->length, size);
wolfSSL 0:d92f9d21154c 2898 }
wolfSSL 0:d92f9d21154c 2899 else {
wolfSSL 0:d92f9d21154c 2900 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 2901 /* type and version in same sport */
wolfSSL 0:d92f9d21154c 2902 XMEMCPY(rh, input + *inOutIdx, ENUM_LEN + VERSION_SZ);
wolfSSL 0:d92f9d21154c 2903 *inOutIdx += ENUM_LEN + VERSION_SZ;
wolfSSL 0:d92f9d21154c 2904 ato16(input + *inOutIdx, &ssl->keys.dtls_state.curEpoch);
wolfSSL 0:d92f9d21154c 2905 *inOutIdx += 4; /* advance past epoch, skip first 2 seq bytes for now */
wolfSSL 0:d92f9d21154c 2906 ato32(input + *inOutIdx, &ssl->keys.dtls_state.curSeq);
wolfSSL 0:d92f9d21154c 2907 *inOutIdx += 4; /* advance past rest of seq */
wolfSSL 0:d92f9d21154c 2908 ato16(input + *inOutIdx, size);
wolfSSL 0:d92f9d21154c 2909 *inOutIdx += LENGTH_SZ;
wolfSSL 0:d92f9d21154c 2910 #ifdef HAVE_FUZZER
wolfSSL 0:d92f9d21154c 2911 if (ssl->fuzzerCb)
wolfSSL 0:d92f9d21154c 2912 ssl->fuzzerCb(ssl, input + *inOutIdx - LENGTH_SZ - 8 - ENUM_LEN -
wolfSSL 0:d92f9d21154c 2913 VERSION_SZ, ENUM_LEN + VERSION_SZ + 8 + LENGTH_SZ,
wolfSSL 0:d92f9d21154c 2914 FUZZ_HEAD, ssl->fuzzerCtx);
wolfSSL 0:d92f9d21154c 2915 #endif
wolfSSL 0:d92f9d21154c 2916 #endif
wolfSSL 0:d92f9d21154c 2917 }
wolfSSL 0:d92f9d21154c 2918
wolfSSL 0:d92f9d21154c 2919 /* catch version mismatch */
wolfSSL 0:d92f9d21154c 2920 if (rh->pvMajor != ssl->version.major || rh->pvMinor != ssl->version.minor){
wolfSSL 0:d92f9d21154c 2921 if (ssl->options.side == WOLFSSL_SERVER_END &&
wolfSSL 0:d92f9d21154c 2922 ssl->options.acceptState == ACCEPT_BEGIN)
wolfSSL 0:d92f9d21154c 2923 WOLFSSL_MSG("Client attempting to connect with different version");
wolfSSL 0:d92f9d21154c 2924 else if (ssl->options.side == WOLFSSL_CLIENT_END &&
wolfSSL 0:d92f9d21154c 2925 ssl->options.downgrade &&
wolfSSL 0:d92f9d21154c 2926 ssl->options.connectState < FIRST_REPLY_DONE)
wolfSSL 0:d92f9d21154c 2927 WOLFSSL_MSG("Server attempting to accept with different version");
wolfSSL 0:d92f9d21154c 2928 else {
wolfSSL 0:d92f9d21154c 2929 WOLFSSL_MSG("SSL version error");
wolfSSL 0:d92f9d21154c 2930 return VERSION_ERROR; /* only use requested version */
wolfSSL 0:d92f9d21154c 2931 }
wolfSSL 0:d92f9d21154c 2932 }
wolfSSL 0:d92f9d21154c 2933
wolfSSL 0:d92f9d21154c 2934 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 2935 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 2936 if (DtlsCheckWindow(&ssl->keys.dtls_state) != 1)
wolfSSL 0:d92f9d21154c 2937 return SEQUENCE_ERROR;
wolfSSL 0:d92f9d21154c 2938 }
wolfSSL 0:d92f9d21154c 2939 #endif
wolfSSL 0:d92f9d21154c 2940
wolfSSL 0:d92f9d21154c 2941 /* record layer length check */
wolfSSL 0:d92f9d21154c 2942 #ifdef HAVE_MAX_FRAGMENT
wolfSSL 0:d92f9d21154c 2943 if (*size > (ssl->max_fragment + MAX_COMP_EXTRA + MAX_MSG_EXTRA)) {
wolfSSL 0:d92f9d21154c 2944 SendAlert(ssl, alert_fatal, record_overflow);
wolfSSL 0:d92f9d21154c 2945 return LENGTH_ERROR;
wolfSSL 0:d92f9d21154c 2946 }
wolfSSL 0:d92f9d21154c 2947 #else
wolfSSL 0:d92f9d21154c 2948 if (*size > (MAX_RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
wolfSSL 0:d92f9d21154c 2949 return LENGTH_ERROR;
wolfSSL 0:d92f9d21154c 2950 #endif
wolfSSL 0:d92f9d21154c 2951
wolfSSL 0:d92f9d21154c 2952 /* verify record type here as well */
wolfSSL 0:d92f9d21154c 2953 switch (rh->type) {
wolfSSL 0:d92f9d21154c 2954 case handshake:
wolfSSL 0:d92f9d21154c 2955 case change_cipher_spec:
wolfSSL 0:d92f9d21154c 2956 case application_data:
wolfSSL 0:d92f9d21154c 2957 case alert:
wolfSSL 0:d92f9d21154c 2958 break;
wolfSSL 0:d92f9d21154c 2959 case no_type:
wolfSSL 0:d92f9d21154c 2960 default:
wolfSSL 0:d92f9d21154c 2961 WOLFSSL_MSG("Unknown Record Type");
wolfSSL 0:d92f9d21154c 2962 return UNKNOWN_RECORD_TYPE;
wolfSSL 0:d92f9d21154c 2963 }
wolfSSL 0:d92f9d21154c 2964
wolfSSL 0:d92f9d21154c 2965 /* haven't decrypted this record yet */
wolfSSL 0:d92f9d21154c 2966 ssl->keys.decryptedCur = 0;
wolfSSL 0:d92f9d21154c 2967
wolfSSL 0:d92f9d21154c 2968 return 0;
wolfSSL 0:d92f9d21154c 2969 }
wolfSSL 0:d92f9d21154c 2970
wolfSSL 0:d92f9d21154c 2971
wolfSSL 0:d92f9d21154c 2972 static int GetHandShakeHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
wolfSSL 0:d92f9d21154c 2973 byte *type, word32 *size, word32 totalSz)
wolfSSL 0:d92f9d21154c 2974 {
wolfSSL 0:d92f9d21154c 2975 const byte *ptr = input + *inOutIdx;
wolfSSL 0:d92f9d21154c 2976 (void)ssl;
wolfSSL 0:d92f9d21154c 2977
wolfSSL 0:d92f9d21154c 2978 *inOutIdx += HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 2979 if (*inOutIdx > totalSz)
wolfSSL 0:d92f9d21154c 2980 return BUFFER_E;
wolfSSL 0:d92f9d21154c 2981
wolfSSL 0:d92f9d21154c 2982 *type = ptr[0];
wolfSSL 0:d92f9d21154c 2983 c24to32(&ptr[1], size);
wolfSSL 0:d92f9d21154c 2984
wolfSSL 0:d92f9d21154c 2985 return 0;
wolfSSL 0:d92f9d21154c 2986 }
wolfSSL 0:d92f9d21154c 2987
wolfSSL 0:d92f9d21154c 2988
wolfSSL 0:d92f9d21154c 2989 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 2990 static int GetDtlsHandShakeHeader(WOLFSSL* ssl, const byte* input,
wolfSSL 0:d92f9d21154c 2991 word32* inOutIdx, byte *type, word32 *size,
wolfSSL 0:d92f9d21154c 2992 word32 *fragOffset, word32 *fragSz,
wolfSSL 0:d92f9d21154c 2993 word32 totalSz)
wolfSSL 0:d92f9d21154c 2994 {
wolfSSL 0:d92f9d21154c 2995 word32 idx = *inOutIdx;
wolfSSL 0:d92f9d21154c 2996
wolfSSL 0:d92f9d21154c 2997 *inOutIdx += HANDSHAKE_HEADER_SZ + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 2998 if (*inOutIdx > totalSz)
wolfSSL 0:d92f9d21154c 2999 return BUFFER_E;
wolfSSL 0:d92f9d21154c 3000
wolfSSL 0:d92f9d21154c 3001 *type = input[idx++];
wolfSSL 0:d92f9d21154c 3002 c24to32(input + idx, size);
wolfSSL 0:d92f9d21154c 3003 idx += BYTE3_LEN;
wolfSSL 0:d92f9d21154c 3004
wolfSSL 0:d92f9d21154c 3005 ato16(input + idx, &ssl->keys.dtls_peer_handshake_number);
wolfSSL 0:d92f9d21154c 3006 idx += DTLS_HANDSHAKE_SEQ_SZ;
wolfSSL 0:d92f9d21154c 3007
wolfSSL 0:d92f9d21154c 3008 c24to32(input + idx, fragOffset);
wolfSSL 0:d92f9d21154c 3009 idx += DTLS_HANDSHAKE_FRAG_SZ;
wolfSSL 0:d92f9d21154c 3010 c24to32(input + idx, fragSz);
wolfSSL 0:d92f9d21154c 3011
wolfSSL 0:d92f9d21154c 3012 return 0;
wolfSSL 0:d92f9d21154c 3013 }
wolfSSL 0:d92f9d21154c 3014 #endif
wolfSSL 0:d92f9d21154c 3015
wolfSSL 0:d92f9d21154c 3016
wolfSSL 0:d92f9d21154c 3017 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 3018 /* fill with MD5 pad size since biggest required */
wolfSSL 0:d92f9d21154c 3019 static const byte PAD1[PAD_MD5] =
wolfSSL 0:d92f9d21154c 3020 { 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
wolfSSL 0:d92f9d21154c 3021 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
wolfSSL 0:d92f9d21154c 3022 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
wolfSSL 0:d92f9d21154c 3023 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
wolfSSL 0:d92f9d21154c 3024 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
wolfSSL 0:d92f9d21154c 3025 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
wolfSSL 0:d92f9d21154c 3026 };
wolfSSL 0:d92f9d21154c 3027 static const byte PAD2[PAD_MD5] =
wolfSSL 0:d92f9d21154c 3028 { 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
wolfSSL 0:d92f9d21154c 3029 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
wolfSSL 0:d92f9d21154c 3030 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
wolfSSL 0:d92f9d21154c 3031 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
wolfSSL 0:d92f9d21154c 3032 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
wolfSSL 0:d92f9d21154c 3033 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
wolfSSL 0:d92f9d21154c 3034 };
wolfSSL 0:d92f9d21154c 3035
wolfSSL 0:d92f9d21154c 3036 /* calculate MD5 hash for finished */
wolfSSL 0:d92f9d21154c 3037 #ifdef WOLFSSL_TI_HASH
wolfSSL 0:d92f9d21154c 3038 #include <wolfssl/wolfcrypt/hash.h>
wolfSSL 0:d92f9d21154c 3039 #endif
wolfSSL 0:d92f9d21154c 3040
wolfSSL 0:d92f9d21154c 3041 static void BuildMD5(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
wolfSSL 0:d92f9d21154c 3042 {
wolfSSL 0:d92f9d21154c 3043
wolfSSL 0:d92f9d21154c 3044 byte md5_result[MD5_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 3045
wolfSSL 0:d92f9d21154c 3046 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 3047 Md5* md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 3048 Md5* md5_2 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 3049 #else
wolfSSL 0:d92f9d21154c 3050 Md5 md5[1];
wolfSSL 0:d92f9d21154c 3051 Md5 md5_2[1];
wolfSSL 0:d92f9d21154c 3052 #endif
wolfSSL 0:d92f9d21154c 3053
wolfSSL 0:d92f9d21154c 3054 /* make md5 inner */
wolfSSL 0:d92f9d21154c 3055 md5[0] = ssl->hsHashes->hashMd5 ; /* Save current position */
wolfSSL 0:d92f9d21154c 3056
wolfSSL 0:d92f9d21154c 3057 wc_Md5Update(&ssl->hsHashes->hashMd5, sender, SIZEOF_SENDER);
wolfSSL 0:d92f9d21154c 3058 wc_Md5Update(&ssl->hsHashes->hashMd5, ssl->arrays->masterSecret,SECRET_LEN);
wolfSSL 0:d92f9d21154c 3059 wc_Md5Update(&ssl->hsHashes->hashMd5, PAD1, PAD_MD5);
wolfSSL 0:d92f9d21154c 3060 wc_Md5GetHash(&ssl->hsHashes->hashMd5, md5_result);
wolfSSL 0:d92f9d21154c 3061 wc_Md5RestorePos(&ssl->hsHashes->hashMd5, md5) ; /* Restore current position */
wolfSSL 0:d92f9d21154c 3062
wolfSSL 0:d92f9d21154c 3063 /* make md5 outer */
wolfSSL 0:d92f9d21154c 3064 wc_InitMd5(md5_2) ;
wolfSSL 0:d92f9d21154c 3065 wc_Md5Update(md5_2, ssl->arrays->masterSecret,SECRET_LEN);
wolfSSL 0:d92f9d21154c 3066 wc_Md5Update(md5_2, PAD2, PAD_MD5);
wolfSSL 0:d92f9d21154c 3067 wc_Md5Update(md5_2, md5_result, MD5_DIGEST_SIZE);
wolfSSL 0:d92f9d21154c 3068 wc_Md5Final(md5_2, hashes->md5);
wolfSSL 0:d92f9d21154c 3069
wolfSSL 0:d92f9d21154c 3070 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 3071 XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 3072 XFREE(md5_2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 3073 #endif
wolfSSL 0:d92f9d21154c 3074
wolfSSL 0:d92f9d21154c 3075 }
wolfSSL 0:d92f9d21154c 3076
wolfSSL 0:d92f9d21154c 3077
wolfSSL 0:d92f9d21154c 3078 /* calculate SHA hash for finished */
wolfSSL 0:d92f9d21154c 3079 static void BuildSHA(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
wolfSSL 0:d92f9d21154c 3080 {
wolfSSL 0:d92f9d21154c 3081 byte sha_result[SHA_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 3082
wolfSSL 0:d92f9d21154c 3083 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 3084 Sha* sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 3085 Sha* sha2 = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 3086 #else
wolfSSL 0:d92f9d21154c 3087 Sha sha[1];
wolfSSL 0:d92f9d21154c 3088 Sha sha2[1] ;
wolfSSL 0:d92f9d21154c 3089 #endif
wolfSSL 0:d92f9d21154c 3090 /* make sha inner */
wolfSSL 0:d92f9d21154c 3091 sha[0] = ssl->hsHashes->hashSha ; /* Save current position */
wolfSSL 0:d92f9d21154c 3092
wolfSSL 0:d92f9d21154c 3093 wc_ShaUpdate(&ssl->hsHashes->hashSha, sender, SIZEOF_SENDER);
wolfSSL 0:d92f9d21154c 3094 wc_ShaUpdate(&ssl->hsHashes->hashSha, ssl->arrays->masterSecret,SECRET_LEN);
wolfSSL 0:d92f9d21154c 3095 wc_ShaUpdate(&ssl->hsHashes->hashSha, PAD1, PAD_SHA);
wolfSSL 0:d92f9d21154c 3096 wc_ShaGetHash(&ssl->hsHashes->hashSha, sha_result);
wolfSSL 0:d92f9d21154c 3097 wc_ShaRestorePos(&ssl->hsHashes->hashSha, sha) ; /* Restore current position */
wolfSSL 0:d92f9d21154c 3098
wolfSSL 0:d92f9d21154c 3099 /* make sha outer */
wolfSSL 0:d92f9d21154c 3100 wc_InitSha(sha2) ;
wolfSSL 0:d92f9d21154c 3101 wc_ShaUpdate(sha2, ssl->arrays->masterSecret,SECRET_LEN);
wolfSSL 0:d92f9d21154c 3102 wc_ShaUpdate(sha2, PAD2, PAD_SHA);
wolfSSL 0:d92f9d21154c 3103 wc_ShaUpdate(sha2, sha_result, SHA_DIGEST_SIZE);
wolfSSL 0:d92f9d21154c 3104 wc_ShaFinal(sha2, hashes->sha);
wolfSSL 0:d92f9d21154c 3105
wolfSSL 0:d92f9d21154c 3106 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 3107 XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 3108 XFREE(sha2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 3109 #endif
wolfSSL 0:d92f9d21154c 3110
wolfSSL 0:d92f9d21154c 3111 }
wolfSSL 0:d92f9d21154c 3112 #endif
wolfSSL 0:d92f9d21154c 3113
wolfSSL 0:d92f9d21154c 3114 /* Finished doesn't support SHA512, not SHA512 cipher suites yet */
wolfSSL 0:d92f9d21154c 3115 static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
wolfSSL 0:d92f9d21154c 3116 {
wolfSSL 0:d92f9d21154c 3117 int ret = 0;
wolfSSL 0:d92f9d21154c 3118 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 3119 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 3120 Sha384* sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 3121 #endif
wolfSSL 0:d92f9d21154c 3122 #else
wolfSSL 0:d92f9d21154c 3123 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 3124 Sha384 sha384[1];
wolfSSL 0:d92f9d21154c 3125 #endif
wolfSSL 0:d92f9d21154c 3126 #endif
wolfSSL 0:d92f9d21154c 3127
wolfSSL 0:d92f9d21154c 3128 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 3129 if (ssl == NULL
wolfSSL 0:d92f9d21154c 3130 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 3131 || sha384 == NULL
wolfSSL 0:d92f9d21154c 3132 #endif
wolfSSL 0:d92f9d21154c 3133 ) {
wolfSSL 0:d92f9d21154c 3134 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 3135 XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 3136 #endif
wolfSSL 0:d92f9d21154c 3137 return MEMORY_E;
wolfSSL 0:d92f9d21154c 3138 }
wolfSSL 0:d92f9d21154c 3139 #endif
wolfSSL 0:d92f9d21154c 3140
wolfSSL 0:d92f9d21154c 3141 /* store current states, building requires get_digest which resets state */
wolfSSL 0:d92f9d21154c 3142 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 3143 sha384[0] = ssl->hsHashes->hashSha384;
wolfSSL 0:d92f9d21154c 3144 #endif
wolfSSL 0:d92f9d21154c 3145
wolfSSL 0:d92f9d21154c 3146 #ifndef NO_TLS
wolfSSL 0:d92f9d21154c 3147 if (ssl->options.tls) {
wolfSSL 0:d92f9d21154c 3148 ret = BuildTlsFinished(ssl, hashes, sender);
wolfSSL 0:d92f9d21154c 3149 }
wolfSSL 0:d92f9d21154c 3150 #endif
wolfSSL 0:d92f9d21154c 3151 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 3152 if (!ssl->options.tls) {
wolfSSL 0:d92f9d21154c 3153 BuildMD5(ssl, hashes, sender);
wolfSSL 0:d92f9d21154c 3154 BuildSHA(ssl, hashes, sender);
wolfSSL 0:d92f9d21154c 3155 }
wolfSSL 0:d92f9d21154c 3156 #endif
wolfSSL 0:d92f9d21154c 3157
wolfSSL 0:d92f9d21154c 3158 /* restore */
wolfSSL 0:d92f9d21154c 3159 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 3160 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 3161 ssl->hsHashes->hashSha384 = sha384[0];
wolfSSL 0:d92f9d21154c 3162 #endif
wolfSSL 0:d92f9d21154c 3163 }
wolfSSL 0:d92f9d21154c 3164
wolfSSL 0:d92f9d21154c 3165 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 3166 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 3167 XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 3168 #endif
wolfSSL 0:d92f9d21154c 3169 #endif
wolfSSL 0:d92f9d21154c 3170
wolfSSL 0:d92f9d21154c 3171 return ret;
wolfSSL 0:d92f9d21154c 3172 }
wolfSSL 0:d92f9d21154c 3173
wolfSSL 0:d92f9d21154c 3174
wolfSSL 0:d92f9d21154c 3175 /* cipher requirements */
wolfSSL 0:d92f9d21154c 3176 enum {
wolfSSL 0:d92f9d21154c 3177 REQUIRES_RSA,
wolfSSL 0:d92f9d21154c 3178 REQUIRES_DHE,
wolfSSL 0:d92f9d21154c 3179 REQUIRES_ECC_DSA,
wolfSSL 0:d92f9d21154c 3180 REQUIRES_ECC_STATIC,
wolfSSL 0:d92f9d21154c 3181 REQUIRES_PSK,
wolfSSL 0:d92f9d21154c 3182 REQUIRES_NTRU,
wolfSSL 0:d92f9d21154c 3183 REQUIRES_RSA_SIG
wolfSSL 0:d92f9d21154c 3184 };
wolfSSL 0:d92f9d21154c 3185
wolfSSL 0:d92f9d21154c 3186
wolfSSL 0:d92f9d21154c 3187
wolfSSL 0:d92f9d21154c 3188 /* Does this cipher suite (first, second) have the requirement
wolfSSL 0:d92f9d21154c 3189 an ephemeral key exchange will still require the key for signing
wolfSSL 0:d92f9d21154c 3190 the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */
wolfSSL 0:d92f9d21154c 3191 static int CipherRequires(byte first, byte second, int requirement)
wolfSSL 0:d92f9d21154c 3192 {
wolfSSL 0:d92f9d21154c 3193
wolfSSL 0:d92f9d21154c 3194 if (first == CHACHA_BYTE) {
wolfSSL 0:d92f9d21154c 3195
wolfSSL 0:d92f9d21154c 3196 switch (second) {
wolfSSL 0:d92f9d21154c 3197
wolfSSL 0:d92f9d21154c 3198 case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
wolfSSL 0:d92f9d21154c 3199 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3200 return 1;
wolfSSL 0:d92f9d21154c 3201 break;
wolfSSL 0:d92f9d21154c 3202
wolfSSL 0:d92f9d21154c 3203 case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
wolfSSL 0:d92f9d21154c 3204 if (requirement == REQUIRES_ECC_DSA)
wolfSSL 0:d92f9d21154c 3205 return 1;
wolfSSL 0:d92f9d21154c 3206 break;
wolfSSL 0:d92f9d21154c 3207
wolfSSL 0:d92f9d21154c 3208 case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
wolfSSL 0:d92f9d21154c 3209 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3210 return 1;
wolfSSL 0:d92f9d21154c 3211 if (requirement == REQUIRES_DHE)
wolfSSL 0:d92f9d21154c 3212 return 1;
wolfSSL 0:d92f9d21154c 3213 break;
wolfSSL 0:d92f9d21154c 3214 }
wolfSSL 0:d92f9d21154c 3215 }
wolfSSL 0:d92f9d21154c 3216
wolfSSL 0:d92f9d21154c 3217 /* ECC extensions */
wolfSSL 0:d92f9d21154c 3218 if (first == ECC_BYTE) {
wolfSSL 0:d92f9d21154c 3219
wolfSSL 0:d92f9d21154c 3220 switch (second) {
wolfSSL 0:d92f9d21154c 3221
wolfSSL 0:d92f9d21154c 3222 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 3223 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
wolfSSL 0:d92f9d21154c 3224 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3225 return 1;
wolfSSL 0:d92f9d21154c 3226 break;
wolfSSL 0:d92f9d21154c 3227
wolfSSL 0:d92f9d21154c 3228 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
wolfSSL 0:d92f9d21154c 3229 if (requirement == REQUIRES_ECC_STATIC)
wolfSSL 0:d92f9d21154c 3230 return 1;
wolfSSL 0:d92f9d21154c 3231 if (requirement == REQUIRES_RSA_SIG)
wolfSSL 0:d92f9d21154c 3232 return 1;
wolfSSL 0:d92f9d21154c 3233 break;
wolfSSL 0:d92f9d21154c 3234
wolfSSL 0:d92f9d21154c 3235 #ifndef NO_DES3
wolfSSL 0:d92f9d21154c 3236 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
wolfSSL 0:d92f9d21154c 3237 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3238 return 1;
wolfSSL 0:d92f9d21154c 3239 break;
wolfSSL 0:d92f9d21154c 3240
wolfSSL 0:d92f9d21154c 3241 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
wolfSSL 0:d92f9d21154c 3242 if (requirement == REQUIRES_ECC_STATIC)
wolfSSL 0:d92f9d21154c 3243 return 1;
wolfSSL 0:d92f9d21154c 3244 if (requirement == REQUIRES_RSA_SIG)
wolfSSL 0:d92f9d21154c 3245 return 1;
wolfSSL 0:d92f9d21154c 3246 break;
wolfSSL 0:d92f9d21154c 3247 #endif
wolfSSL 0:d92f9d21154c 3248
wolfSSL 0:d92f9d21154c 3249 #ifndef NO_RC4
wolfSSL 0:d92f9d21154c 3250 case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
wolfSSL 0:d92f9d21154c 3251 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3252 return 1;
wolfSSL 0:d92f9d21154c 3253 break;
wolfSSL 0:d92f9d21154c 3254
wolfSSL 0:d92f9d21154c 3255 case TLS_ECDH_RSA_WITH_RC4_128_SHA :
wolfSSL 0:d92f9d21154c 3256 if (requirement == REQUIRES_ECC_STATIC)
wolfSSL 0:d92f9d21154c 3257 return 1;
wolfSSL 0:d92f9d21154c 3258 if (requirement == REQUIRES_RSA_SIG)
wolfSSL 0:d92f9d21154c 3259 return 1;
wolfSSL 0:d92f9d21154c 3260 break;
wolfSSL 0:d92f9d21154c 3261 #endif
wolfSSL 0:d92f9d21154c 3262 #endif /* NO_RSA */
wolfSSL 0:d92f9d21154c 3263
wolfSSL 0:d92f9d21154c 3264 #ifndef NO_DES3
wolfSSL 0:d92f9d21154c 3265 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
wolfSSL 0:d92f9d21154c 3266 if (requirement == REQUIRES_ECC_DSA)
wolfSSL 0:d92f9d21154c 3267 return 1;
wolfSSL 0:d92f9d21154c 3268 break;
wolfSSL 0:d92f9d21154c 3269
wolfSSL 0:d92f9d21154c 3270 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
wolfSSL 0:d92f9d21154c 3271 if (requirement == REQUIRES_ECC_STATIC)
wolfSSL 0:d92f9d21154c 3272 return 1;
wolfSSL 0:d92f9d21154c 3273 break;
wolfSSL 0:d92f9d21154c 3274 #endif
wolfSSL 0:d92f9d21154c 3275 #ifndef NO_RC4
wolfSSL 0:d92f9d21154c 3276 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
wolfSSL 0:d92f9d21154c 3277 if (requirement == REQUIRES_ECC_DSA)
wolfSSL 0:d92f9d21154c 3278 return 1;
wolfSSL 0:d92f9d21154c 3279 break;
wolfSSL 0:d92f9d21154c 3280
wolfSSL 0:d92f9d21154c 3281 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
wolfSSL 0:d92f9d21154c 3282 if (requirement == REQUIRES_ECC_STATIC)
wolfSSL 0:d92f9d21154c 3283 return 1;
wolfSSL 0:d92f9d21154c 3284 break;
wolfSSL 0:d92f9d21154c 3285 #endif
wolfSSL 0:d92f9d21154c 3286 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 3287 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
wolfSSL 0:d92f9d21154c 3288 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3289 return 1;
wolfSSL 0:d92f9d21154c 3290 break;
wolfSSL 0:d92f9d21154c 3291
wolfSSL 0:d92f9d21154c 3292 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
wolfSSL 0:d92f9d21154c 3293 if (requirement == REQUIRES_ECC_STATIC)
wolfSSL 0:d92f9d21154c 3294 return 1;
wolfSSL 0:d92f9d21154c 3295 if (requirement == REQUIRES_RSA_SIG)
wolfSSL 0:d92f9d21154c 3296 return 1;
wolfSSL 0:d92f9d21154c 3297 break;
wolfSSL 0:d92f9d21154c 3298 #endif
wolfSSL 0:d92f9d21154c 3299
wolfSSL 0:d92f9d21154c 3300 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
wolfSSL 0:d92f9d21154c 3301 if (requirement == REQUIRES_ECC_DSA)
wolfSSL 0:d92f9d21154c 3302 return 1;
wolfSSL 0:d92f9d21154c 3303 break;
wolfSSL 0:d92f9d21154c 3304
wolfSSL 0:d92f9d21154c 3305 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
wolfSSL 0:d92f9d21154c 3306 if (requirement == REQUIRES_ECC_STATIC)
wolfSSL 0:d92f9d21154c 3307 return 1;
wolfSSL 0:d92f9d21154c 3308 break;
wolfSSL 0:d92f9d21154c 3309
wolfSSL 0:d92f9d21154c 3310 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
wolfSSL 0:d92f9d21154c 3311 if (requirement == REQUIRES_ECC_DSA)
wolfSSL 0:d92f9d21154c 3312 return 1;
wolfSSL 0:d92f9d21154c 3313 break;
wolfSSL 0:d92f9d21154c 3314
wolfSSL 0:d92f9d21154c 3315 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
wolfSSL 0:d92f9d21154c 3316 if (requirement == REQUIRES_ECC_STATIC)
wolfSSL 0:d92f9d21154c 3317 return 1;
wolfSSL 0:d92f9d21154c 3318 break;
wolfSSL 0:d92f9d21154c 3319
wolfSSL 0:d92f9d21154c 3320 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 :
wolfSSL 0:d92f9d21154c 3321 if (requirement == REQUIRES_ECC_DSA)
wolfSSL 0:d92f9d21154c 3322 return 1;
wolfSSL 0:d92f9d21154c 3323 break;
wolfSSL 0:d92f9d21154c 3324
wolfSSL 0:d92f9d21154c 3325 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 :
wolfSSL 0:d92f9d21154c 3326 if (requirement == REQUIRES_ECC_DSA)
wolfSSL 0:d92f9d21154c 3327 return 1;
wolfSSL 0:d92f9d21154c 3328 break;
wolfSSL 0:d92f9d21154c 3329
wolfSSL 0:d92f9d21154c 3330 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 :
wolfSSL 0:d92f9d21154c 3331 if (requirement == REQUIRES_ECC_STATIC)
wolfSSL 0:d92f9d21154c 3332 return 1;
wolfSSL 0:d92f9d21154c 3333 break;
wolfSSL 0:d92f9d21154c 3334
wolfSSL 0:d92f9d21154c 3335 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 :
wolfSSL 0:d92f9d21154c 3336 if (requirement == REQUIRES_ECC_STATIC)
wolfSSL 0:d92f9d21154c 3337 return 1;
wolfSSL 0:d92f9d21154c 3338 break;
wolfSSL 0:d92f9d21154c 3339
wolfSSL 0:d92f9d21154c 3340 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 3341 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 :
wolfSSL 0:d92f9d21154c 3342 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3343 return 1;
wolfSSL 0:d92f9d21154c 3344 break;
wolfSSL 0:d92f9d21154c 3345
wolfSSL 0:d92f9d21154c 3346 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 :
wolfSSL 0:d92f9d21154c 3347 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3348 return 1;
wolfSSL 0:d92f9d21154c 3349 break;
wolfSSL 0:d92f9d21154c 3350
wolfSSL 0:d92f9d21154c 3351 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 :
wolfSSL 0:d92f9d21154c 3352 if (requirement == REQUIRES_ECC_STATIC)
wolfSSL 0:d92f9d21154c 3353 return 1;
wolfSSL 0:d92f9d21154c 3354 if (requirement == REQUIRES_RSA_SIG)
wolfSSL 0:d92f9d21154c 3355 return 1;
wolfSSL 0:d92f9d21154c 3356 break;
wolfSSL 0:d92f9d21154c 3357
wolfSSL 0:d92f9d21154c 3358 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 :
wolfSSL 0:d92f9d21154c 3359 if (requirement == REQUIRES_ECC_STATIC)
wolfSSL 0:d92f9d21154c 3360 return 1;
wolfSSL 0:d92f9d21154c 3361 if (requirement == REQUIRES_RSA_SIG)
wolfSSL 0:d92f9d21154c 3362 return 1;
wolfSSL 0:d92f9d21154c 3363 break;
wolfSSL 0:d92f9d21154c 3364
wolfSSL 0:d92f9d21154c 3365 case TLS_RSA_WITH_AES_128_CCM_8 :
wolfSSL 0:d92f9d21154c 3366 case TLS_RSA_WITH_AES_256_CCM_8 :
wolfSSL 0:d92f9d21154c 3367 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3368 return 1;
wolfSSL 0:d92f9d21154c 3369 if (requirement == REQUIRES_RSA_SIG)
wolfSSL 0:d92f9d21154c 3370 return 1;
wolfSSL 0:d92f9d21154c 3371 break;
wolfSSL 0:d92f9d21154c 3372
wolfSSL 0:d92f9d21154c 3373 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
wolfSSL 0:d92f9d21154c 3374 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 :
wolfSSL 0:d92f9d21154c 3375 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3376 return 1;
wolfSSL 0:d92f9d21154c 3377 if (requirement == REQUIRES_RSA_SIG)
wolfSSL 0:d92f9d21154c 3378 return 1;
wolfSSL 0:d92f9d21154c 3379 break;
wolfSSL 0:d92f9d21154c 3380
wolfSSL 0:d92f9d21154c 3381 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 :
wolfSSL 0:d92f9d21154c 3382 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 :
wolfSSL 0:d92f9d21154c 3383 if (requirement == REQUIRES_RSA_SIG)
wolfSSL 0:d92f9d21154c 3384 return 1;
wolfSSL 0:d92f9d21154c 3385 if (requirement == REQUIRES_ECC_STATIC)
wolfSSL 0:d92f9d21154c 3386 return 1;
wolfSSL 0:d92f9d21154c 3387 break;
wolfSSL 0:d92f9d21154c 3388 #endif
wolfSSL 0:d92f9d21154c 3389
wolfSSL 0:d92f9d21154c 3390 case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 :
wolfSSL 0:d92f9d21154c 3391 case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 :
wolfSSL 0:d92f9d21154c 3392 if (requirement == REQUIRES_ECC_DSA)
wolfSSL 0:d92f9d21154c 3393 return 1;
wolfSSL 0:d92f9d21154c 3394 break;
wolfSSL 0:d92f9d21154c 3395
wolfSSL 0:d92f9d21154c 3396 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 :
wolfSSL 0:d92f9d21154c 3397 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
wolfSSL 0:d92f9d21154c 3398 if (requirement == REQUIRES_ECC_DSA)
wolfSSL 0:d92f9d21154c 3399 return 1;
wolfSSL 0:d92f9d21154c 3400 break;
wolfSSL 0:d92f9d21154c 3401
wolfSSL 0:d92f9d21154c 3402 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 :
wolfSSL 0:d92f9d21154c 3403 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 :
wolfSSL 0:d92f9d21154c 3404 if (requirement == REQUIRES_ECC_DSA)
wolfSSL 0:d92f9d21154c 3405 return 1;
wolfSSL 0:d92f9d21154c 3406 if (requirement == REQUIRES_ECC_STATIC)
wolfSSL 0:d92f9d21154c 3407 return 1;
wolfSSL 0:d92f9d21154c 3408 break;
wolfSSL 0:d92f9d21154c 3409
wolfSSL 0:d92f9d21154c 3410 case TLS_PSK_WITH_AES_128_CCM:
wolfSSL 0:d92f9d21154c 3411 case TLS_PSK_WITH_AES_256_CCM:
wolfSSL 0:d92f9d21154c 3412 case TLS_PSK_WITH_AES_128_CCM_8:
wolfSSL 0:d92f9d21154c 3413 case TLS_PSK_WITH_AES_256_CCM_8:
wolfSSL 0:d92f9d21154c 3414 if (requirement == REQUIRES_PSK)
wolfSSL 0:d92f9d21154c 3415 return 1;
wolfSSL 0:d92f9d21154c 3416 break;
wolfSSL 0:d92f9d21154c 3417
wolfSSL 0:d92f9d21154c 3418 case TLS_DHE_PSK_WITH_AES_128_CCM:
wolfSSL 0:d92f9d21154c 3419 case TLS_DHE_PSK_WITH_AES_256_CCM:
wolfSSL 0:d92f9d21154c 3420 if (requirement == REQUIRES_PSK)
wolfSSL 0:d92f9d21154c 3421 return 1;
wolfSSL 0:d92f9d21154c 3422 if (requirement == REQUIRES_DHE)
wolfSSL 0:d92f9d21154c 3423 return 1;
wolfSSL 0:d92f9d21154c 3424 break;
wolfSSL 0:d92f9d21154c 3425
wolfSSL 0:d92f9d21154c 3426 default:
wolfSSL 0:d92f9d21154c 3427 WOLFSSL_MSG("Unsupported cipher suite, CipherRequires ECC");
wolfSSL 0:d92f9d21154c 3428 return 0;
wolfSSL 0:d92f9d21154c 3429 } /* switch */
wolfSSL 0:d92f9d21154c 3430 } /* if */
wolfSSL 0:d92f9d21154c 3431 if (first != ECC_BYTE) { /* normal suites */
wolfSSL 0:d92f9d21154c 3432 switch (second) {
wolfSSL 0:d92f9d21154c 3433
wolfSSL 0:d92f9d21154c 3434 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 3435 case SSL_RSA_WITH_RC4_128_SHA :
wolfSSL 0:d92f9d21154c 3436 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3437 return 1;
wolfSSL 0:d92f9d21154c 3438 break;
wolfSSL 0:d92f9d21154c 3439
wolfSSL 0:d92f9d21154c 3440 case TLS_NTRU_RSA_WITH_RC4_128_SHA :
wolfSSL 0:d92f9d21154c 3441 if (requirement == REQUIRES_NTRU)
wolfSSL 0:d92f9d21154c 3442 return 1;
wolfSSL 0:d92f9d21154c 3443 break;
wolfSSL 0:d92f9d21154c 3444
wolfSSL 0:d92f9d21154c 3445 case SSL_RSA_WITH_RC4_128_MD5 :
wolfSSL 0:d92f9d21154c 3446 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3447 return 1;
wolfSSL 0:d92f9d21154c 3448 break;
wolfSSL 0:d92f9d21154c 3449
wolfSSL 0:d92f9d21154c 3450 case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
wolfSSL 0:d92f9d21154c 3451 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3452 return 1;
wolfSSL 0:d92f9d21154c 3453 break;
wolfSSL 0:d92f9d21154c 3454
wolfSSL 0:d92f9d21154c 3455 case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
wolfSSL 0:d92f9d21154c 3456 if (requirement == REQUIRES_NTRU)
wolfSSL 0:d92f9d21154c 3457 return 1;
wolfSSL 0:d92f9d21154c 3458 break;
wolfSSL 0:d92f9d21154c 3459
wolfSSL 0:d92f9d21154c 3460 case TLS_RSA_WITH_AES_128_CBC_SHA :
wolfSSL 0:d92f9d21154c 3461 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3462 return 1;
wolfSSL 0:d92f9d21154c 3463 break;
wolfSSL 0:d92f9d21154c 3464
wolfSSL 0:d92f9d21154c 3465 case TLS_RSA_WITH_AES_128_CBC_SHA256 :
wolfSSL 0:d92f9d21154c 3466 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3467 return 1;
wolfSSL 0:d92f9d21154c 3468 break;
wolfSSL 0:d92f9d21154c 3469
wolfSSL 0:d92f9d21154c 3470 case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
wolfSSL 0:d92f9d21154c 3471 if (requirement == REQUIRES_NTRU)
wolfSSL 0:d92f9d21154c 3472 return 1;
wolfSSL 0:d92f9d21154c 3473 break;
wolfSSL 0:d92f9d21154c 3474
wolfSSL 0:d92f9d21154c 3475 case TLS_RSA_WITH_AES_256_CBC_SHA :
wolfSSL 0:d92f9d21154c 3476 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3477 return 1;
wolfSSL 0:d92f9d21154c 3478 break;
wolfSSL 0:d92f9d21154c 3479
wolfSSL 0:d92f9d21154c 3480 case TLS_RSA_WITH_AES_256_CBC_SHA256 :
wolfSSL 0:d92f9d21154c 3481 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3482 return 1;
wolfSSL 0:d92f9d21154c 3483 break;
wolfSSL 0:d92f9d21154c 3484
wolfSSL 0:d92f9d21154c 3485 case TLS_RSA_WITH_NULL_SHA :
wolfSSL 0:d92f9d21154c 3486 case TLS_RSA_WITH_NULL_SHA256 :
wolfSSL 0:d92f9d21154c 3487 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3488 return 1;
wolfSSL 0:d92f9d21154c 3489 break;
wolfSSL 0:d92f9d21154c 3490
wolfSSL 0:d92f9d21154c 3491 case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
wolfSSL 0:d92f9d21154c 3492 if (requirement == REQUIRES_NTRU)
wolfSSL 0:d92f9d21154c 3493 return 1;
wolfSSL 0:d92f9d21154c 3494 break;
wolfSSL 0:d92f9d21154c 3495 #endif
wolfSSL 0:d92f9d21154c 3496
wolfSSL 0:d92f9d21154c 3497 case TLS_PSK_WITH_AES_128_GCM_SHA256 :
wolfSSL 0:d92f9d21154c 3498 case TLS_PSK_WITH_AES_256_GCM_SHA384 :
wolfSSL 0:d92f9d21154c 3499 case TLS_PSK_WITH_AES_128_CBC_SHA256 :
wolfSSL 0:d92f9d21154c 3500 case TLS_PSK_WITH_AES_256_CBC_SHA384 :
wolfSSL 0:d92f9d21154c 3501 case TLS_PSK_WITH_AES_128_CBC_SHA :
wolfSSL 0:d92f9d21154c 3502 case TLS_PSK_WITH_AES_256_CBC_SHA :
wolfSSL 0:d92f9d21154c 3503 case TLS_PSK_WITH_NULL_SHA384 :
wolfSSL 0:d92f9d21154c 3504 case TLS_PSK_WITH_NULL_SHA256 :
wolfSSL 0:d92f9d21154c 3505 case TLS_PSK_WITH_NULL_SHA :
wolfSSL 0:d92f9d21154c 3506 if (requirement == REQUIRES_PSK)
wolfSSL 0:d92f9d21154c 3507 return 1;
wolfSSL 0:d92f9d21154c 3508 break;
wolfSSL 0:d92f9d21154c 3509
wolfSSL 0:d92f9d21154c 3510 case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 :
wolfSSL 0:d92f9d21154c 3511 case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 :
wolfSSL 0:d92f9d21154c 3512 case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 :
wolfSSL 0:d92f9d21154c 3513 case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 :
wolfSSL 0:d92f9d21154c 3514 case TLS_DHE_PSK_WITH_NULL_SHA384 :
wolfSSL 0:d92f9d21154c 3515 case TLS_DHE_PSK_WITH_NULL_SHA256 :
wolfSSL 0:d92f9d21154c 3516 if (requirement == REQUIRES_DHE)
wolfSSL 0:d92f9d21154c 3517 return 1;
wolfSSL 0:d92f9d21154c 3518 if (requirement == REQUIRES_PSK)
wolfSSL 0:d92f9d21154c 3519 return 1;
wolfSSL 0:d92f9d21154c 3520 break;
wolfSSL 0:d92f9d21154c 3521
wolfSSL 0:d92f9d21154c 3522 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 3523 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
wolfSSL 0:d92f9d21154c 3524 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3525 return 1;
wolfSSL 0:d92f9d21154c 3526 if (requirement == REQUIRES_DHE)
wolfSSL 0:d92f9d21154c 3527 return 1;
wolfSSL 0:d92f9d21154c 3528 break;
wolfSSL 0:d92f9d21154c 3529
wolfSSL 0:d92f9d21154c 3530 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
wolfSSL 0:d92f9d21154c 3531 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3532 return 1;
wolfSSL 0:d92f9d21154c 3533 if (requirement == REQUIRES_DHE)
wolfSSL 0:d92f9d21154c 3534 return 1;
wolfSSL 0:d92f9d21154c 3535 break;
wolfSSL 0:d92f9d21154c 3536
wolfSSL 0:d92f9d21154c 3537 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
wolfSSL 0:d92f9d21154c 3538 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3539 return 1;
wolfSSL 0:d92f9d21154c 3540 if (requirement == REQUIRES_DHE)
wolfSSL 0:d92f9d21154c 3541 return 1;
wolfSSL 0:d92f9d21154c 3542 break;
wolfSSL 0:d92f9d21154c 3543
wolfSSL 0:d92f9d21154c 3544 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
wolfSSL 0:d92f9d21154c 3545 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3546 return 1;
wolfSSL 0:d92f9d21154c 3547 if (requirement == REQUIRES_DHE)
wolfSSL 0:d92f9d21154c 3548 return 1;
wolfSSL 0:d92f9d21154c 3549 break;
wolfSSL 0:d92f9d21154c 3550
wolfSSL 0:d92f9d21154c 3551 case TLS_RSA_WITH_HC_128_MD5 :
wolfSSL 0:d92f9d21154c 3552 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3553 return 1;
wolfSSL 0:d92f9d21154c 3554 break;
wolfSSL 0:d92f9d21154c 3555
wolfSSL 0:d92f9d21154c 3556 case TLS_RSA_WITH_HC_128_SHA :
wolfSSL 0:d92f9d21154c 3557 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3558 return 1;
wolfSSL 0:d92f9d21154c 3559 break;
wolfSSL 0:d92f9d21154c 3560
wolfSSL 0:d92f9d21154c 3561 case TLS_RSA_WITH_HC_128_B2B256:
wolfSSL 0:d92f9d21154c 3562 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3563 return 1;
wolfSSL 0:d92f9d21154c 3564 break;
wolfSSL 0:d92f9d21154c 3565
wolfSSL 0:d92f9d21154c 3566 case TLS_RSA_WITH_AES_128_CBC_B2B256:
wolfSSL 0:d92f9d21154c 3567 case TLS_RSA_WITH_AES_256_CBC_B2B256:
wolfSSL 0:d92f9d21154c 3568 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3569 return 1;
wolfSSL 0:d92f9d21154c 3570 break;
wolfSSL 0:d92f9d21154c 3571
wolfSSL 0:d92f9d21154c 3572 case TLS_RSA_WITH_RABBIT_SHA :
wolfSSL 0:d92f9d21154c 3573 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3574 return 1;
wolfSSL 0:d92f9d21154c 3575 break;
wolfSSL 0:d92f9d21154c 3576
wolfSSL 0:d92f9d21154c 3577 case TLS_RSA_WITH_AES_128_GCM_SHA256 :
wolfSSL 0:d92f9d21154c 3578 case TLS_RSA_WITH_AES_256_GCM_SHA384 :
wolfSSL 0:d92f9d21154c 3579 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3580 return 1;
wolfSSL 0:d92f9d21154c 3581 break;
wolfSSL 0:d92f9d21154c 3582
wolfSSL 0:d92f9d21154c 3583 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 :
wolfSSL 0:d92f9d21154c 3584 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 :
wolfSSL 0:d92f9d21154c 3585 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3586 return 1;
wolfSSL 0:d92f9d21154c 3587 if (requirement == REQUIRES_DHE)
wolfSSL 0:d92f9d21154c 3588 return 1;
wolfSSL 0:d92f9d21154c 3589 break;
wolfSSL 0:d92f9d21154c 3590
wolfSSL 0:d92f9d21154c 3591 case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA :
wolfSSL 0:d92f9d21154c 3592 case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA :
wolfSSL 0:d92f9d21154c 3593 case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
wolfSSL 0:d92f9d21154c 3594 case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
wolfSSL 0:d92f9d21154c 3595 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3596 return 1;
wolfSSL 0:d92f9d21154c 3597 break;
wolfSSL 0:d92f9d21154c 3598
wolfSSL 0:d92f9d21154c 3599 case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA :
wolfSSL 0:d92f9d21154c 3600 case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA :
wolfSSL 0:d92f9d21154c 3601 case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 :
wolfSSL 0:d92f9d21154c 3602 case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 :
wolfSSL 0:d92f9d21154c 3603 if (requirement == REQUIRES_RSA)
wolfSSL 0:d92f9d21154c 3604 return 1;
wolfSSL 0:d92f9d21154c 3605 if (requirement == REQUIRES_RSA_SIG)
wolfSSL 0:d92f9d21154c 3606 return 1;
wolfSSL 0:d92f9d21154c 3607 if (requirement == REQUIRES_DHE)
wolfSSL 0:d92f9d21154c 3608 return 1;
wolfSSL 0:d92f9d21154c 3609 break;
wolfSSL 0:d92f9d21154c 3610 #endif
wolfSSL 0:d92f9d21154c 3611 #ifdef HAVE_ANON
wolfSSL 0:d92f9d21154c 3612 case TLS_DH_anon_WITH_AES_128_CBC_SHA :
wolfSSL 0:d92f9d21154c 3613 if (requirement == REQUIRES_DHE)
wolfSSL 0:d92f9d21154c 3614 return 1;
wolfSSL 0:d92f9d21154c 3615 break;
wolfSSL 0:d92f9d21154c 3616 #endif
wolfSSL 0:d92f9d21154c 3617
wolfSSL 0:d92f9d21154c 3618 default:
wolfSSL 0:d92f9d21154c 3619 WOLFSSL_MSG("Unsupported cipher suite, CipherRequires");
wolfSSL 0:d92f9d21154c 3620 return 0;
wolfSSL 0:d92f9d21154c 3621 } /* switch */
wolfSSL 0:d92f9d21154c 3622 } /* if ECC / Normal suites else */
wolfSSL 0:d92f9d21154c 3623
wolfSSL 0:d92f9d21154c 3624 return 0;
wolfSSL 0:d92f9d21154c 3625 }
wolfSSL 0:d92f9d21154c 3626
wolfSSL 0:d92f9d21154c 3627
wolfSSL 0:d92f9d21154c 3628 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 3629
wolfSSL 0:d92f9d21154c 3630
wolfSSL 0:d92f9d21154c 3631 /* Match names with wildcards, each wildcard can represent a single name
wolfSSL 0:d92f9d21154c 3632 component or fragment but not mulitple names, i.e.,
wolfSSL 0:d92f9d21154c 3633 *.z.com matches y.z.com but not x.y.z.com
wolfSSL 0:d92f9d21154c 3634
wolfSSL 0:d92f9d21154c 3635 return 1 on success */
wolfSSL 0:d92f9d21154c 3636 static int MatchDomainName(const char* pattern, int len, const char* str)
wolfSSL 0:d92f9d21154c 3637 {
wolfSSL 0:d92f9d21154c 3638 char p, s;
wolfSSL 0:d92f9d21154c 3639
wolfSSL 0:d92f9d21154c 3640 if (pattern == NULL || str == NULL || len <= 0)
wolfSSL 0:d92f9d21154c 3641 return 0;
wolfSSL 0:d92f9d21154c 3642
wolfSSL 0:d92f9d21154c 3643 while (len > 0) {
wolfSSL 0:d92f9d21154c 3644
wolfSSL 0:d92f9d21154c 3645 p = (char)XTOLOWER((unsigned char)*pattern++);
wolfSSL 0:d92f9d21154c 3646 if (p == 0)
wolfSSL 0:d92f9d21154c 3647 break;
wolfSSL 0:d92f9d21154c 3648
wolfSSL 0:d92f9d21154c 3649 if (p == '*') {
wolfSSL 0:d92f9d21154c 3650 while (--len > 0 &&
wolfSSL 0:d92f9d21154c 3651 (p = (char)XTOLOWER((unsigned char)*pattern++)) == '*')
wolfSSL 0:d92f9d21154c 3652 ;
wolfSSL 0:d92f9d21154c 3653
wolfSSL 0:d92f9d21154c 3654 if (len == 0)
wolfSSL 0:d92f9d21154c 3655 p = '\0';
wolfSSL 0:d92f9d21154c 3656
wolfSSL 0:d92f9d21154c 3657 while ( (s = (char)XTOLOWER((unsigned char) *str)) != '\0') {
wolfSSL 0:d92f9d21154c 3658 if (s == p)
wolfSSL 0:d92f9d21154c 3659 break;
wolfSSL 0:d92f9d21154c 3660 if (s == '.')
wolfSSL 0:d92f9d21154c 3661 return 0;
wolfSSL 0:d92f9d21154c 3662 str++;
wolfSSL 0:d92f9d21154c 3663 }
wolfSSL 0:d92f9d21154c 3664 }
wolfSSL 0:d92f9d21154c 3665 else {
wolfSSL 0:d92f9d21154c 3666 if (p != (char)XTOLOWER((unsigned char) *str))
wolfSSL 0:d92f9d21154c 3667 return 0;
wolfSSL 0:d92f9d21154c 3668 }
wolfSSL 0:d92f9d21154c 3669
wolfSSL 0:d92f9d21154c 3670 if (*str != '\0')
wolfSSL 0:d92f9d21154c 3671 str++;
wolfSSL 0:d92f9d21154c 3672
wolfSSL 0:d92f9d21154c 3673 if (len > 0)
wolfSSL 0:d92f9d21154c 3674 len--;
wolfSSL 0:d92f9d21154c 3675 }
wolfSSL 0:d92f9d21154c 3676
wolfSSL 0:d92f9d21154c 3677 return *str == '\0';
wolfSSL 0:d92f9d21154c 3678 }
wolfSSL 0:d92f9d21154c 3679
wolfSSL 0:d92f9d21154c 3680
wolfSSL 0:d92f9d21154c 3681 /* try to find an altName match to domain, return 1 on success */
wolfSSL 0:d92f9d21154c 3682 static int CheckAltNames(DecodedCert* dCert, char* domain)
wolfSSL 0:d92f9d21154c 3683 {
wolfSSL 0:d92f9d21154c 3684 int match = 0;
wolfSSL 0:d92f9d21154c 3685 DNS_entry* altName = NULL;
wolfSSL 0:d92f9d21154c 3686
wolfSSL 0:d92f9d21154c 3687 WOLFSSL_MSG("Checking AltNames");
wolfSSL 0:d92f9d21154c 3688
wolfSSL 0:d92f9d21154c 3689 if (dCert)
wolfSSL 0:d92f9d21154c 3690 altName = dCert->altNames;
wolfSSL 0:d92f9d21154c 3691
wolfSSL 0:d92f9d21154c 3692 while (altName) {
wolfSSL 0:d92f9d21154c 3693 WOLFSSL_MSG(" individual AltName check");
wolfSSL 0:d92f9d21154c 3694
wolfSSL 0:d92f9d21154c 3695 if (MatchDomainName(altName->name,(int)XSTRLEN(altName->name), domain)){
wolfSSL 0:d92f9d21154c 3696 match = 1;
wolfSSL 0:d92f9d21154c 3697 break;
wolfSSL 0:d92f9d21154c 3698 }
wolfSSL 0:d92f9d21154c 3699
wolfSSL 0:d92f9d21154c 3700 altName = altName->next;
wolfSSL 0:d92f9d21154c 3701 }
wolfSSL 0:d92f9d21154c 3702
wolfSSL 0:d92f9d21154c 3703 return match;
wolfSSL 0:d92f9d21154c 3704 }
wolfSSL 0:d92f9d21154c 3705
wolfSSL 0:d92f9d21154c 3706
wolfSSL 0:d92f9d21154c 3707 #if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
wolfSSL 0:d92f9d21154c 3708
wolfSSL 0:d92f9d21154c 3709 /* Copy parts X509 needs from Decoded cert, 0 on success */
wolfSSL 0:d92f9d21154c 3710 int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert)
wolfSSL 0:d92f9d21154c 3711 {
wolfSSL 0:d92f9d21154c 3712 int ret = 0;
wolfSSL 0:d92f9d21154c 3713
wolfSSL 0:d92f9d21154c 3714 if (x509 == NULL || dCert == NULL)
wolfSSL 0:d92f9d21154c 3715 return BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 3716
wolfSSL 0:d92f9d21154c 3717 x509->version = dCert->version + 1;
wolfSSL 0:d92f9d21154c 3718
wolfSSL 0:d92f9d21154c 3719 XSTRNCPY(x509->issuer.name, dCert->issuer, ASN_NAME_MAX);
wolfSSL 0:d92f9d21154c 3720 x509->issuer.name[ASN_NAME_MAX - 1] = '\0';
wolfSSL 0:d92f9d21154c 3721 x509->issuer.sz = (int)XSTRLEN(x509->issuer.name) + 1;
wolfSSL 0:d92f9d21154c 3722 #ifdef OPENSSL_EXTRA
wolfSSL 0:d92f9d21154c 3723 if (dCert->issuerName.fullName != NULL) {
wolfSSL 0:d92f9d21154c 3724 XMEMCPY(&x509->issuer.fullName,
wolfSSL 0:d92f9d21154c 3725 &dCert->issuerName, sizeof(DecodedName));
wolfSSL 0:d92f9d21154c 3726 x509->issuer.fullName.fullName = (char*)XMALLOC(
wolfSSL 0:d92f9d21154c 3727 dCert->issuerName.fullNameLen, NULL, DYNAMIC_TYPE_X509);
wolfSSL 0:d92f9d21154c 3728 if (x509->issuer.fullName.fullName != NULL)
wolfSSL 0:d92f9d21154c 3729 XMEMCPY(x509->issuer.fullName.fullName,
wolfSSL 0:d92f9d21154c 3730 dCert->issuerName.fullName, dCert->issuerName.fullNameLen);
wolfSSL 0:d92f9d21154c 3731 }
wolfSSL 0:d92f9d21154c 3732 #endif /* OPENSSL_EXTRA */
wolfSSL 0:d92f9d21154c 3733
wolfSSL 0:d92f9d21154c 3734 XSTRNCPY(x509->subject.name, dCert->subject, ASN_NAME_MAX);
wolfSSL 0:d92f9d21154c 3735 x509->subject.name[ASN_NAME_MAX - 1] = '\0';
wolfSSL 0:d92f9d21154c 3736 x509->subject.sz = (int)XSTRLEN(x509->subject.name) + 1;
wolfSSL 0:d92f9d21154c 3737 #ifdef OPENSSL_EXTRA
wolfSSL 0:d92f9d21154c 3738 if (dCert->subjectName.fullName != NULL) {
wolfSSL 0:d92f9d21154c 3739 XMEMCPY(&x509->subject.fullName,
wolfSSL 0:d92f9d21154c 3740 &dCert->subjectName, sizeof(DecodedName));
wolfSSL 0:d92f9d21154c 3741 x509->subject.fullName.fullName = (char*)XMALLOC(
wolfSSL 0:d92f9d21154c 3742 dCert->subjectName.fullNameLen, NULL, DYNAMIC_TYPE_X509);
wolfSSL 0:d92f9d21154c 3743 if (x509->subject.fullName.fullName != NULL)
wolfSSL 0:d92f9d21154c 3744 XMEMCPY(x509->subject.fullName.fullName,
wolfSSL 0:d92f9d21154c 3745 dCert->subjectName.fullName, dCert->subjectName.fullNameLen);
wolfSSL 0:d92f9d21154c 3746 }
wolfSSL 0:d92f9d21154c 3747 #endif /* OPENSSL_EXTRA */
wolfSSL 0:d92f9d21154c 3748
wolfSSL 0:d92f9d21154c 3749 XMEMCPY(x509->serial, dCert->serial, EXTERNAL_SERIAL_SIZE);
wolfSSL 0:d92f9d21154c 3750 x509->serialSz = dCert->serialSz;
wolfSSL 0:d92f9d21154c 3751 if (dCert->subjectCNLen < ASN_NAME_MAX) {
wolfSSL 0:d92f9d21154c 3752 XMEMCPY(x509->subjectCN, dCert->subjectCN, dCert->subjectCNLen);
wolfSSL 0:d92f9d21154c 3753 x509->subjectCN[dCert->subjectCNLen] = '\0';
wolfSSL 0:d92f9d21154c 3754 }
wolfSSL 0:d92f9d21154c 3755 else
wolfSSL 0:d92f9d21154c 3756 x509->subjectCN[0] = '\0';
wolfSSL 0:d92f9d21154c 3757
wolfSSL 0:d92f9d21154c 3758 #ifdef WOLFSSL_SEP
wolfSSL 0:d92f9d21154c 3759 {
wolfSSL 0:d92f9d21154c 3760 int minSz = min(dCert->deviceTypeSz, EXTERNAL_SERIAL_SIZE);
wolfSSL 0:d92f9d21154c 3761 if (minSz > 0) {
wolfSSL 0:d92f9d21154c 3762 x509->deviceTypeSz = minSz;
wolfSSL 0:d92f9d21154c 3763 XMEMCPY(x509->deviceType, dCert->deviceType, minSz);
wolfSSL 0:d92f9d21154c 3764 }
wolfSSL 0:d92f9d21154c 3765 else
wolfSSL 0:d92f9d21154c 3766 x509->deviceTypeSz = 0;
wolfSSL 0:d92f9d21154c 3767 minSz = min(dCert->hwTypeSz, EXTERNAL_SERIAL_SIZE);
wolfSSL 0:d92f9d21154c 3768 if (minSz != 0) {
wolfSSL 0:d92f9d21154c 3769 x509->hwTypeSz = minSz;
wolfSSL 0:d92f9d21154c 3770 XMEMCPY(x509->hwType, dCert->hwType, minSz);
wolfSSL 0:d92f9d21154c 3771 }
wolfSSL 0:d92f9d21154c 3772 else
wolfSSL 0:d92f9d21154c 3773 x509->hwTypeSz = 0;
wolfSSL 0:d92f9d21154c 3774 minSz = min(dCert->hwSerialNumSz, EXTERNAL_SERIAL_SIZE);
wolfSSL 0:d92f9d21154c 3775 if (minSz != 0) {
wolfSSL 0:d92f9d21154c 3776 x509->hwSerialNumSz = minSz;
wolfSSL 0:d92f9d21154c 3777 XMEMCPY(x509->hwSerialNum, dCert->hwSerialNum, minSz);
wolfSSL 0:d92f9d21154c 3778 }
wolfSSL 0:d92f9d21154c 3779 else
wolfSSL 0:d92f9d21154c 3780 x509->hwSerialNumSz = 0;
wolfSSL 0:d92f9d21154c 3781 }
wolfSSL 0:d92f9d21154c 3782 #endif /* WOLFSSL_SEP */
wolfSSL 0:d92f9d21154c 3783 {
wolfSSL 0:d92f9d21154c 3784 int minSz = min(dCert->beforeDateLen, MAX_DATE_SZ);
wolfSSL 0:d92f9d21154c 3785 if (minSz != 0) {
wolfSSL 0:d92f9d21154c 3786 x509->notBeforeSz = minSz;
wolfSSL 0:d92f9d21154c 3787 XMEMCPY(x509->notBefore, dCert->beforeDate, minSz);
wolfSSL 0:d92f9d21154c 3788 }
wolfSSL 0:d92f9d21154c 3789 else
wolfSSL 0:d92f9d21154c 3790 x509->notBeforeSz = 0;
wolfSSL 0:d92f9d21154c 3791 minSz = min(dCert->afterDateLen, MAX_DATE_SZ);
wolfSSL 0:d92f9d21154c 3792 if (minSz != 0) {
wolfSSL 0:d92f9d21154c 3793 x509->notAfterSz = minSz;
wolfSSL 0:d92f9d21154c 3794 XMEMCPY(x509->notAfter, dCert->afterDate, minSz);
wolfSSL 0:d92f9d21154c 3795 }
wolfSSL 0:d92f9d21154c 3796 else
wolfSSL 0:d92f9d21154c 3797 x509->notAfterSz = 0;
wolfSSL 0:d92f9d21154c 3798 }
wolfSSL 0:d92f9d21154c 3799
wolfSSL 0:d92f9d21154c 3800 if (dCert->publicKey != NULL && dCert->pubKeySize != 0) {
wolfSSL 0:d92f9d21154c 3801 x509->pubKey.buffer = (byte*)XMALLOC(
wolfSSL 0:d92f9d21154c 3802 dCert->pubKeySize, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 0:d92f9d21154c 3803 if (x509->pubKey.buffer != NULL) {
wolfSSL 0:d92f9d21154c 3804 x509->pubKeyOID = dCert->keyOID;
wolfSSL 0:d92f9d21154c 3805 x509->pubKey.length = dCert->pubKeySize;
wolfSSL 0:d92f9d21154c 3806 XMEMCPY(x509->pubKey.buffer, dCert->publicKey, dCert->pubKeySize);
wolfSSL 0:d92f9d21154c 3807 }
wolfSSL 0:d92f9d21154c 3808 else
wolfSSL 0:d92f9d21154c 3809 ret = MEMORY_E;
wolfSSL 0:d92f9d21154c 3810 }
wolfSSL 0:d92f9d21154c 3811
wolfSSL 0:d92f9d21154c 3812 if (dCert->signature != NULL && dCert->sigLength != 0) {
wolfSSL 0:d92f9d21154c 3813 x509->sig.buffer = (byte*)XMALLOC(
wolfSSL 0:d92f9d21154c 3814 dCert->sigLength, NULL, DYNAMIC_TYPE_SIGNATURE);
wolfSSL 0:d92f9d21154c 3815 if (x509->sig.buffer == NULL) {
wolfSSL 0:d92f9d21154c 3816 ret = MEMORY_E;
wolfSSL 0:d92f9d21154c 3817 }
wolfSSL 0:d92f9d21154c 3818 else {
wolfSSL 0:d92f9d21154c 3819 XMEMCPY(x509->sig.buffer, dCert->signature, dCert->sigLength);
wolfSSL 0:d92f9d21154c 3820 x509->sig.length = dCert->sigLength;
wolfSSL 0:d92f9d21154c 3821 x509->sigOID = dCert->signatureOID;
wolfSSL 0:d92f9d21154c 3822 }
wolfSSL 0:d92f9d21154c 3823 }
wolfSSL 0:d92f9d21154c 3824
wolfSSL 0:d92f9d21154c 3825 /* store cert for potential retrieval */
wolfSSL 0:d92f9d21154c 3826 x509->derCert.buffer = (byte*)XMALLOC(dCert->maxIdx, NULL,
wolfSSL 0:d92f9d21154c 3827 DYNAMIC_TYPE_CERT);
wolfSSL 0:d92f9d21154c 3828 if (x509->derCert.buffer == NULL) {
wolfSSL 0:d92f9d21154c 3829 ret = MEMORY_E;
wolfSSL 0:d92f9d21154c 3830 }
wolfSSL 0:d92f9d21154c 3831 else {
wolfSSL 0:d92f9d21154c 3832 XMEMCPY(x509->derCert.buffer, dCert->source, dCert->maxIdx);
wolfSSL 0:d92f9d21154c 3833 x509->derCert.length = dCert->maxIdx;
wolfSSL 0:d92f9d21154c 3834 }
wolfSSL 0:d92f9d21154c 3835
wolfSSL 0:d92f9d21154c 3836 x509->altNames = dCert->altNames;
wolfSSL 0:d92f9d21154c 3837 dCert->weOwnAltNames = 0;
wolfSSL 0:d92f9d21154c 3838 x509->altNamesNext = x509->altNames; /* index hint */
wolfSSL 0:d92f9d21154c 3839
wolfSSL 0:d92f9d21154c 3840 x509->isCa = dCert->isCA;
wolfSSL 0:d92f9d21154c 3841 #ifdef OPENSSL_EXTRA
wolfSSL 0:d92f9d21154c 3842 x509->pathLength = dCert->pathLength;
wolfSSL 0:d92f9d21154c 3843 x509->keyUsage = dCert->extKeyUsage;
wolfSSL 0:d92f9d21154c 3844
wolfSSL 0:d92f9d21154c 3845 x509->basicConstSet = dCert->extBasicConstSet;
wolfSSL 0:d92f9d21154c 3846 x509->basicConstCrit = dCert->extBasicConstCrit;
wolfSSL 0:d92f9d21154c 3847 x509->basicConstPlSet = dCert->extBasicConstPlSet;
wolfSSL 0:d92f9d21154c 3848 x509->subjAltNameSet = dCert->extSubjAltNameSet;
wolfSSL 0:d92f9d21154c 3849 x509->subjAltNameCrit = dCert->extSubjAltNameCrit;
wolfSSL 0:d92f9d21154c 3850 x509->authKeyIdSet = dCert->extAuthKeyIdSet;
wolfSSL 0:d92f9d21154c 3851 x509->authKeyIdCrit = dCert->extAuthKeyIdCrit;
wolfSSL 0:d92f9d21154c 3852 if (dCert->extAuthKeyIdSrc != NULL && dCert->extAuthKeyIdSz != 0) {
wolfSSL 0:d92f9d21154c 3853 x509->authKeyId = (byte*)XMALLOC(dCert->extAuthKeyIdSz, NULL, 0);
wolfSSL 0:d92f9d21154c 3854 if (x509->authKeyId != NULL) {
wolfSSL 0:d92f9d21154c 3855 XMEMCPY(x509->authKeyId,
wolfSSL 0:d92f9d21154c 3856 dCert->extAuthKeyIdSrc, dCert->extAuthKeyIdSz);
wolfSSL 0:d92f9d21154c 3857 x509->authKeyIdSz = dCert->extAuthKeyIdSz;
wolfSSL 0:d92f9d21154c 3858 }
wolfSSL 0:d92f9d21154c 3859 else
wolfSSL 0:d92f9d21154c 3860 ret = MEMORY_E;
wolfSSL 0:d92f9d21154c 3861 }
wolfSSL 0:d92f9d21154c 3862 x509->subjKeyIdSet = dCert->extSubjKeyIdSet;
wolfSSL 0:d92f9d21154c 3863 x509->subjKeyIdCrit = dCert->extSubjKeyIdCrit;
wolfSSL 0:d92f9d21154c 3864 if (dCert->extSubjKeyIdSrc != NULL && dCert->extSubjKeyIdSz != 0) {
wolfSSL 0:d92f9d21154c 3865 x509->subjKeyId = (byte*)XMALLOC(dCert->extSubjKeyIdSz, NULL, 0);
wolfSSL 0:d92f9d21154c 3866 if (x509->subjKeyId != NULL) {
wolfSSL 0:d92f9d21154c 3867 XMEMCPY(x509->subjKeyId,
wolfSSL 0:d92f9d21154c 3868 dCert->extSubjKeyIdSrc, dCert->extSubjKeyIdSz);
wolfSSL 0:d92f9d21154c 3869 x509->subjKeyIdSz = dCert->extSubjKeyIdSz;
wolfSSL 0:d92f9d21154c 3870 }
wolfSSL 0:d92f9d21154c 3871 else
wolfSSL 0:d92f9d21154c 3872 ret = MEMORY_E;
wolfSSL 0:d92f9d21154c 3873 }
wolfSSL 0:d92f9d21154c 3874 x509->keyUsageSet = dCert->extKeyUsageSet;
wolfSSL 0:d92f9d21154c 3875 x509->keyUsageCrit = dCert->extKeyUsageCrit;
wolfSSL 0:d92f9d21154c 3876 #ifdef WOLFSSL_SEP
wolfSSL 0:d92f9d21154c 3877 x509->certPolicySet = dCert->extCertPolicySet;
wolfSSL 0:d92f9d21154c 3878 x509->certPolicyCrit = dCert->extCertPolicyCrit;
wolfSSL 0:d92f9d21154c 3879 #endif /* WOLFSSL_SEP */
wolfSSL 0:d92f9d21154c 3880 #endif /* OPENSSL_EXTRA */
wolfSSL 0:d92f9d21154c 3881 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 3882 x509->pkCurveOID = dCert->pkCurveOID;
wolfSSL 0:d92f9d21154c 3883 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 3884
wolfSSL 0:d92f9d21154c 3885 return ret;
wolfSSL 0:d92f9d21154c 3886 }
wolfSSL 0:d92f9d21154c 3887
wolfSSL 0:d92f9d21154c 3888 #endif /* KEEP_PEER_CERT || SESSION_CERTS */
wolfSSL 0:d92f9d21154c 3889
wolfSSL 0:d92f9d21154c 3890
wolfSSL 0:d92f9d21154c 3891 static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
wolfSSL 0:d92f9d21154c 3892 word32 size)
wolfSSL 0:d92f9d21154c 3893 {
wolfSSL 0:d92f9d21154c 3894 word32 listSz;
wolfSSL 0:d92f9d21154c 3895 word32 begin = *inOutIdx;
wolfSSL 0:d92f9d21154c 3896 int ret = 0;
wolfSSL 0:d92f9d21154c 3897 int anyError = 0;
wolfSSL 0:d92f9d21154c 3898 int totalCerts = 0; /* number of certs in certs buffer */
wolfSSL 0:d92f9d21154c 3899 int count;
wolfSSL 0:d92f9d21154c 3900 buffer certs[MAX_CHAIN_DEPTH];
wolfSSL 0:d92f9d21154c 3901
wolfSSL 0:d92f9d21154c 3902 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 3903 char* domain = NULL;
wolfSSL 0:d92f9d21154c 3904 DecodedCert* dCert = NULL;
wolfSSL 0:d92f9d21154c 3905 WOLFSSL_X509_STORE_CTX* store = NULL;
wolfSSL 0:d92f9d21154c 3906 #else
wolfSSL 0:d92f9d21154c 3907 char domain[ASN_NAME_MAX];
wolfSSL 0:d92f9d21154c 3908 DecodedCert dCert[1];
wolfSSL 0:d92f9d21154c 3909 WOLFSSL_X509_STORE_CTX store[1];
wolfSSL 0:d92f9d21154c 3910 #endif
wolfSSL 0:d92f9d21154c 3911
wolfSSL 0:d92f9d21154c 3912 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 3913 if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 3914 if (ssl->toInfoOn) AddLateName("Certificate", &ssl->timeoutInfo);
wolfSSL 0:d92f9d21154c 3915 #endif
wolfSSL 0:d92f9d21154c 3916
wolfSSL 0:d92f9d21154c 3917 if ((*inOutIdx - begin) + OPAQUE24_LEN > size)
wolfSSL 0:d92f9d21154c 3918 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 3919
wolfSSL 0:d92f9d21154c 3920 c24to32(input + *inOutIdx, &listSz);
wolfSSL 0:d92f9d21154c 3921 *inOutIdx += OPAQUE24_LEN;
wolfSSL 0:d92f9d21154c 3922
wolfSSL 0:d92f9d21154c 3923 #ifdef HAVE_MAX_FRAGMENT
wolfSSL 0:d92f9d21154c 3924 if (listSz > ssl->max_fragment) {
wolfSSL 0:d92f9d21154c 3925 SendAlert(ssl, alert_fatal, record_overflow);
wolfSSL 0:d92f9d21154c 3926 return BUFFER_E;
wolfSSL 0:d92f9d21154c 3927 }
wolfSSL 0:d92f9d21154c 3928 #else
wolfSSL 0:d92f9d21154c 3929 if (listSz > MAX_RECORD_SIZE)
wolfSSL 0:d92f9d21154c 3930 return BUFFER_E;
wolfSSL 0:d92f9d21154c 3931 #endif
wolfSSL 0:d92f9d21154c 3932
wolfSSL 0:d92f9d21154c 3933 if ((*inOutIdx - begin) + listSz != size)
wolfSSL 0:d92f9d21154c 3934 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 3935
wolfSSL 0:d92f9d21154c 3936 WOLFSSL_MSG("Loading peer's cert chain");
wolfSSL 0:d92f9d21154c 3937 /* first put cert chain into buffer so can verify top down
wolfSSL 0:d92f9d21154c 3938 we're sent bottom up */
wolfSSL 0:d92f9d21154c 3939 while (listSz) {
wolfSSL 0:d92f9d21154c 3940 word32 certSz;
wolfSSL 0:d92f9d21154c 3941
wolfSSL 0:d92f9d21154c 3942 if (totalCerts >= MAX_CHAIN_DEPTH)
wolfSSL 0:d92f9d21154c 3943 return MAX_CHAIN_ERROR;
wolfSSL 0:d92f9d21154c 3944
wolfSSL 0:d92f9d21154c 3945 if ((*inOutIdx - begin) + OPAQUE24_LEN > size)
wolfSSL 0:d92f9d21154c 3946 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 3947
wolfSSL 0:d92f9d21154c 3948 c24to32(input + *inOutIdx, &certSz);
wolfSSL 0:d92f9d21154c 3949 *inOutIdx += OPAQUE24_LEN;
wolfSSL 0:d92f9d21154c 3950
wolfSSL 0:d92f9d21154c 3951 if ((*inOutIdx - begin) + certSz > size)
wolfSSL 0:d92f9d21154c 3952 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 3953
wolfSSL 0:d92f9d21154c 3954 certs[totalCerts].length = certSz;
wolfSSL 0:d92f9d21154c 3955 certs[totalCerts].buffer = input + *inOutIdx;
wolfSSL 0:d92f9d21154c 3956
wolfSSL 0:d92f9d21154c 3957 #ifdef SESSION_CERTS
wolfSSL 0:d92f9d21154c 3958 if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
wolfSSL 0:d92f9d21154c 3959 certSz < MAX_X509_SIZE) {
wolfSSL 0:d92f9d21154c 3960 ssl->session.chain.certs[ssl->session.chain.count].length = certSz;
wolfSSL 0:d92f9d21154c 3961 XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
wolfSSL 0:d92f9d21154c 3962 input + *inOutIdx, certSz);
wolfSSL 0:d92f9d21154c 3963 ssl->session.chain.count++;
wolfSSL 0:d92f9d21154c 3964 } else {
wolfSSL 0:d92f9d21154c 3965 WOLFSSL_MSG("Couldn't store chain cert for session");
wolfSSL 0:d92f9d21154c 3966 }
wolfSSL 0:d92f9d21154c 3967 #endif
wolfSSL 0:d92f9d21154c 3968
wolfSSL 0:d92f9d21154c 3969 *inOutIdx += certSz;
wolfSSL 0:d92f9d21154c 3970 listSz -= certSz + CERT_HEADER_SZ;
wolfSSL 0:d92f9d21154c 3971
wolfSSL 0:d92f9d21154c 3972 totalCerts++;
wolfSSL 0:d92f9d21154c 3973 WOLFSSL_MSG(" Put another cert into chain");
wolfSSL 0:d92f9d21154c 3974 }
wolfSSL 0:d92f9d21154c 3975
wolfSSL 0:d92f9d21154c 3976 count = totalCerts;
wolfSSL 0:d92f9d21154c 3977
wolfSSL 0:d92f9d21154c 3978 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 3979 dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
wolfSSL 0:d92f9d21154c 3980 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 3981 if (dCert == NULL)
wolfSSL 0:d92f9d21154c 3982 return MEMORY_E;
wolfSSL 0:d92f9d21154c 3983 #endif
wolfSSL 0:d92f9d21154c 3984
wolfSSL 0:d92f9d21154c 3985 /* verify up to peer's first */
wolfSSL 0:d92f9d21154c 3986 while (count > 1) {
wolfSSL 0:d92f9d21154c 3987 buffer myCert = certs[count - 1];
wolfSSL 0:d92f9d21154c 3988 byte* subjectHash;
wolfSSL 0:d92f9d21154c 3989
wolfSSL 0:d92f9d21154c 3990 InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap);
wolfSSL 0:d92f9d21154c 3991 ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone,
wolfSSL 0:d92f9d21154c 3992 ssl->ctx->cm);
wolfSSL 0:d92f9d21154c 3993 #ifndef NO_SKID
wolfSSL 0:d92f9d21154c 3994 subjectHash = dCert->extSubjKeyId;
wolfSSL 0:d92f9d21154c 3995 #else
wolfSSL 0:d92f9d21154c 3996 subjectHash = dCert->subjectHash;
wolfSSL 0:d92f9d21154c 3997 #endif
wolfSSL 0:d92f9d21154c 3998
wolfSSL 0:d92f9d21154c 3999 if (ret == 0 && dCert->isCA == 0) {
wolfSSL 0:d92f9d21154c 4000 WOLFSSL_MSG("Chain cert is not a CA, not adding as one");
wolfSSL 0:d92f9d21154c 4001 }
wolfSSL 0:d92f9d21154c 4002 else if (ret == 0 && ssl->options.verifyNone) {
wolfSSL 0:d92f9d21154c 4003 WOLFSSL_MSG("Chain cert not verified by option, not adding as CA");
wolfSSL 0:d92f9d21154c 4004 }
wolfSSL 0:d92f9d21154c 4005 else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, subjectHash)) {
wolfSSL 0:d92f9d21154c 4006 buffer add;
wolfSSL 0:d92f9d21154c 4007 add.length = myCert.length;
wolfSSL 0:d92f9d21154c 4008 add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
wolfSSL 0:d92f9d21154c 4009 DYNAMIC_TYPE_CA);
wolfSSL 0:d92f9d21154c 4010 WOLFSSL_MSG("Adding CA from chain");
wolfSSL 0:d92f9d21154c 4011
wolfSSL 0:d92f9d21154c 4012 if (add.buffer == NULL)
wolfSSL 0:d92f9d21154c 4013 return MEMORY_E;
wolfSSL 0:d92f9d21154c 4014 XMEMCPY(add.buffer, myCert.buffer, myCert.length);
wolfSSL 0:d92f9d21154c 4015
wolfSSL 0:d92f9d21154c 4016 ret = AddCA(ssl->ctx->cm, add, WOLFSSL_CHAIN_CA,
wolfSSL 0:d92f9d21154c 4017 ssl->ctx->verifyPeer);
wolfSSL 0:d92f9d21154c 4018 if (ret == 1) ret = 0; /* SSL_SUCCESS for external */
wolfSSL 0:d92f9d21154c 4019 }
wolfSSL 0:d92f9d21154c 4020 else if (ret != 0) {
wolfSSL 0:d92f9d21154c 4021 WOLFSSL_MSG("Failed to verify CA from chain");
wolfSSL 0:d92f9d21154c 4022 }
wolfSSL 0:d92f9d21154c 4023 else {
wolfSSL 0:d92f9d21154c 4024 WOLFSSL_MSG("Verified CA from chain and already had it");
wolfSSL 0:d92f9d21154c 4025 }
wolfSSL 0:d92f9d21154c 4026
wolfSSL 0:d92f9d21154c 4027 #if defined(HAVE_OCSP) || defined(HAVE_CRL)
wolfSSL 0:d92f9d21154c 4028 if (ret == 0) {
wolfSSL 0:d92f9d21154c 4029 int doCrlLookup = 1;
wolfSSL 0:d92f9d21154c 4030 (void)doCrlLookup;
wolfSSL 0:d92f9d21154c 4031 #ifdef HAVE_OCSP
wolfSSL 0:d92f9d21154c 4032 if (ssl->ctx->cm->ocspEnabled && ssl->ctx->cm->ocspCheckAll) {
wolfSSL 0:d92f9d21154c 4033 WOLFSSL_MSG("Doing Non Leaf OCSP check");
wolfSSL 0:d92f9d21154c 4034 ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert);
wolfSSL 0:d92f9d21154c 4035 doCrlLookup = (ret == OCSP_CERT_UNKNOWN);
wolfSSL 0:d92f9d21154c 4036 if (ret != 0) {
wolfSSL 0:d92f9d21154c 4037 doCrlLookup = 0;
wolfSSL 0:d92f9d21154c 4038 WOLFSSL_MSG("\tOCSP Lookup not ok");
wolfSSL 0:d92f9d21154c 4039 }
wolfSSL 0:d92f9d21154c 4040 }
wolfSSL 0:d92f9d21154c 4041 #endif /* HAVE_OCSP */
wolfSSL 0:d92f9d21154c 4042
wolfSSL 0:d92f9d21154c 4043 #ifdef HAVE_CRL
wolfSSL 0:d92f9d21154c 4044 if (doCrlLookup && ssl->ctx->cm->crlEnabled
wolfSSL 0:d92f9d21154c 4045 && ssl->ctx->cm->crlCheckAll) {
wolfSSL 0:d92f9d21154c 4046 WOLFSSL_MSG("Doing Non Leaf CRL check");
wolfSSL 0:d92f9d21154c 4047 ret = CheckCertCRL(ssl->ctx->cm->crl, dCert);
wolfSSL 0:d92f9d21154c 4048
wolfSSL 0:d92f9d21154c 4049 if (ret != 0) {
wolfSSL 0:d92f9d21154c 4050 WOLFSSL_MSG("\tCRL check not ok");
wolfSSL 0:d92f9d21154c 4051 }
wolfSSL 0:d92f9d21154c 4052 }
wolfSSL 0:d92f9d21154c 4053 #endif /* HAVE_CRL */
wolfSSL 0:d92f9d21154c 4054 }
wolfSSL 0:d92f9d21154c 4055 #endif /* HAVE_OCSP || HAVE_CRL */
wolfSSL 0:d92f9d21154c 4056
wolfSSL 0:d92f9d21154c 4057 if (ret != 0 && anyError == 0)
wolfSSL 0:d92f9d21154c 4058 anyError = ret; /* save error from last time */
wolfSSL 0:d92f9d21154c 4059
wolfSSL 0:d92f9d21154c 4060 FreeDecodedCert(dCert);
wolfSSL 0:d92f9d21154c 4061 count--;
wolfSSL 0:d92f9d21154c 4062 }
wolfSSL 0:d92f9d21154c 4063
wolfSSL 0:d92f9d21154c 4064 /* peer's, may not have one if blank client cert sent by TLSv1.2 */
wolfSSL 0:d92f9d21154c 4065 if (count) {
wolfSSL 0:d92f9d21154c 4066 buffer myCert = certs[0];
wolfSSL 0:d92f9d21154c 4067 int fatal = 0;
wolfSSL 0:d92f9d21154c 4068
wolfSSL 0:d92f9d21154c 4069 WOLFSSL_MSG("Verifying Peer's cert");
wolfSSL 0:d92f9d21154c 4070
wolfSSL 0:d92f9d21154c 4071 InitDecodedCert(dCert, myCert.buffer, myCert.length, ssl->heap);
wolfSSL 0:d92f9d21154c 4072 ret = ParseCertRelative(dCert, CERT_TYPE, !ssl->options.verifyNone,
wolfSSL 0:d92f9d21154c 4073 ssl->ctx->cm);
wolfSSL 0:d92f9d21154c 4074 if (ret == 0) {
wolfSSL 0:d92f9d21154c 4075 WOLFSSL_MSG("Verified Peer's cert");
wolfSSL 0:d92f9d21154c 4076 fatal = 0;
wolfSSL 0:d92f9d21154c 4077 }
wolfSSL 0:d92f9d21154c 4078 else if (ret == ASN_PARSE_E) {
wolfSSL 0:d92f9d21154c 4079 WOLFSSL_MSG("Got Peer cert ASN PARSE ERROR, fatal");
wolfSSL 0:d92f9d21154c 4080 fatal = 1;
wolfSSL 0:d92f9d21154c 4081 }
wolfSSL 0:d92f9d21154c 4082 else {
wolfSSL 0:d92f9d21154c 4083 WOLFSSL_MSG("Failed to verify Peer's cert");
wolfSSL 0:d92f9d21154c 4084 if (ssl->verifyCallback) {
wolfSSL 0:d92f9d21154c 4085 WOLFSSL_MSG("\tCallback override available, will continue");
wolfSSL 0:d92f9d21154c 4086 fatal = 0;
wolfSSL 0:d92f9d21154c 4087 }
wolfSSL 0:d92f9d21154c 4088 else {
wolfSSL 0:d92f9d21154c 4089 WOLFSSL_MSG("\tNo callback override available, fatal");
wolfSSL 0:d92f9d21154c 4090 fatal = 1;
wolfSSL 0:d92f9d21154c 4091 }
wolfSSL 0:d92f9d21154c 4092 }
wolfSSL 0:d92f9d21154c 4093
wolfSSL 0:d92f9d21154c 4094 #ifdef HAVE_SECURE_RENEGOTIATION
wolfSSL 0:d92f9d21154c 4095 if (fatal == 0 && ssl->secure_renegotiation
wolfSSL 0:d92f9d21154c 4096 && ssl->secure_renegotiation->enabled) {
wolfSSL 0:d92f9d21154c 4097
wolfSSL 0:d92f9d21154c 4098 if (ssl->keys.encryptionOn) {
wolfSSL 0:d92f9d21154c 4099 /* compare against previous time */
wolfSSL 0:d92f9d21154c 4100 if (XMEMCMP(dCert->subjectHash,
wolfSSL 0:d92f9d21154c 4101 ssl->secure_renegotiation->subject_hash,
wolfSSL 0:d92f9d21154c 4102 SHA_DIGEST_SIZE) != 0) {
wolfSSL 0:d92f9d21154c 4103 WOLFSSL_MSG("Peer sent different cert during scr, fatal");
wolfSSL 0:d92f9d21154c 4104 fatal = 1;
wolfSSL 0:d92f9d21154c 4105 ret = SCR_DIFFERENT_CERT_E;
wolfSSL 0:d92f9d21154c 4106 }
wolfSSL 0:d92f9d21154c 4107 }
wolfSSL 0:d92f9d21154c 4108
wolfSSL 0:d92f9d21154c 4109 /* cache peer's hash */
wolfSSL 0:d92f9d21154c 4110 if (fatal == 0) {
wolfSSL 0:d92f9d21154c 4111 XMEMCPY(ssl->secure_renegotiation->subject_hash,
wolfSSL 0:d92f9d21154c 4112 dCert->subjectHash, SHA_DIGEST_SIZE);
wolfSSL 0:d92f9d21154c 4113 }
wolfSSL 0:d92f9d21154c 4114 }
wolfSSL 0:d92f9d21154c 4115 #endif
wolfSSL 0:d92f9d21154c 4116
wolfSSL 0:d92f9d21154c 4117 #if defined(HAVE_OCSP) || defined(HAVE_CRL)
wolfSSL 0:d92f9d21154c 4118 if (fatal == 0) {
wolfSSL 0:d92f9d21154c 4119 int doCrlLookup = 1;
wolfSSL 0:d92f9d21154c 4120 (void)doCrlLookup;
wolfSSL 0:d92f9d21154c 4121 #ifdef HAVE_OCSP
wolfSSL 0:d92f9d21154c 4122 if (ssl->ctx->cm->ocspEnabled) {
wolfSSL 0:d92f9d21154c 4123 ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert);
wolfSSL 0:d92f9d21154c 4124 doCrlLookup = (ret == OCSP_CERT_UNKNOWN);
wolfSSL 0:d92f9d21154c 4125 if (ret != 0) {
wolfSSL 0:d92f9d21154c 4126 WOLFSSL_MSG("\tOCSP Lookup not ok");
wolfSSL 0:d92f9d21154c 4127 fatal = 0;
wolfSSL 0:d92f9d21154c 4128 }
wolfSSL 0:d92f9d21154c 4129 }
wolfSSL 0:d92f9d21154c 4130 #endif /* HAVE_OCSP */
wolfSSL 0:d92f9d21154c 4131
wolfSSL 0:d92f9d21154c 4132 #ifdef HAVE_CRL
wolfSSL 0:d92f9d21154c 4133 if (doCrlLookup && ssl->ctx->cm->crlEnabled) {
wolfSSL 0:d92f9d21154c 4134 WOLFSSL_MSG("Doing Leaf CRL check");
wolfSSL 0:d92f9d21154c 4135 ret = CheckCertCRL(ssl->ctx->cm->crl, dCert);
wolfSSL 0:d92f9d21154c 4136 if (ret != 0) {
wolfSSL 0:d92f9d21154c 4137 WOLFSSL_MSG("\tCRL check not ok");
wolfSSL 0:d92f9d21154c 4138 fatal = 0;
wolfSSL 0:d92f9d21154c 4139 }
wolfSSL 0:d92f9d21154c 4140 }
wolfSSL 0:d92f9d21154c 4141 #endif /* HAVE_CRL */
wolfSSL 0:d92f9d21154c 4142 }
wolfSSL 0:d92f9d21154c 4143 #endif /* HAVE_OCSP || HAVE_CRL */
wolfSSL 0:d92f9d21154c 4144
wolfSSL 0:d92f9d21154c 4145 #ifdef KEEP_PEER_CERT
wolfSSL 0:d92f9d21154c 4146 {
wolfSSL 0:d92f9d21154c 4147 /* set X509 format for peer cert even if fatal */
wolfSSL 0:d92f9d21154c 4148 int copyRet = CopyDecodedToX509(&ssl->peerCert, dCert);
wolfSSL 0:d92f9d21154c 4149 if (copyRet == MEMORY_E)
wolfSSL 0:d92f9d21154c 4150 fatal = 1;
wolfSSL 0:d92f9d21154c 4151 }
wolfSSL 0:d92f9d21154c 4152 #endif
wolfSSL 0:d92f9d21154c 4153
wolfSSL 0:d92f9d21154c 4154 #ifndef IGNORE_KEY_EXTENSIONS
wolfSSL 0:d92f9d21154c 4155 if (dCert->extKeyUsageSet) {
wolfSSL 0:d92f9d21154c 4156 if ((ssl->specs.kea == rsa_kea) &&
wolfSSL 0:d92f9d21154c 4157 (dCert->extKeyUsage & KEYUSE_KEY_ENCIPHER) == 0) {
wolfSSL 0:d92f9d21154c 4158 ret = KEYUSE_ENCIPHER_E;
wolfSSL 0:d92f9d21154c 4159 }
wolfSSL 0:d92f9d21154c 4160 if ((ssl->specs.sig_algo == rsa_sa_algo ||
wolfSSL 0:d92f9d21154c 4161 (ssl->specs.sig_algo == ecc_dsa_sa_algo &&
wolfSSL 0:d92f9d21154c 4162 !ssl->specs.static_ecdh)) &&
wolfSSL 0:d92f9d21154c 4163 (dCert->extKeyUsage & KEYUSE_DIGITAL_SIG) == 0) {
wolfSSL 0:d92f9d21154c 4164 WOLFSSL_MSG("KeyUse Digital Sig not set");
wolfSSL 0:d92f9d21154c 4165 ret = KEYUSE_SIGNATURE_E;
wolfSSL 0:d92f9d21154c 4166 }
wolfSSL 0:d92f9d21154c 4167 }
wolfSSL 0:d92f9d21154c 4168
wolfSSL 0:d92f9d21154c 4169 if (dCert->extExtKeyUsageSet) {
wolfSSL 0:d92f9d21154c 4170 if (ssl->options.side == WOLFSSL_CLIENT_END) {
wolfSSL 0:d92f9d21154c 4171 if ((dCert->extExtKeyUsage &
wolfSSL 0:d92f9d21154c 4172 (EXTKEYUSE_ANY | EXTKEYUSE_SERVER_AUTH)) == 0) {
wolfSSL 0:d92f9d21154c 4173 WOLFSSL_MSG("ExtKeyUse Server Auth not set");
wolfSSL 0:d92f9d21154c 4174 ret = EXTKEYUSE_AUTH_E;
wolfSSL 0:d92f9d21154c 4175 }
wolfSSL 0:d92f9d21154c 4176 }
wolfSSL 0:d92f9d21154c 4177 else {
wolfSSL 0:d92f9d21154c 4178 if ((dCert->extExtKeyUsage &
wolfSSL 0:d92f9d21154c 4179 (EXTKEYUSE_ANY | EXTKEYUSE_CLIENT_AUTH)) == 0) {
wolfSSL 0:d92f9d21154c 4180 WOLFSSL_MSG("ExtKeyUse Client Auth not set");
wolfSSL 0:d92f9d21154c 4181 ret = EXTKEYUSE_AUTH_E;
wolfSSL 0:d92f9d21154c 4182 }
wolfSSL 0:d92f9d21154c 4183 }
wolfSSL 0:d92f9d21154c 4184 }
wolfSSL 0:d92f9d21154c 4185 #endif /* IGNORE_KEY_EXTENSIONS */
wolfSSL 0:d92f9d21154c 4186
wolfSSL 0:d92f9d21154c 4187 if (fatal) {
wolfSSL 0:d92f9d21154c 4188 FreeDecodedCert(dCert);
wolfSSL 0:d92f9d21154c 4189 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 4190 XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 4191 #endif
wolfSSL 0:d92f9d21154c 4192 ssl->error = ret;
wolfSSL 0:d92f9d21154c 4193 return ret;
wolfSSL 0:d92f9d21154c 4194 }
wolfSSL 0:d92f9d21154c 4195 ssl->options.havePeerCert = 1;
wolfSSL 0:d92f9d21154c 4196
wolfSSL 0:d92f9d21154c 4197 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 4198 domain = (char*)XMALLOC(ASN_NAME_MAX, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 4199 if (domain == NULL) {
wolfSSL 0:d92f9d21154c 4200 FreeDecodedCert(dCert);
wolfSSL 0:d92f9d21154c 4201 XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 4202 return MEMORY_E;
wolfSSL 0:d92f9d21154c 4203 }
wolfSSL 0:d92f9d21154c 4204 #endif
wolfSSL 0:d92f9d21154c 4205 /* store for callback use */
wolfSSL 0:d92f9d21154c 4206 if (dCert->subjectCNLen < ASN_NAME_MAX) {
wolfSSL 0:d92f9d21154c 4207 XMEMCPY(domain, dCert->subjectCN, dCert->subjectCNLen);
wolfSSL 0:d92f9d21154c 4208 domain[dCert->subjectCNLen] = '\0';
wolfSSL 0:d92f9d21154c 4209 }
wolfSSL 0:d92f9d21154c 4210 else
wolfSSL 0:d92f9d21154c 4211 domain[0] = '\0';
wolfSSL 0:d92f9d21154c 4212
wolfSSL 0:d92f9d21154c 4213 if (!ssl->options.verifyNone && ssl->buffers.domainName.buffer) {
wolfSSL 0:d92f9d21154c 4214 if (MatchDomainName(dCert->subjectCN, dCert->subjectCNLen,
wolfSSL 0:d92f9d21154c 4215 (char*)ssl->buffers.domainName.buffer) == 0) {
wolfSSL 0:d92f9d21154c 4216 WOLFSSL_MSG("DomainName match on common name failed");
wolfSSL 0:d92f9d21154c 4217 if (CheckAltNames(dCert,
wolfSSL 0:d92f9d21154c 4218 (char*)ssl->buffers.domainName.buffer) == 0 ) {
wolfSSL 0:d92f9d21154c 4219 WOLFSSL_MSG("DomainName match on alt names failed too");
wolfSSL 0:d92f9d21154c 4220 ret = DOMAIN_NAME_MISMATCH; /* try to get peer key still */
wolfSSL 0:d92f9d21154c 4221 }
wolfSSL 0:d92f9d21154c 4222 }
wolfSSL 0:d92f9d21154c 4223 }
wolfSSL 0:d92f9d21154c 4224
wolfSSL 0:d92f9d21154c 4225 /* decode peer key */
wolfSSL 0:d92f9d21154c 4226 switch (dCert->keyOID) {
wolfSSL 0:d92f9d21154c 4227 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 4228 case RSAk:
wolfSSL 0:d92f9d21154c 4229 {
wolfSSL 0:d92f9d21154c 4230 word32 idx = 0;
wolfSSL 0:d92f9d21154c 4231 int keyRet = 0;
wolfSSL 0:d92f9d21154c 4232
wolfSSL 0:d92f9d21154c 4233 if (ssl->peerRsaKey == NULL) {
wolfSSL 0:d92f9d21154c 4234 ssl->peerRsaKey = (RsaKey*)XMALLOC(sizeof(RsaKey),
wolfSSL 0:d92f9d21154c 4235 ssl->heap, DYNAMIC_TYPE_RSA);
wolfSSL 0:d92f9d21154c 4236 if (ssl->peerRsaKey == NULL) {
wolfSSL 0:d92f9d21154c 4237 WOLFSSL_MSG("PeerRsaKey Memory error");
wolfSSL 0:d92f9d21154c 4238 keyRet = MEMORY_E;
wolfSSL 0:d92f9d21154c 4239 } else {
wolfSSL 0:d92f9d21154c 4240 keyRet = wc_InitRsaKey(ssl->peerRsaKey,
wolfSSL 0:d92f9d21154c 4241 ssl->ctx->heap);
wolfSSL 0:d92f9d21154c 4242 }
wolfSSL 0:d92f9d21154c 4243 } else if (ssl->peerRsaKeyPresent) {
wolfSSL 0:d92f9d21154c 4244 /* don't leak on reuse */
wolfSSL 0:d92f9d21154c 4245 wc_FreeRsaKey(ssl->peerRsaKey);
wolfSSL 0:d92f9d21154c 4246 ssl->peerRsaKeyPresent = 0;
wolfSSL 0:d92f9d21154c 4247 keyRet = wc_InitRsaKey(ssl->peerRsaKey, ssl->heap);
wolfSSL 0:d92f9d21154c 4248 }
wolfSSL 0:d92f9d21154c 4249
wolfSSL 0:d92f9d21154c 4250 if (keyRet != 0 || wc_RsaPublicKeyDecode(dCert->publicKey,
wolfSSL 0:d92f9d21154c 4251 &idx, ssl->peerRsaKey, dCert->pubKeySize) != 0) {
wolfSSL 0:d92f9d21154c 4252 ret = PEER_KEY_ERROR;
wolfSSL 0:d92f9d21154c 4253 }
wolfSSL 0:d92f9d21154c 4254 else {
wolfSSL 0:d92f9d21154c 4255 ssl->peerRsaKeyPresent = 1;
wolfSSL 0:d92f9d21154c 4256 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 4257 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 4258 ssl->buffers.peerRsaKey.buffer =
wolfSSL 0:d92f9d21154c 4259 (byte*)XMALLOC(dCert->pubKeySize,
wolfSSL 0:d92f9d21154c 4260 ssl->heap, DYNAMIC_TYPE_RSA);
wolfSSL 0:d92f9d21154c 4261 if (ssl->buffers.peerRsaKey.buffer == NULL)
wolfSSL 0:d92f9d21154c 4262 ret = MEMORY_ERROR;
wolfSSL 0:d92f9d21154c 4263 else {
wolfSSL 0:d92f9d21154c 4264 XMEMCPY(ssl->buffers.peerRsaKey.buffer,
wolfSSL 0:d92f9d21154c 4265 dCert->publicKey, dCert->pubKeySize);
wolfSSL 0:d92f9d21154c 4266 ssl->buffers.peerRsaKey.length =
wolfSSL 0:d92f9d21154c 4267 dCert->pubKeySize;
wolfSSL 0:d92f9d21154c 4268 }
wolfSSL 0:d92f9d21154c 4269 #endif /* NO_RSA */
wolfSSL 0:d92f9d21154c 4270 #endif /*HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 4271 }
wolfSSL 0:d92f9d21154c 4272 }
wolfSSL 0:d92f9d21154c 4273 break;
wolfSSL 0:d92f9d21154c 4274 #endif /* NO_RSA */
wolfSSL 0:d92f9d21154c 4275 #ifdef HAVE_NTRU
wolfSSL 0:d92f9d21154c 4276 case NTRUk:
wolfSSL 0:d92f9d21154c 4277 {
wolfSSL 0:d92f9d21154c 4278 if (dCert->pubKeySize > sizeof(ssl->peerNtruKey)) {
wolfSSL 0:d92f9d21154c 4279 ret = PEER_KEY_ERROR;
wolfSSL 0:d92f9d21154c 4280 }
wolfSSL 0:d92f9d21154c 4281 else {
wolfSSL 0:d92f9d21154c 4282 XMEMCPY(ssl->peerNtruKey, dCert->publicKey,
wolfSSL 0:d92f9d21154c 4283 dCert->pubKeySize);
wolfSSL 0:d92f9d21154c 4284 ssl->peerNtruKeyLen = (word16)dCert->pubKeySize;
wolfSSL 0:d92f9d21154c 4285 ssl->peerNtruKeyPresent = 1;
wolfSSL 0:d92f9d21154c 4286 }
wolfSSL 0:d92f9d21154c 4287 }
wolfSSL 0:d92f9d21154c 4288 break;
wolfSSL 0:d92f9d21154c 4289 #endif /* HAVE_NTRU */
wolfSSL 0:d92f9d21154c 4290 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 4291 case ECDSAk:
wolfSSL 0:d92f9d21154c 4292 {
wolfSSL 0:d92f9d21154c 4293 if (ssl->peerEccDsaKey == NULL) {
wolfSSL 0:d92f9d21154c 4294 /* alloc/init on demand */
wolfSSL 0:d92f9d21154c 4295 ssl->peerEccDsaKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
wolfSSL 0:d92f9d21154c 4296 ssl->ctx->heap, DYNAMIC_TYPE_ECC);
wolfSSL 0:d92f9d21154c 4297 if (ssl->peerEccDsaKey == NULL) {
wolfSSL 0:d92f9d21154c 4298 WOLFSSL_MSG("PeerEccDsaKey Memory error");
wolfSSL 0:d92f9d21154c 4299 return MEMORY_E;
wolfSSL 0:d92f9d21154c 4300 }
wolfSSL 0:d92f9d21154c 4301 wc_ecc_init(ssl->peerEccDsaKey);
wolfSSL 0:d92f9d21154c 4302 } else if (ssl->peerEccDsaKeyPresent) {
wolfSSL 0:d92f9d21154c 4303 /* don't leak on reuse */
wolfSSL 0:d92f9d21154c 4304 wc_ecc_free(ssl->peerEccDsaKey);
wolfSSL 0:d92f9d21154c 4305 ssl->peerEccDsaKeyPresent = 0;
wolfSSL 0:d92f9d21154c 4306 wc_ecc_init(ssl->peerEccDsaKey);
wolfSSL 0:d92f9d21154c 4307 }
wolfSSL 0:d92f9d21154c 4308 if (wc_ecc_import_x963(dCert->publicKey, dCert->pubKeySize,
wolfSSL 0:d92f9d21154c 4309 ssl->peerEccDsaKey) != 0) {
wolfSSL 0:d92f9d21154c 4310 ret = PEER_KEY_ERROR;
wolfSSL 0:d92f9d21154c 4311 }
wolfSSL 0:d92f9d21154c 4312 else {
wolfSSL 0:d92f9d21154c 4313 ssl->peerEccDsaKeyPresent = 1;
wolfSSL 0:d92f9d21154c 4314 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 4315 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 4316 ssl->buffers.peerEccDsaKey.buffer =
wolfSSL 0:d92f9d21154c 4317 (byte*)XMALLOC(dCert->pubKeySize,
wolfSSL 0:d92f9d21154c 4318 ssl->heap, DYNAMIC_TYPE_ECC);
wolfSSL 0:d92f9d21154c 4319 if (ssl->buffers.peerEccDsaKey.buffer == NULL)
wolfSSL 0:d92f9d21154c 4320 ret = MEMORY_ERROR;
wolfSSL 0:d92f9d21154c 4321 else {
wolfSSL 0:d92f9d21154c 4322 XMEMCPY(ssl->buffers.peerEccDsaKey.buffer,
wolfSSL 0:d92f9d21154c 4323 dCert->publicKey, dCert->pubKeySize);
wolfSSL 0:d92f9d21154c 4324 ssl->buffers.peerEccDsaKey.length =
wolfSSL 0:d92f9d21154c 4325 dCert->pubKeySize;
wolfSSL 0:d92f9d21154c 4326 }
wolfSSL 0:d92f9d21154c 4327 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 4328 #endif /*HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 4329 }
wolfSSL 0:d92f9d21154c 4330 }
wolfSSL 0:d92f9d21154c 4331 break;
wolfSSL 0:d92f9d21154c 4332 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 4333 default:
wolfSSL 0:d92f9d21154c 4334 break;
wolfSSL 0:d92f9d21154c 4335 }
wolfSSL 0:d92f9d21154c 4336
wolfSSL 0:d92f9d21154c 4337 FreeDecodedCert(dCert);
wolfSSL 0:d92f9d21154c 4338 }
wolfSSL 0:d92f9d21154c 4339
wolfSSL 0:d92f9d21154c 4340 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 4341 XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 4342
wolfSSL 0:d92f9d21154c 4343 store = (WOLFSSL_X509_STORE_CTX*)XMALLOC(sizeof(WOLFSSL_X509_STORE_CTX),
wolfSSL 0:d92f9d21154c 4344 NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 4345 if (store == NULL) {
wolfSSL 0:d92f9d21154c 4346 XFREE(domain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 4347 return MEMORY_E;
wolfSSL 0:d92f9d21154c 4348 }
wolfSSL 0:d92f9d21154c 4349 #endif
wolfSSL 0:d92f9d21154c 4350
wolfSSL 0:d92f9d21154c 4351 if (anyError != 0 && ret == 0)
wolfSSL 0:d92f9d21154c 4352 ret = anyError;
wolfSSL 0:d92f9d21154c 4353
wolfSSL 0:d92f9d21154c 4354 if (ret != 0) {
wolfSSL 0:d92f9d21154c 4355 if (!ssl->options.verifyNone) {
wolfSSL 0:d92f9d21154c 4356 int why = bad_certificate;
wolfSSL 0:d92f9d21154c 4357
wolfSSL 0:d92f9d21154c 4358 if (ret == ASN_AFTER_DATE_E || ret == ASN_BEFORE_DATE_E)
wolfSSL 0:d92f9d21154c 4359 why = certificate_expired;
wolfSSL 0:d92f9d21154c 4360 if (ssl->verifyCallback) {
wolfSSL 0:d92f9d21154c 4361 int ok;
wolfSSL 0:d92f9d21154c 4362
wolfSSL 0:d92f9d21154c 4363 store->error = ret;
wolfSSL 0:d92f9d21154c 4364 store->error_depth = totalCerts;
wolfSSL 0:d92f9d21154c 4365 store->discardSessionCerts = 0;
wolfSSL 0:d92f9d21154c 4366 store->domain = domain;
wolfSSL 0:d92f9d21154c 4367 store->userCtx = ssl->verifyCbCtx;
wolfSSL 0:d92f9d21154c 4368 #ifdef KEEP_PEER_CERT
wolfSSL 0:d92f9d21154c 4369 store->current_cert = &ssl->peerCert;
wolfSSL 0:d92f9d21154c 4370 #else
wolfSSL 0:d92f9d21154c 4371 store->current_cert = NULL;
wolfSSL 0:d92f9d21154c 4372 #endif
wolfSSL 0:d92f9d21154c 4373 #ifdef FORTRESS
wolfSSL 0:d92f9d21154c 4374 store->ex_data = ssl;
wolfSSL 0:d92f9d21154c 4375 #endif
wolfSSL 0:d92f9d21154c 4376 ok = ssl->verifyCallback(0, store);
wolfSSL 0:d92f9d21154c 4377 if (ok) {
wolfSSL 0:d92f9d21154c 4378 WOLFSSL_MSG("Verify callback overriding error!");
wolfSSL 0:d92f9d21154c 4379 ret = 0;
wolfSSL 0:d92f9d21154c 4380 }
wolfSSL 0:d92f9d21154c 4381 #ifdef SESSION_CERTS
wolfSSL 0:d92f9d21154c 4382 if (store->discardSessionCerts) {
wolfSSL 0:d92f9d21154c 4383 WOLFSSL_MSG("Verify callback requested discard sess certs");
wolfSSL 0:d92f9d21154c 4384 ssl->session.chain.count = 0;
wolfSSL 0:d92f9d21154c 4385 }
wolfSSL 0:d92f9d21154c 4386 #endif
wolfSSL 0:d92f9d21154c 4387 }
wolfSSL 0:d92f9d21154c 4388 if (ret != 0) {
wolfSSL 0:d92f9d21154c 4389 SendAlert(ssl, alert_fatal, why); /* try to send */
wolfSSL 0:d92f9d21154c 4390 ssl->options.isClosed = 1;
wolfSSL 0:d92f9d21154c 4391 }
wolfSSL 0:d92f9d21154c 4392 }
wolfSSL 0:d92f9d21154c 4393 ssl->error = ret;
wolfSSL 0:d92f9d21154c 4394 }
wolfSSL 0:d92f9d21154c 4395 #ifdef WOLFSSL_ALWAYS_VERIFY_CB
wolfSSL 0:d92f9d21154c 4396 else {
wolfSSL 0:d92f9d21154c 4397 if (ssl->verifyCallback) {
wolfSSL 0:d92f9d21154c 4398 int ok;
wolfSSL 0:d92f9d21154c 4399
wolfSSL 0:d92f9d21154c 4400 store->error = ret;
wolfSSL 0:d92f9d21154c 4401 store->error_depth = totalCerts;
wolfSSL 0:d92f9d21154c 4402 store->discardSessionCerts = 0;
wolfSSL 0:d92f9d21154c 4403 store->domain = domain;
wolfSSL 0:d92f9d21154c 4404 store->userCtx = ssl->verifyCbCtx;
wolfSSL 0:d92f9d21154c 4405 #ifdef KEEP_PEER_CERT
wolfSSL 0:d92f9d21154c 4406 store->current_cert = &ssl->peerCert;
wolfSSL 0:d92f9d21154c 4407 #endif
wolfSSL 0:d92f9d21154c 4408 store->ex_data = ssl;
wolfSSL 0:d92f9d21154c 4409
wolfSSL 0:d92f9d21154c 4410 ok = ssl->verifyCallback(1, store);
wolfSSL 0:d92f9d21154c 4411 if (!ok) {
wolfSSL 0:d92f9d21154c 4412 WOLFSSL_MSG("Verify callback overriding valid certificate!");
wolfSSL 0:d92f9d21154c 4413 ret = -1;
wolfSSL 0:d92f9d21154c 4414 SendAlert(ssl, alert_fatal, bad_certificate);
wolfSSL 0:d92f9d21154c 4415 ssl->options.isClosed = 1;
wolfSSL 0:d92f9d21154c 4416 }
wolfSSL 0:d92f9d21154c 4417 #ifdef SESSION_CERTS
wolfSSL 0:d92f9d21154c 4418 if (store->discardSessionCerts) {
wolfSSL 0:d92f9d21154c 4419 WOLFSSL_MSG("Verify callback requested discard sess certs");
wolfSSL 0:d92f9d21154c 4420 ssl->session.chain.count = 0;
wolfSSL 0:d92f9d21154c 4421 }
wolfSSL 0:d92f9d21154c 4422 #endif
wolfSSL 0:d92f9d21154c 4423 }
wolfSSL 0:d92f9d21154c 4424 }
wolfSSL 0:d92f9d21154c 4425 #endif
wolfSSL 0:d92f9d21154c 4426
wolfSSL 0:d92f9d21154c 4427 if (ssl->options.verifyNone &&
wolfSSL 0:d92f9d21154c 4428 (ret == CRL_MISSING || ret == CRL_CERT_REVOKED)) {
wolfSSL 0:d92f9d21154c 4429 WOLFSSL_MSG("Ignoring CRL problem based on verify setting");
wolfSSL 0:d92f9d21154c 4430 ret = ssl->error = 0;
wolfSSL 0:d92f9d21154c 4431 }
wolfSSL 0:d92f9d21154c 4432
wolfSSL 0:d92f9d21154c 4433 if (ret == 0 && ssl->options.side == WOLFSSL_CLIENT_END)
wolfSSL 0:d92f9d21154c 4434 ssl->options.serverState = SERVER_CERT_COMPLETE;
wolfSSL 0:d92f9d21154c 4435
wolfSSL 0:d92f9d21154c 4436 if (ssl->keys.encryptionOn) {
wolfSSL 0:d92f9d21154c 4437 *inOutIdx += ssl->keys.padSz;
wolfSSL 0:d92f9d21154c 4438 }
wolfSSL 0:d92f9d21154c 4439
wolfSSL 0:d92f9d21154c 4440 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 4441 XFREE(store, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 4442 XFREE(domain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 4443 #endif
wolfSSL 0:d92f9d21154c 4444
wolfSSL 0:d92f9d21154c 4445 return ret;
wolfSSL 0:d92f9d21154c 4446 }
wolfSSL 0:d92f9d21154c 4447
wolfSSL 0:d92f9d21154c 4448 #endif /* !NO_CERTS */
wolfSSL 0:d92f9d21154c 4449
wolfSSL 0:d92f9d21154c 4450
wolfSSL 0:d92f9d21154c 4451 static int DoHelloRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
wolfSSL 0:d92f9d21154c 4452 word32 size, word32 totalSz)
wolfSSL 0:d92f9d21154c 4453 {
wolfSSL 0:d92f9d21154c 4454 (void)input;
wolfSSL 0:d92f9d21154c 4455
wolfSSL 0:d92f9d21154c 4456 if (size) /* must be 0 */
wolfSSL 0:d92f9d21154c 4457 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 4458
wolfSSL 0:d92f9d21154c 4459 if (ssl->keys.encryptionOn) {
wolfSSL 0:d92f9d21154c 4460 /* access beyond input + size should be checked against totalSz */
wolfSSL 0:d92f9d21154c 4461 if (*inOutIdx + ssl->keys.padSz > totalSz)
wolfSSL 0:d92f9d21154c 4462 return BUFFER_E;
wolfSSL 0:d92f9d21154c 4463
wolfSSL 0:d92f9d21154c 4464 *inOutIdx += ssl->keys.padSz;
wolfSSL 0:d92f9d21154c 4465 }
wolfSSL 0:d92f9d21154c 4466
wolfSSL 0:d92f9d21154c 4467 if (ssl->options.side == WOLFSSL_SERVER_END) {
wolfSSL 0:d92f9d21154c 4468 SendAlert(ssl, alert_fatal, unexpected_message); /* try */
wolfSSL 0:d92f9d21154c 4469 return FATAL_ERROR;
wolfSSL 0:d92f9d21154c 4470 }
wolfSSL 0:d92f9d21154c 4471 #ifdef HAVE_SECURE_RENEGOTIATION
wolfSSL 0:d92f9d21154c 4472 else if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled) {
wolfSSL 0:d92f9d21154c 4473 ssl->secure_renegotiation->startScr = 1;
wolfSSL 0:d92f9d21154c 4474 return 0;
wolfSSL 0:d92f9d21154c 4475 }
wolfSSL 0:d92f9d21154c 4476 #endif
wolfSSL 0:d92f9d21154c 4477 else {
wolfSSL 0:d92f9d21154c 4478 return SendAlert(ssl, alert_warning, no_renegotiation);
wolfSSL 0:d92f9d21154c 4479 }
wolfSSL 0:d92f9d21154c 4480 }
wolfSSL 0:d92f9d21154c 4481
wolfSSL 0:d92f9d21154c 4482
wolfSSL 0:d92f9d21154c 4483 int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size,
wolfSSL 0:d92f9d21154c 4484 word32 totalSz, int sniff)
wolfSSL 0:d92f9d21154c 4485 {
wolfSSL 0:d92f9d21154c 4486 word32 finishedSz = (ssl->options.tls ? TLS_FINISHED_SZ : FINISHED_SZ);
wolfSSL 0:d92f9d21154c 4487
wolfSSL 0:d92f9d21154c 4488 if (finishedSz != size)
wolfSSL 0:d92f9d21154c 4489 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 4490
wolfSSL 0:d92f9d21154c 4491 /* check against totalSz */
wolfSSL 0:d92f9d21154c 4492 if (*inOutIdx + size + ssl->keys.padSz > totalSz)
wolfSSL 0:d92f9d21154c 4493 return BUFFER_E;
wolfSSL 0:d92f9d21154c 4494
wolfSSL 0:d92f9d21154c 4495 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 4496 if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 4497 if (ssl->toInfoOn) AddLateName("Finished", &ssl->timeoutInfo);
wolfSSL 0:d92f9d21154c 4498 #endif
wolfSSL 0:d92f9d21154c 4499
wolfSSL 0:d92f9d21154c 4500 if (sniff == NO_SNIFF) {
wolfSSL 0:d92f9d21154c 4501 if (XMEMCMP(input + *inOutIdx, &ssl->hsHashes->verifyHashes,size) != 0){
wolfSSL 0:d92f9d21154c 4502 WOLFSSL_MSG("Verify finished error on hashes");
wolfSSL 0:d92f9d21154c 4503 return VERIFY_FINISHED_ERROR;
wolfSSL 0:d92f9d21154c 4504 }
wolfSSL 0:d92f9d21154c 4505 }
wolfSSL 0:d92f9d21154c 4506
wolfSSL 0:d92f9d21154c 4507 #ifdef HAVE_SECURE_RENEGOTIATION
wolfSSL 0:d92f9d21154c 4508 if (ssl->secure_renegotiation) {
wolfSSL 0:d92f9d21154c 4509 /* save peer's state */
wolfSSL 0:d92f9d21154c 4510 if (ssl->options.side == WOLFSSL_CLIENT_END)
wolfSSL 0:d92f9d21154c 4511 XMEMCPY(ssl->secure_renegotiation->server_verify_data,
wolfSSL 0:d92f9d21154c 4512 input + *inOutIdx, TLS_FINISHED_SZ);
wolfSSL 0:d92f9d21154c 4513 else
wolfSSL 0:d92f9d21154c 4514 XMEMCPY(ssl->secure_renegotiation->client_verify_data,
wolfSSL 0:d92f9d21154c 4515 input + *inOutIdx, TLS_FINISHED_SZ);
wolfSSL 0:d92f9d21154c 4516 }
wolfSSL 0:d92f9d21154c 4517 #endif
wolfSSL 0:d92f9d21154c 4518
wolfSSL 0:d92f9d21154c 4519 /* force input exhaustion at ProcessReply consuming padSz */
wolfSSL 0:d92f9d21154c 4520 *inOutIdx += size + ssl->keys.padSz;
wolfSSL 0:d92f9d21154c 4521
wolfSSL 0:d92f9d21154c 4522 if (ssl->options.side == WOLFSSL_CLIENT_END) {
wolfSSL 0:d92f9d21154c 4523 ssl->options.serverState = SERVER_FINISHED_COMPLETE;
wolfSSL 0:d92f9d21154c 4524 if (!ssl->options.resuming) {
wolfSSL 0:d92f9d21154c 4525 ssl->options.handShakeState = HANDSHAKE_DONE;
wolfSSL 0:d92f9d21154c 4526 ssl->options.handShakeDone = 1;
wolfSSL 0:d92f9d21154c 4527
wolfSSL 0:d92f9d21154c 4528 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 4529 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 4530 /* Other side has received our Finished, go to next epoch */
wolfSSL 0:d92f9d21154c 4531 ssl->keys.dtls_epoch++;
wolfSSL 0:d92f9d21154c 4532 ssl->keys.dtls_sequence_number = 1;
wolfSSL 0:d92f9d21154c 4533 }
wolfSSL 0:d92f9d21154c 4534 #endif
wolfSSL 0:d92f9d21154c 4535 }
wolfSSL 0:d92f9d21154c 4536 }
wolfSSL 0:d92f9d21154c 4537 else {
wolfSSL 0:d92f9d21154c 4538 ssl->options.clientState = CLIENT_FINISHED_COMPLETE;
wolfSSL 0:d92f9d21154c 4539 if (ssl->options.resuming) {
wolfSSL 0:d92f9d21154c 4540 ssl->options.handShakeState = HANDSHAKE_DONE;
wolfSSL 0:d92f9d21154c 4541 ssl->options.handShakeDone = 1;
wolfSSL 0:d92f9d21154c 4542
wolfSSL 0:d92f9d21154c 4543 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 4544 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 4545 /* Other side has received our Finished, go to next epoch */
wolfSSL 0:d92f9d21154c 4546 ssl->keys.dtls_epoch++;
wolfSSL 0:d92f9d21154c 4547 ssl->keys.dtls_sequence_number = 1;
wolfSSL 0:d92f9d21154c 4548 }
wolfSSL 0:d92f9d21154c 4549 #endif
wolfSSL 0:d92f9d21154c 4550 }
wolfSSL 0:d92f9d21154c 4551 }
wolfSSL 0:d92f9d21154c 4552
wolfSSL 0:d92f9d21154c 4553 return 0;
wolfSSL 0:d92f9d21154c 4554 }
wolfSSL 0:d92f9d21154c 4555
wolfSSL 0:d92f9d21154c 4556
wolfSSL 0:d92f9d21154c 4557 /* Make sure no duplicates, no fast forward, or other problems; 0 on success */
wolfSSL 0:d92f9d21154c 4558 static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
wolfSSL 0:d92f9d21154c 4559 {
wolfSSL 0:d92f9d21154c 4560 /* verify not a duplicate, mark received, check state */
wolfSSL 0:d92f9d21154c 4561 switch (type) {
wolfSSL 0:d92f9d21154c 4562
wolfSSL 0:d92f9d21154c 4563 #ifndef NO_WOLFSSL_CLIENT
wolfSSL 0:d92f9d21154c 4564 case hello_request:
wolfSSL 0:d92f9d21154c 4565 if (ssl->msgsReceived.got_hello_request) {
wolfSSL 0:d92f9d21154c 4566 WOLFSSL_MSG("Duplicate HelloRequest received");
wolfSSL 0:d92f9d21154c 4567 return DUPLICATE_MSG_E;
wolfSSL 0:d92f9d21154c 4568 }
wolfSSL 0:d92f9d21154c 4569 ssl->msgsReceived.got_hello_request = 1;
wolfSSL 0:d92f9d21154c 4570
wolfSSL 0:d92f9d21154c 4571 break;
wolfSSL 0:d92f9d21154c 4572 #endif
wolfSSL 0:d92f9d21154c 4573
wolfSSL 0:d92f9d21154c 4574 #ifndef NO_WOLFSSL_SERVER
wolfSSL 0:d92f9d21154c 4575 case client_hello:
wolfSSL 0:d92f9d21154c 4576 if (ssl->msgsReceived.got_client_hello) {
wolfSSL 0:d92f9d21154c 4577 WOLFSSL_MSG("Duplicate ClientHello received");
wolfSSL 0:d92f9d21154c 4578 return DUPLICATE_MSG_E;
wolfSSL 0:d92f9d21154c 4579 }
wolfSSL 0:d92f9d21154c 4580 ssl->msgsReceived.got_client_hello = 1;
wolfSSL 0:d92f9d21154c 4581
wolfSSL 0:d92f9d21154c 4582 break;
wolfSSL 0:d92f9d21154c 4583 #endif
wolfSSL 0:d92f9d21154c 4584
wolfSSL 0:d92f9d21154c 4585 #ifndef NO_WOLFSSL_CLIENT
wolfSSL 0:d92f9d21154c 4586 case server_hello:
wolfSSL 0:d92f9d21154c 4587 if (ssl->msgsReceived.got_server_hello) {
wolfSSL 0:d92f9d21154c 4588 WOLFSSL_MSG("Duplicate ServerHello received");
wolfSSL 0:d92f9d21154c 4589 return DUPLICATE_MSG_E;
wolfSSL 0:d92f9d21154c 4590 }
wolfSSL 0:d92f9d21154c 4591 ssl->msgsReceived.got_server_hello = 1;
wolfSSL 0:d92f9d21154c 4592
wolfSSL 0:d92f9d21154c 4593 break;
wolfSSL 0:d92f9d21154c 4594 #endif
wolfSSL 0:d92f9d21154c 4595
wolfSSL 0:d92f9d21154c 4596 #ifndef NO_WOLFSSL_CLIENT
wolfSSL 0:d92f9d21154c 4597 case hello_verify_request:
wolfSSL 0:d92f9d21154c 4598 if (ssl->msgsReceived.got_hello_verify_request) {
wolfSSL 0:d92f9d21154c 4599 WOLFSSL_MSG("Duplicate HelloVerifyRequest received");
wolfSSL 0:d92f9d21154c 4600 return DUPLICATE_MSG_E;
wolfSSL 0:d92f9d21154c 4601 }
wolfSSL 0:d92f9d21154c 4602 ssl->msgsReceived.got_hello_verify_request = 1;
wolfSSL 0:d92f9d21154c 4603
wolfSSL 0:d92f9d21154c 4604 break;
wolfSSL 0:d92f9d21154c 4605 #endif
wolfSSL 0:d92f9d21154c 4606
wolfSSL 0:d92f9d21154c 4607 #ifndef NO_WOLFSSL_CLIENT
wolfSSL 0:d92f9d21154c 4608 case session_ticket:
wolfSSL 0:d92f9d21154c 4609 if (ssl->msgsReceived.got_session_ticket) {
wolfSSL 0:d92f9d21154c 4610 WOLFSSL_MSG("Duplicate SessionTicket received");
wolfSSL 0:d92f9d21154c 4611 return DUPLICATE_MSG_E;
wolfSSL 0:d92f9d21154c 4612 }
wolfSSL 0:d92f9d21154c 4613 ssl->msgsReceived.got_session_ticket = 1;
wolfSSL 0:d92f9d21154c 4614
wolfSSL 0:d92f9d21154c 4615 break;
wolfSSL 0:d92f9d21154c 4616 #endif
wolfSSL 0:d92f9d21154c 4617
wolfSSL 0:d92f9d21154c 4618 case certificate:
wolfSSL 0:d92f9d21154c 4619 if (ssl->msgsReceived.got_certificate) {
wolfSSL 0:d92f9d21154c 4620 WOLFSSL_MSG("Duplicate Certificate received");
wolfSSL 0:d92f9d21154c 4621 return DUPLICATE_MSG_E;
wolfSSL 0:d92f9d21154c 4622 }
wolfSSL 0:d92f9d21154c 4623 ssl->msgsReceived.got_certificate = 1;
wolfSSL 0:d92f9d21154c 4624
wolfSSL 0:d92f9d21154c 4625 #ifndef NO_WOLFSSL_CLIENT
wolfSSL 0:d92f9d21154c 4626 if (ssl->options.side == WOLFSSL_CLIENT_END) {
wolfSSL 0:d92f9d21154c 4627 if ( ssl->msgsReceived.got_server_hello == 0) {
wolfSSL 0:d92f9d21154c 4628 WOLFSSL_MSG("No ServerHello before Cert");
wolfSSL 0:d92f9d21154c 4629 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 4630 }
wolfSSL 0:d92f9d21154c 4631 }
wolfSSL 0:d92f9d21154c 4632 #endif
wolfSSL 0:d92f9d21154c 4633 #ifndef NO_WOLFSSL_SERVER
wolfSSL 0:d92f9d21154c 4634 if (ssl->options.side == WOLFSSL_SERVER_END) {
wolfSSL 0:d92f9d21154c 4635 if ( ssl->msgsReceived.got_client_hello == 0) {
wolfSSL 0:d92f9d21154c 4636 WOLFSSL_MSG("No ClientHello before Cert");
wolfSSL 0:d92f9d21154c 4637 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 4638 }
wolfSSL 0:d92f9d21154c 4639 }
wolfSSL 0:d92f9d21154c 4640 #endif
wolfSSL 0:d92f9d21154c 4641 break;
wolfSSL 0:d92f9d21154c 4642
wolfSSL 0:d92f9d21154c 4643 #ifndef NO_WOLFSSL_CLIENT
wolfSSL 0:d92f9d21154c 4644 case server_key_exchange:
wolfSSL 0:d92f9d21154c 4645 if (ssl->msgsReceived.got_server_key_exchange) {
wolfSSL 0:d92f9d21154c 4646 WOLFSSL_MSG("Duplicate ServerKeyExchange received");
wolfSSL 0:d92f9d21154c 4647 return DUPLICATE_MSG_E;
wolfSSL 0:d92f9d21154c 4648 }
wolfSSL 0:d92f9d21154c 4649 ssl->msgsReceived.got_server_key_exchange = 1;
wolfSSL 0:d92f9d21154c 4650
wolfSSL 0:d92f9d21154c 4651 if ( ssl->msgsReceived.got_server_hello == 0) {
wolfSSL 0:d92f9d21154c 4652 WOLFSSL_MSG("No ServerHello before Cert");
wolfSSL 0:d92f9d21154c 4653 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 4654 }
wolfSSL 0:d92f9d21154c 4655
wolfSSL 0:d92f9d21154c 4656 break;
wolfSSL 0:d92f9d21154c 4657 #endif
wolfSSL 0:d92f9d21154c 4658
wolfSSL 0:d92f9d21154c 4659 #ifndef NO_WOLFSSL_CLIENT
wolfSSL 0:d92f9d21154c 4660 case certificate_request:
wolfSSL 0:d92f9d21154c 4661 if (ssl->msgsReceived.got_certificate_request) {
wolfSSL 0:d92f9d21154c 4662 WOLFSSL_MSG("Duplicate CertificateRequest received");
wolfSSL 0:d92f9d21154c 4663 return DUPLICATE_MSG_E;
wolfSSL 0:d92f9d21154c 4664 }
wolfSSL 0:d92f9d21154c 4665 ssl->msgsReceived.got_certificate_request = 1;
wolfSSL 0:d92f9d21154c 4666
wolfSSL 0:d92f9d21154c 4667 break;
wolfSSL 0:d92f9d21154c 4668 #endif
wolfSSL 0:d92f9d21154c 4669
wolfSSL 0:d92f9d21154c 4670 #ifndef NO_WOLFSSL_CLIENT
wolfSSL 0:d92f9d21154c 4671 case server_hello_done:
wolfSSL 0:d92f9d21154c 4672 if (ssl->msgsReceived.got_server_hello_done) {
wolfSSL 0:d92f9d21154c 4673 WOLFSSL_MSG("Duplicate ServerHelloDone received");
wolfSSL 0:d92f9d21154c 4674 return DUPLICATE_MSG_E;
wolfSSL 0:d92f9d21154c 4675 }
wolfSSL 0:d92f9d21154c 4676 ssl->msgsReceived.got_server_hello_done = 1;
wolfSSL 0:d92f9d21154c 4677
wolfSSL 0:d92f9d21154c 4678 if (ssl->msgsReceived.got_certificate == 0) {
wolfSSL 0:d92f9d21154c 4679 if (ssl->specs.kea == psk_kea ||
wolfSSL 0:d92f9d21154c 4680 ssl->specs.kea == dhe_psk_kea ||
wolfSSL 0:d92f9d21154c 4681 ssl->options.usingAnon_cipher) {
wolfSSL 0:d92f9d21154c 4682 WOLFSSL_MSG("No Cert required");
wolfSSL 0:d92f9d21154c 4683 } else {
wolfSSL 0:d92f9d21154c 4684 WOLFSSL_MSG("No Certificate before ServerHelloDone");
wolfSSL 0:d92f9d21154c 4685 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 4686 }
wolfSSL 0:d92f9d21154c 4687 }
wolfSSL 0:d92f9d21154c 4688 if (ssl->msgsReceived.got_server_key_exchange == 0) {
wolfSSL 0:d92f9d21154c 4689 if (ssl->specs.static_ecdh == 1 ||
wolfSSL 0:d92f9d21154c 4690 ssl->specs.kea == rsa_kea ||
wolfSSL 0:d92f9d21154c 4691 ssl->specs.kea == ntru_kea) {
wolfSSL 0:d92f9d21154c 4692 WOLFSSL_MSG("No KeyExchange required");
wolfSSL 0:d92f9d21154c 4693 } else {
wolfSSL 0:d92f9d21154c 4694 WOLFSSL_MSG("No ServerKeyExchange before ServerDone");
wolfSSL 0:d92f9d21154c 4695 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 4696 }
wolfSSL 0:d92f9d21154c 4697 }
wolfSSL 0:d92f9d21154c 4698 break;
wolfSSL 0:d92f9d21154c 4699 #endif
wolfSSL 0:d92f9d21154c 4700
wolfSSL 0:d92f9d21154c 4701 #ifndef NO_WOLFSSL_SERVER
wolfSSL 0:d92f9d21154c 4702 case certificate_verify:
wolfSSL 0:d92f9d21154c 4703 if (ssl->msgsReceived.got_certificate_verify) {
wolfSSL 0:d92f9d21154c 4704 WOLFSSL_MSG("Duplicate CertificateVerify received");
wolfSSL 0:d92f9d21154c 4705 return DUPLICATE_MSG_E;
wolfSSL 0:d92f9d21154c 4706 }
wolfSSL 0:d92f9d21154c 4707 ssl->msgsReceived.got_certificate_verify = 1;
wolfSSL 0:d92f9d21154c 4708
wolfSSL 0:d92f9d21154c 4709 if ( ssl->msgsReceived.got_certificate == 0) {
wolfSSL 0:d92f9d21154c 4710 WOLFSSL_MSG("No Cert before CertVerify");
wolfSSL 0:d92f9d21154c 4711 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 4712 }
wolfSSL 0:d92f9d21154c 4713 break;
wolfSSL 0:d92f9d21154c 4714 #endif
wolfSSL 0:d92f9d21154c 4715
wolfSSL 0:d92f9d21154c 4716 #ifndef NO_WOLFSSL_SERVER
wolfSSL 0:d92f9d21154c 4717 case client_key_exchange:
wolfSSL 0:d92f9d21154c 4718 if (ssl->msgsReceived.got_client_key_exchange) {
wolfSSL 0:d92f9d21154c 4719 WOLFSSL_MSG("Duplicate ClientKeyExchange received");
wolfSSL 0:d92f9d21154c 4720 return DUPLICATE_MSG_E;
wolfSSL 0:d92f9d21154c 4721 }
wolfSSL 0:d92f9d21154c 4722 ssl->msgsReceived.got_client_key_exchange = 1;
wolfSSL 0:d92f9d21154c 4723
wolfSSL 0:d92f9d21154c 4724 if (ssl->msgsReceived.got_client_hello == 0) {
wolfSSL 0:d92f9d21154c 4725 WOLFSSL_MSG("No ClientHello before ClientKeyExchange");
wolfSSL 0:d92f9d21154c 4726 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 4727 }
wolfSSL 0:d92f9d21154c 4728 break;
wolfSSL 0:d92f9d21154c 4729 #endif
wolfSSL 0:d92f9d21154c 4730
wolfSSL 0:d92f9d21154c 4731 case finished:
wolfSSL 0:d92f9d21154c 4732 if (ssl->msgsReceived.got_finished) {
wolfSSL 0:d92f9d21154c 4733 WOLFSSL_MSG("Duplicate Finished received");
wolfSSL 0:d92f9d21154c 4734 return DUPLICATE_MSG_E;
wolfSSL 0:d92f9d21154c 4735 }
wolfSSL 0:d92f9d21154c 4736 ssl->msgsReceived.got_finished = 1;
wolfSSL 0:d92f9d21154c 4737
wolfSSL 0:d92f9d21154c 4738 if (ssl->msgsReceived.got_change_cipher == 0) {
wolfSSL 0:d92f9d21154c 4739 WOLFSSL_MSG("Finished received before ChangeCipher");
wolfSSL 0:d92f9d21154c 4740 return NO_CHANGE_CIPHER_E;
wolfSSL 0:d92f9d21154c 4741 }
wolfSSL 0:d92f9d21154c 4742
wolfSSL 0:d92f9d21154c 4743 break;
wolfSSL 0:d92f9d21154c 4744
wolfSSL 0:d92f9d21154c 4745 case change_cipher_hs:
wolfSSL 0:d92f9d21154c 4746 if (ssl->msgsReceived.got_change_cipher) {
wolfSSL 0:d92f9d21154c 4747 WOLFSSL_MSG("Duplicate ChangeCipher received");
wolfSSL 0:d92f9d21154c 4748 return DUPLICATE_MSG_E;
wolfSSL 0:d92f9d21154c 4749 }
wolfSSL 0:d92f9d21154c 4750 ssl->msgsReceived.got_change_cipher = 1;
wolfSSL 0:d92f9d21154c 4751
wolfSSL 0:d92f9d21154c 4752 #ifndef NO_WOLFSSL_CLIENT
wolfSSL 0:d92f9d21154c 4753 if (ssl->options.side == WOLFSSL_CLIENT_END) {
wolfSSL 0:d92f9d21154c 4754 if (!ssl->options.resuming &&
wolfSSL 0:d92f9d21154c 4755 ssl->msgsReceived.got_server_hello_done == 0) {
wolfSSL 0:d92f9d21154c 4756 WOLFSSL_MSG("No ServerHelloDone before ChangeCipher");
wolfSSL 0:d92f9d21154c 4757 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 4758 }
wolfSSL 0:d92f9d21154c 4759 }
wolfSSL 0:d92f9d21154c 4760 #endif
wolfSSL 0:d92f9d21154c 4761 #ifndef NO_WOLFSSL_SERVER
wolfSSL 0:d92f9d21154c 4762 if (ssl->options.side == WOLFSSL_SERVER_END) {
wolfSSL 0:d92f9d21154c 4763 if (!ssl->options.resuming &&
wolfSSL 0:d92f9d21154c 4764 ssl->msgsReceived.got_client_key_exchange == 0) {
wolfSSL 0:d92f9d21154c 4765 WOLFSSL_MSG("No ClientKeyExchange before ChangeCipher");
wolfSSL 0:d92f9d21154c 4766 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 4767 }
wolfSSL 0:d92f9d21154c 4768 }
wolfSSL 0:d92f9d21154c 4769 #endif
wolfSSL 0:d92f9d21154c 4770
wolfSSL 0:d92f9d21154c 4771 break;
wolfSSL 0:d92f9d21154c 4772
wolfSSL 0:d92f9d21154c 4773 default:
wolfSSL 0:d92f9d21154c 4774 WOLFSSL_MSG("Unknown message type");
wolfSSL 0:d92f9d21154c 4775 return SANITY_MSG_E;
wolfSSL 0:d92f9d21154c 4776 }
wolfSSL 0:d92f9d21154c 4777
wolfSSL 0:d92f9d21154c 4778 return 0;
wolfSSL 0:d92f9d21154c 4779 }
wolfSSL 0:d92f9d21154c 4780
wolfSSL 0:d92f9d21154c 4781
wolfSSL 0:d92f9d21154c 4782 static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
wolfSSL 0:d92f9d21154c 4783 byte type, word32 size, word32 totalSz)
wolfSSL 0:d92f9d21154c 4784 {
wolfSSL 0:d92f9d21154c 4785 int ret = 0;
wolfSSL 0:d92f9d21154c 4786 (void)totalSz;
wolfSSL 0:d92f9d21154c 4787
wolfSSL 0:d92f9d21154c 4788 WOLFSSL_ENTER("DoHandShakeMsgType");
wolfSSL 0:d92f9d21154c 4789
wolfSSL 0:d92f9d21154c 4790 /* make sure can read the message */
wolfSSL 0:d92f9d21154c 4791 if (*inOutIdx + size > totalSz)
wolfSSL 0:d92f9d21154c 4792 return INCOMPLETE_DATA;
wolfSSL 0:d92f9d21154c 4793
wolfSSL 0:d92f9d21154c 4794 /* sanity check msg received */
wolfSSL 0:d92f9d21154c 4795 if ( (ret = SanityCheckMsgReceived(ssl, type)) != 0) {
wolfSSL 0:d92f9d21154c 4796 WOLFSSL_MSG("Sanity Check on handshake message type received failed");
wolfSSL 0:d92f9d21154c 4797 return ret;
wolfSSL 0:d92f9d21154c 4798 }
wolfSSL 0:d92f9d21154c 4799
wolfSSL 0:d92f9d21154c 4800 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 4801 /* add name later, add on record and handshake header part back on */
wolfSSL 0:d92f9d21154c 4802 if (ssl->toInfoOn) {
wolfSSL 0:d92f9d21154c 4803 int add = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 4804 AddPacketInfo(0, &ssl->timeoutInfo, input + *inOutIdx - add,
wolfSSL 0:d92f9d21154c 4805 size + add, ssl->heap);
wolfSSL 0:d92f9d21154c 4806 AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
wolfSSL 0:d92f9d21154c 4807 }
wolfSSL 0:d92f9d21154c 4808 #endif
wolfSSL 0:d92f9d21154c 4809
wolfSSL 0:d92f9d21154c 4810 if (ssl->options.handShakeState == HANDSHAKE_DONE && type != hello_request){
wolfSSL 0:d92f9d21154c 4811 WOLFSSL_MSG("HandShake message after handshake complete");
wolfSSL 0:d92f9d21154c 4812 SendAlert(ssl, alert_fatal, unexpected_message);
wolfSSL 0:d92f9d21154c 4813 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 4814 }
wolfSSL 0:d92f9d21154c 4815
wolfSSL 0:d92f9d21154c 4816 if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls == 0 &&
wolfSSL 0:d92f9d21154c 4817 ssl->options.serverState == NULL_STATE && type != server_hello) {
wolfSSL 0:d92f9d21154c 4818 WOLFSSL_MSG("First server message not server hello");
wolfSSL 0:d92f9d21154c 4819 SendAlert(ssl, alert_fatal, unexpected_message);
wolfSSL 0:d92f9d21154c 4820 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 4821 }
wolfSSL 0:d92f9d21154c 4822
wolfSSL 0:d92f9d21154c 4823 if (ssl->options.side == WOLFSSL_CLIENT_END && ssl->options.dtls &&
wolfSSL 0:d92f9d21154c 4824 type == server_hello_done &&
wolfSSL 0:d92f9d21154c 4825 ssl->options.serverState < SERVER_HELLO_COMPLETE) {
wolfSSL 0:d92f9d21154c 4826 WOLFSSL_MSG("Server hello done received before server hello in DTLS");
wolfSSL 0:d92f9d21154c 4827 SendAlert(ssl, alert_fatal, unexpected_message);
wolfSSL 0:d92f9d21154c 4828 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 4829 }
wolfSSL 0:d92f9d21154c 4830
wolfSSL 0:d92f9d21154c 4831 if (ssl->options.side == WOLFSSL_SERVER_END &&
wolfSSL 0:d92f9d21154c 4832 ssl->options.clientState == NULL_STATE && type != client_hello) {
wolfSSL 0:d92f9d21154c 4833 WOLFSSL_MSG("First client message not client hello");
wolfSSL 0:d92f9d21154c 4834 SendAlert(ssl, alert_fatal, unexpected_message);
wolfSSL 0:d92f9d21154c 4835 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 4836 }
wolfSSL 0:d92f9d21154c 4837
wolfSSL 0:d92f9d21154c 4838 /* above checks handshake state */
wolfSSL 0:d92f9d21154c 4839 /* hello_request not hashed */
wolfSSL 0:d92f9d21154c 4840 if (type != hello_request) {
wolfSSL 0:d92f9d21154c 4841 ret = HashInput(ssl, input + *inOutIdx, size);
wolfSSL 0:d92f9d21154c 4842 if (ret != 0) return ret;
wolfSSL 0:d92f9d21154c 4843 }
wolfSSL 0:d92f9d21154c 4844
wolfSSL 0:d92f9d21154c 4845 switch (type) {
wolfSSL 0:d92f9d21154c 4846
wolfSSL 0:d92f9d21154c 4847 case hello_request:
wolfSSL 0:d92f9d21154c 4848 WOLFSSL_MSG("processing hello request");
wolfSSL 0:d92f9d21154c 4849 ret = DoHelloRequest(ssl, input, inOutIdx, size, totalSz);
wolfSSL 0:d92f9d21154c 4850 break;
wolfSSL 0:d92f9d21154c 4851
wolfSSL 0:d92f9d21154c 4852 #ifndef NO_WOLFSSL_CLIENT
wolfSSL 0:d92f9d21154c 4853 case hello_verify_request:
wolfSSL 0:d92f9d21154c 4854 WOLFSSL_MSG("processing hello verify request");
wolfSSL 0:d92f9d21154c 4855 ret = DoHelloVerifyRequest(ssl, input,inOutIdx, size);
wolfSSL 0:d92f9d21154c 4856 break;
wolfSSL 0:d92f9d21154c 4857
wolfSSL 0:d92f9d21154c 4858 case server_hello:
wolfSSL 0:d92f9d21154c 4859 WOLFSSL_MSG("processing server hello");
wolfSSL 0:d92f9d21154c 4860 ret = DoServerHello(ssl, input, inOutIdx, size);
wolfSSL 0:d92f9d21154c 4861 break;
wolfSSL 0:d92f9d21154c 4862
wolfSSL 0:d92f9d21154c 4863 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 4864 case certificate_request:
wolfSSL 0:d92f9d21154c 4865 WOLFSSL_MSG("processing certificate request");
wolfSSL 0:d92f9d21154c 4866 ret = DoCertificateRequest(ssl, input, inOutIdx, size);
wolfSSL 0:d92f9d21154c 4867 break;
wolfSSL 0:d92f9d21154c 4868 #endif
wolfSSL 0:d92f9d21154c 4869
wolfSSL 0:d92f9d21154c 4870 case server_key_exchange:
wolfSSL 0:d92f9d21154c 4871 WOLFSSL_MSG("processing server key exchange");
wolfSSL 0:d92f9d21154c 4872 ret = DoServerKeyExchange(ssl, input, inOutIdx, size);
wolfSSL 0:d92f9d21154c 4873 break;
wolfSSL 0:d92f9d21154c 4874
wolfSSL 0:d92f9d21154c 4875 #ifdef HAVE_SESSION_TICKET
wolfSSL 0:d92f9d21154c 4876 case session_ticket:
wolfSSL 0:d92f9d21154c 4877 WOLFSSL_MSG("processing session ticket");
wolfSSL 0:d92f9d21154c 4878 ret = DoSessionTicket(ssl, input, inOutIdx, size);
wolfSSL 0:d92f9d21154c 4879 break;
wolfSSL 0:d92f9d21154c 4880 #endif /* HAVE_SESSION_TICKET */
wolfSSL 0:d92f9d21154c 4881 #endif
wolfSSL 0:d92f9d21154c 4882
wolfSSL 0:d92f9d21154c 4883 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 4884 case certificate:
wolfSSL 0:d92f9d21154c 4885 WOLFSSL_MSG("processing certificate");
wolfSSL 0:d92f9d21154c 4886 ret = DoCertificate(ssl, input, inOutIdx, size);
wolfSSL 0:d92f9d21154c 4887 break;
wolfSSL 0:d92f9d21154c 4888 #endif
wolfSSL 0:d92f9d21154c 4889
wolfSSL 0:d92f9d21154c 4890 case server_hello_done:
wolfSSL 0:d92f9d21154c 4891 WOLFSSL_MSG("processing server hello done");
wolfSSL 0:d92f9d21154c 4892 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 4893 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 4894 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 4895 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 4896 AddLateName("ServerHelloDone", &ssl->timeoutInfo);
wolfSSL 0:d92f9d21154c 4897 #endif
wolfSSL 0:d92f9d21154c 4898 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
wolfSSL 0:d92f9d21154c 4899 if (ssl->keys.encryptionOn) {
wolfSSL 0:d92f9d21154c 4900 *inOutIdx += ssl->keys.padSz;
wolfSSL 0:d92f9d21154c 4901 }
wolfSSL 0:d92f9d21154c 4902 if (ssl->options.resuming) {
wolfSSL 0:d92f9d21154c 4903 WOLFSSL_MSG("Not resuming as thought");
wolfSSL 0:d92f9d21154c 4904 ssl->options.resuming = 0;
wolfSSL 0:d92f9d21154c 4905 }
wolfSSL 0:d92f9d21154c 4906 break;
wolfSSL 0:d92f9d21154c 4907
wolfSSL 0:d92f9d21154c 4908 case finished:
wolfSSL 0:d92f9d21154c 4909 WOLFSSL_MSG("processing finished");
wolfSSL 0:d92f9d21154c 4910 ret = DoFinished(ssl, input, inOutIdx, size, totalSz, NO_SNIFF);
wolfSSL 0:d92f9d21154c 4911 break;
wolfSSL 0:d92f9d21154c 4912
wolfSSL 0:d92f9d21154c 4913 #ifndef NO_WOLFSSL_SERVER
wolfSSL 0:d92f9d21154c 4914 case client_hello:
wolfSSL 0:d92f9d21154c 4915 WOLFSSL_MSG("processing client hello");
wolfSSL 0:d92f9d21154c 4916 ret = DoClientHello(ssl, input, inOutIdx, size);
wolfSSL 0:d92f9d21154c 4917 break;
wolfSSL 0:d92f9d21154c 4918
wolfSSL 0:d92f9d21154c 4919 case client_key_exchange:
wolfSSL 0:d92f9d21154c 4920 WOLFSSL_MSG("processing client key exchange");
wolfSSL 0:d92f9d21154c 4921 ret = DoClientKeyExchange(ssl, input, inOutIdx, size);
wolfSSL 0:d92f9d21154c 4922 break;
wolfSSL 0:d92f9d21154c 4923
wolfSSL 0:d92f9d21154c 4924 #if !defined(NO_RSA) || defined(HAVE_ECC)
wolfSSL 0:d92f9d21154c 4925 case certificate_verify:
wolfSSL 0:d92f9d21154c 4926 WOLFSSL_MSG("processing certificate verify");
wolfSSL 0:d92f9d21154c 4927 ret = DoCertificateVerify(ssl, input, inOutIdx, size);
wolfSSL 0:d92f9d21154c 4928 break;
wolfSSL 0:d92f9d21154c 4929 #endif /* !NO_RSA || HAVE_ECC */
wolfSSL 0:d92f9d21154c 4930
wolfSSL 0:d92f9d21154c 4931 #endif /* !NO_WOLFSSL_SERVER */
wolfSSL 0:d92f9d21154c 4932
wolfSSL 0:d92f9d21154c 4933 default:
wolfSSL 0:d92f9d21154c 4934 WOLFSSL_MSG("Unknown handshake message type");
wolfSSL 0:d92f9d21154c 4935 ret = UNKNOWN_HANDSHAKE_TYPE;
wolfSSL 0:d92f9d21154c 4936 break;
wolfSSL 0:d92f9d21154c 4937 }
wolfSSL 0:d92f9d21154c 4938
wolfSSL 0:d92f9d21154c 4939 WOLFSSL_LEAVE("DoHandShakeMsgType()", ret);
wolfSSL 0:d92f9d21154c 4940 return ret;
wolfSSL 0:d92f9d21154c 4941 }
wolfSSL 0:d92f9d21154c 4942
wolfSSL 0:d92f9d21154c 4943
wolfSSL 0:d92f9d21154c 4944 static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
wolfSSL 0:d92f9d21154c 4945 word32 totalSz)
wolfSSL 0:d92f9d21154c 4946 {
wolfSSL 0:d92f9d21154c 4947 byte type;
wolfSSL 0:d92f9d21154c 4948 word32 size;
wolfSSL 0:d92f9d21154c 4949 int ret = 0;
wolfSSL 0:d92f9d21154c 4950
wolfSSL 0:d92f9d21154c 4951 WOLFSSL_ENTER("DoHandShakeMsg()");
wolfSSL 0:d92f9d21154c 4952
wolfSSL 0:d92f9d21154c 4953 if (GetHandShakeHeader(ssl, input, inOutIdx, &type, &size, totalSz) != 0)
wolfSSL 0:d92f9d21154c 4954 return PARSE_ERROR;
wolfSSL 0:d92f9d21154c 4955
wolfSSL 0:d92f9d21154c 4956 ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
wolfSSL 0:d92f9d21154c 4957
wolfSSL 0:d92f9d21154c 4958 WOLFSSL_LEAVE("DoHandShakeMsg()", ret);
wolfSSL 0:d92f9d21154c 4959 return ret;
wolfSSL 0:d92f9d21154c 4960 }
wolfSSL 0:d92f9d21154c 4961
wolfSSL 0:d92f9d21154c 4962
wolfSSL 0:d92f9d21154c 4963 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 4964
wolfSSL 0:d92f9d21154c 4965 static INLINE int DtlsCheckWindow(DtlsState* state)
wolfSSL 0:d92f9d21154c 4966 {
wolfSSL 0:d92f9d21154c 4967 word32 cur;
wolfSSL 0:d92f9d21154c 4968 word32 next;
wolfSSL 0:d92f9d21154c 4969 DtlsSeq window;
wolfSSL 0:d92f9d21154c 4970
wolfSSL 0:d92f9d21154c 4971 if (state->curEpoch == state->nextEpoch) {
wolfSSL 0:d92f9d21154c 4972 next = state->nextSeq;
wolfSSL 0:d92f9d21154c 4973 window = state->window;
wolfSSL 0:d92f9d21154c 4974 }
wolfSSL 0:d92f9d21154c 4975 else if (state->curEpoch < state->nextEpoch) {
wolfSSL 0:d92f9d21154c 4976 next = state->prevSeq;
wolfSSL 0:d92f9d21154c 4977 window = state->prevWindow;
wolfSSL 0:d92f9d21154c 4978 }
wolfSSL 0:d92f9d21154c 4979 else {
wolfSSL 0:d92f9d21154c 4980 return 0;
wolfSSL 0:d92f9d21154c 4981 }
wolfSSL 0:d92f9d21154c 4982
wolfSSL 0:d92f9d21154c 4983 cur = state->curSeq;
wolfSSL 0:d92f9d21154c 4984
wolfSSL 0:d92f9d21154c 4985 if ((next > DTLS_SEQ_BITS) && (cur < next - DTLS_SEQ_BITS)) {
wolfSSL 0:d92f9d21154c 4986 return 0;
wolfSSL 0:d92f9d21154c 4987 }
wolfSSL 0:d92f9d21154c 4988 else if ((cur < next) && (window & ((DtlsSeq)1 << (next - cur - 1)))) {
wolfSSL 0:d92f9d21154c 4989 return 0;
wolfSSL 0:d92f9d21154c 4990 }
wolfSSL 0:d92f9d21154c 4991
wolfSSL 0:d92f9d21154c 4992 return 1;
wolfSSL 0:d92f9d21154c 4993 }
wolfSSL 0:d92f9d21154c 4994
wolfSSL 0:d92f9d21154c 4995
wolfSSL 0:d92f9d21154c 4996 static INLINE int DtlsUpdateWindow(DtlsState* state)
wolfSSL 0:d92f9d21154c 4997 {
wolfSSL 0:d92f9d21154c 4998 word32 cur;
wolfSSL 0:d92f9d21154c 4999 word32* next;
wolfSSL 0:d92f9d21154c 5000 DtlsSeq* window;
wolfSSL 0:d92f9d21154c 5001
wolfSSL 0:d92f9d21154c 5002 if (state->curEpoch == state->nextEpoch) {
wolfSSL 0:d92f9d21154c 5003 next = &state->nextSeq;
wolfSSL 0:d92f9d21154c 5004 window = &state->window;
wolfSSL 0:d92f9d21154c 5005 }
wolfSSL 0:d92f9d21154c 5006 else {
wolfSSL 0:d92f9d21154c 5007 next = &state->prevSeq;
wolfSSL 0:d92f9d21154c 5008 window = &state->prevWindow;
wolfSSL 0:d92f9d21154c 5009 }
wolfSSL 0:d92f9d21154c 5010
wolfSSL 0:d92f9d21154c 5011 cur = state->curSeq;
wolfSSL 0:d92f9d21154c 5012
wolfSSL 0:d92f9d21154c 5013 if (cur < *next) {
wolfSSL 0:d92f9d21154c 5014 *window |= ((DtlsSeq)1 << (*next - cur - 1));
wolfSSL 0:d92f9d21154c 5015 }
wolfSSL 0:d92f9d21154c 5016 else {
wolfSSL 0:d92f9d21154c 5017 *window <<= (1 + cur - *next);
wolfSSL 0:d92f9d21154c 5018 *window |= 1;
wolfSSL 0:d92f9d21154c 5019 *next = cur + 1;
wolfSSL 0:d92f9d21154c 5020 }
wolfSSL 0:d92f9d21154c 5021
wolfSSL 0:d92f9d21154c 5022 return 1;
wolfSSL 0:d92f9d21154c 5023 }
wolfSSL 0:d92f9d21154c 5024
wolfSSL 0:d92f9d21154c 5025
wolfSSL 0:d92f9d21154c 5026 static int DtlsMsgDrain(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 5027 {
wolfSSL 0:d92f9d21154c 5028 DtlsMsg* item = ssl->dtls_msg_list;
wolfSSL 0:d92f9d21154c 5029 int ret = 0;
wolfSSL 0:d92f9d21154c 5030
wolfSSL 0:d92f9d21154c 5031 /* While there is an item in the store list, and it is the expected
wolfSSL 0:d92f9d21154c 5032 * message, and it is complete, and there hasn't been an error in the
wolfSSL 0:d92f9d21154c 5033 * last messge... */
wolfSSL 0:d92f9d21154c 5034 while (item != NULL &&
wolfSSL 0:d92f9d21154c 5035 ssl->keys.dtls_expected_peer_handshake_number == item->seq &&
wolfSSL 0:d92f9d21154c 5036 item->fragSz == item->sz &&
wolfSSL 0:d92f9d21154c 5037 ret == 0) {
wolfSSL 0:d92f9d21154c 5038 word32 idx = 0;
wolfSSL 0:d92f9d21154c 5039 ssl->keys.dtls_expected_peer_handshake_number++;
wolfSSL 0:d92f9d21154c 5040 ret = DoHandShakeMsgType(ssl, item->msg,
wolfSSL 0:d92f9d21154c 5041 &idx, item->type, item->sz, item->sz);
wolfSSL 0:d92f9d21154c 5042 ssl->dtls_msg_list = item->next;
wolfSSL 0:d92f9d21154c 5043 DtlsMsgDelete(item, ssl->heap);
wolfSSL 0:d92f9d21154c 5044 item = ssl->dtls_msg_list;
wolfSSL 0:d92f9d21154c 5045 }
wolfSSL 0:d92f9d21154c 5046
wolfSSL 0:d92f9d21154c 5047 return ret;
wolfSSL 0:d92f9d21154c 5048 }
wolfSSL 0:d92f9d21154c 5049
wolfSSL 0:d92f9d21154c 5050
wolfSSL 0:d92f9d21154c 5051 static int DoDtlsHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx,
wolfSSL 0:d92f9d21154c 5052 word32 totalSz)
wolfSSL 0:d92f9d21154c 5053 {
wolfSSL 0:d92f9d21154c 5054 byte type;
wolfSSL 0:d92f9d21154c 5055 word32 size;
wolfSSL 0:d92f9d21154c 5056 word32 fragOffset, fragSz;
wolfSSL 0:d92f9d21154c 5057 int ret = 0;
wolfSSL 0:d92f9d21154c 5058
wolfSSL 0:d92f9d21154c 5059 WOLFSSL_ENTER("DoDtlsHandShakeMsg()");
wolfSSL 0:d92f9d21154c 5060 if (GetDtlsHandShakeHeader(ssl, input, inOutIdx, &type,
wolfSSL 0:d92f9d21154c 5061 &size, &fragOffset, &fragSz, totalSz) != 0)
wolfSSL 0:d92f9d21154c 5062 return PARSE_ERROR;
wolfSSL 0:d92f9d21154c 5063
wolfSSL 0:d92f9d21154c 5064 if (*inOutIdx + fragSz > totalSz)
wolfSSL 0:d92f9d21154c 5065 return INCOMPLETE_DATA;
wolfSSL 0:d92f9d21154c 5066
wolfSSL 0:d92f9d21154c 5067 /* Check the handshake sequence number first. If out of order,
wolfSSL 0:d92f9d21154c 5068 * add the current message to the list. If the message is in order,
wolfSSL 0:d92f9d21154c 5069 * but it is a fragment, add the current message to the list, then
wolfSSL 0:d92f9d21154c 5070 * check the head of the list to see if it is complete, if so, pop
wolfSSL 0:d92f9d21154c 5071 * it out as the current message. If the message is complete and in
wolfSSL 0:d92f9d21154c 5072 * order, process it. Check the head of the list to see if it is in
wolfSSL 0:d92f9d21154c 5073 * order, if so, process it. (Repeat until list exhausted.) If the
wolfSSL 0:d92f9d21154c 5074 * head is out of order, return for more processing.
wolfSSL 0:d92f9d21154c 5075 */
wolfSSL 0:d92f9d21154c 5076 if (ssl->keys.dtls_peer_handshake_number >
wolfSSL 0:d92f9d21154c 5077 ssl->keys.dtls_expected_peer_handshake_number) {
wolfSSL 0:d92f9d21154c 5078 /* Current message is out of order. It will get stored in the list.
wolfSSL 0:d92f9d21154c 5079 * Storing also takes care of defragmentation. */
wolfSSL 0:d92f9d21154c 5080 ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
wolfSSL 0:d92f9d21154c 5081 ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
wolfSSL 0:d92f9d21154c 5082 size, type, fragOffset, fragSz, ssl->heap);
wolfSSL 0:d92f9d21154c 5083 *inOutIdx += fragSz;
wolfSSL 0:d92f9d21154c 5084 ret = 0;
wolfSSL 0:d92f9d21154c 5085 }
wolfSSL 0:d92f9d21154c 5086 else if (ssl->keys.dtls_peer_handshake_number <
wolfSSL 0:d92f9d21154c 5087 ssl->keys.dtls_expected_peer_handshake_number) {
wolfSSL 0:d92f9d21154c 5088 /* Already saw this message and processed it. It can be ignored. */
wolfSSL 0:d92f9d21154c 5089 *inOutIdx += fragSz;
wolfSSL 0:d92f9d21154c 5090 ret = 0;
wolfSSL 0:d92f9d21154c 5091 }
wolfSSL 0:d92f9d21154c 5092 else if (fragSz < size) {
wolfSSL 0:d92f9d21154c 5093 /* Since this branch is in order, but fragmented, dtls_msg_list will be
wolfSSL 0:d92f9d21154c 5094 * pointing to the message with this fragment in it. Check it to see
wolfSSL 0:d92f9d21154c 5095 * if it is completed. */
wolfSSL 0:d92f9d21154c 5096 ssl->dtls_msg_list = DtlsMsgStore(ssl->dtls_msg_list,
wolfSSL 0:d92f9d21154c 5097 ssl->keys.dtls_peer_handshake_number, input + *inOutIdx,
wolfSSL 0:d92f9d21154c 5098 size, type, fragOffset, fragSz, ssl->heap);
wolfSSL 0:d92f9d21154c 5099 *inOutIdx += fragSz;
wolfSSL 0:d92f9d21154c 5100 ret = 0;
wolfSSL 0:d92f9d21154c 5101 if (ssl->dtls_msg_list != NULL &&
wolfSSL 0:d92f9d21154c 5102 ssl->dtls_msg_list->fragSz >= ssl->dtls_msg_list->sz)
wolfSSL 0:d92f9d21154c 5103 ret = DtlsMsgDrain(ssl);
wolfSSL 0:d92f9d21154c 5104 }
wolfSSL 0:d92f9d21154c 5105 else {
wolfSSL 0:d92f9d21154c 5106 /* This branch is in order next, and a complete message. */
wolfSSL 0:d92f9d21154c 5107 ssl->keys.dtls_expected_peer_handshake_number++;
wolfSSL 0:d92f9d21154c 5108 ret = DoHandShakeMsgType(ssl, input, inOutIdx, type, size, totalSz);
wolfSSL 0:d92f9d21154c 5109 if (ret == 0 && ssl->dtls_msg_list != NULL)
wolfSSL 0:d92f9d21154c 5110 ret = DtlsMsgDrain(ssl);
wolfSSL 0:d92f9d21154c 5111 }
wolfSSL 0:d92f9d21154c 5112
wolfSSL 0:d92f9d21154c 5113 WOLFSSL_LEAVE("DoDtlsHandShakeMsg()", ret);
wolfSSL 0:d92f9d21154c 5114 return ret;
wolfSSL 0:d92f9d21154c 5115 }
wolfSSL 0:d92f9d21154c 5116 #endif
wolfSSL 0:d92f9d21154c 5117
wolfSSL 0:d92f9d21154c 5118
wolfSSL 0:d92f9d21154c 5119 #if !defined(NO_OLD_TLS) || defined(HAVE_CHACHA) || defined(HAVE_AESCCM) \
wolfSSL 0:d92f9d21154c 5120 || defined(HAVE_AESGCM)
wolfSSL 0:d92f9d21154c 5121 static INLINE word32 GetSEQIncrement(WOLFSSL* ssl, int verify)
wolfSSL 0:d92f9d21154c 5122 {
wolfSSL 0:d92f9d21154c 5123 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 5124 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 5125 if (verify)
wolfSSL 0:d92f9d21154c 5126 return ssl->keys.dtls_state.curSeq; /* explicit from peer */
wolfSSL 0:d92f9d21154c 5127 else
wolfSSL 0:d92f9d21154c 5128 return ssl->keys.dtls_sequence_number - 1; /* already incremented */
wolfSSL 0:d92f9d21154c 5129 }
wolfSSL 0:d92f9d21154c 5130 #endif
wolfSSL 0:d92f9d21154c 5131 if (verify)
wolfSSL 0:d92f9d21154c 5132 return ssl->keys.peer_sequence_number++;
wolfSSL 0:d92f9d21154c 5133 else
wolfSSL 0:d92f9d21154c 5134 return ssl->keys.sequence_number++;
wolfSSL 0:d92f9d21154c 5135 }
wolfSSL 0:d92f9d21154c 5136 #endif
wolfSSL 0:d92f9d21154c 5137
wolfSSL 0:d92f9d21154c 5138
wolfSSL 0:d92f9d21154c 5139 #ifdef HAVE_AEAD
wolfSSL 0:d92f9d21154c 5140 static INLINE void AeadIncrementExpIV(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 5141 {
wolfSSL 0:d92f9d21154c 5142 int i;
wolfSSL 0:d92f9d21154c 5143 for (i = AEAD_EXP_IV_SZ-1; i >= 0; i--) {
wolfSSL 0:d92f9d21154c 5144 if (++ssl->keys.aead_exp_IV[i]) return;
wolfSSL 0:d92f9d21154c 5145 }
wolfSSL 0:d92f9d21154c 5146 }
wolfSSL 0:d92f9d21154c 5147
wolfSSL 0:d92f9d21154c 5148
wolfSSL 0:d92f9d21154c 5149 #if defined(HAVE_POLY1305) && defined(HAVE_CHACHA)
wolfSSL 0:d92f9d21154c 5150 /*more recent rfc's concatonate input for poly1305 differently*/
wolfSSL 0:d92f9d21154c 5151 static int Poly1305Tag(WOLFSSL* ssl, byte* additional, const byte* out,
wolfSSL 0:d92f9d21154c 5152 byte* cipher, word16 sz, byte* tag)
wolfSSL 0:d92f9d21154c 5153 {
wolfSSL 0:d92f9d21154c 5154 int ret = 0;
wolfSSL 0:d92f9d21154c 5155 int paddingSz = 0;
wolfSSL 0:d92f9d21154c 5156 int msglen = (sz - ssl->specs.aead_mac_size);
wolfSSL 0:d92f9d21154c 5157 word32 keySz = 32;
wolfSSL 0:d92f9d21154c 5158 int blockSz = 16;
wolfSSL 0:d92f9d21154c 5159 byte padding[16];
wolfSSL 0:d92f9d21154c 5160
wolfSSL 0:d92f9d21154c 5161 if (msglen < 0)
wolfSSL 0:d92f9d21154c 5162 return INPUT_CASE_ERROR;
wolfSSL 0:d92f9d21154c 5163
wolfSSL 0:d92f9d21154c 5164 XMEMSET(padding, 0, sizeof(padding));
wolfSSL 0:d92f9d21154c 5165
wolfSSL 0:d92f9d21154c 5166 if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0)
wolfSSL 0:d92f9d21154c 5167 return ret;
wolfSSL 0:d92f9d21154c 5168
wolfSSL 0:d92f9d21154c 5169 /* additional input to poly1305 */
wolfSSL 0:d92f9d21154c 5170 if ((ret = wc_Poly1305Update(ssl->auth.poly1305, additional, blockSz)) != 0)
wolfSSL 0:d92f9d21154c 5171 return ret;
wolfSSL 0:d92f9d21154c 5172
wolfSSL 0:d92f9d21154c 5173 /* cipher input */
wolfSSL 0:d92f9d21154c 5174 if ((ret = wc_Poly1305Update(ssl->auth.poly1305, out, msglen)) != 0)
wolfSSL 0:d92f9d21154c 5175 return ret;
wolfSSL 0:d92f9d21154c 5176
wolfSSL 0:d92f9d21154c 5177 /* handle padding for cipher input to make it 16 bytes long */
wolfSSL 0:d92f9d21154c 5178 if (msglen % 16 != 0) {
wolfSSL 0:d92f9d21154c 5179 paddingSz = (16 - (sz - ssl->specs.aead_mac_size) % 16);
wolfSSL 0:d92f9d21154c 5180 if (paddingSz < 0)
wolfSSL 0:d92f9d21154c 5181 return INPUT_CASE_ERROR;
wolfSSL 0:d92f9d21154c 5182
wolfSSL 0:d92f9d21154c 5183 if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding, paddingSz))
wolfSSL 0:d92f9d21154c 5184 != 0)
wolfSSL 0:d92f9d21154c 5185 return ret;
wolfSSL 0:d92f9d21154c 5186 }
wolfSSL 0:d92f9d21154c 5187
wolfSSL 0:d92f9d21154c 5188 /* add size of AD and size of cipher to poly input */
wolfSSL 0:d92f9d21154c 5189 XMEMSET(padding, 0, sizeof(padding));
wolfSSL 0:d92f9d21154c 5190 padding[0] = blockSz;
wolfSSL 0:d92f9d21154c 5191
wolfSSL 0:d92f9d21154c 5192 /* 32 bit size of cipher to 64 bit endian */
wolfSSL 0:d92f9d21154c 5193 padding[8] = msglen & 0xff;
wolfSSL 0:d92f9d21154c 5194 padding[9] = (msglen >> 8) & 0xff;
wolfSSL 0:d92f9d21154c 5195 padding[10] = (msglen >>16) & 0xff;
wolfSSL 0:d92f9d21154c 5196 padding[11] = (msglen >>24) & 0xff;
wolfSSL 0:d92f9d21154c 5197 if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding)))
wolfSSL 0:d92f9d21154c 5198 != 0)
wolfSSL 0:d92f9d21154c 5199 return ret;
wolfSSL 0:d92f9d21154c 5200
wolfSSL 0:d92f9d21154c 5201 /* generate tag */
wolfSSL 0:d92f9d21154c 5202 if ((ret = wc_Poly1305Final(ssl->auth.poly1305, tag)) != 0)
wolfSSL 0:d92f9d21154c 5203 return ret;
wolfSSL 0:d92f9d21154c 5204
wolfSSL 0:d92f9d21154c 5205 return ret;
wolfSSL 0:d92f9d21154c 5206 }
wolfSSL 0:d92f9d21154c 5207
wolfSSL 0:d92f9d21154c 5208
wolfSSL 0:d92f9d21154c 5209 /* Used for the older version of creating AEAD tags with Poly1305 */
wolfSSL 0:d92f9d21154c 5210 static int Poly1305TagOld(WOLFSSL* ssl, byte* additional, const byte* out,
wolfSSL 0:d92f9d21154c 5211 byte* cipher, word16 sz, byte* tag)
wolfSSL 0:d92f9d21154c 5212 {
wolfSSL 0:d92f9d21154c 5213 int ret = 0;
wolfSSL 0:d92f9d21154c 5214 int msglen = (sz - ssl->specs.aead_mac_size);
wolfSSL 0:d92f9d21154c 5215 word32 keySz = 32;
wolfSSL 0:d92f9d21154c 5216 byte padding[8]; /* used to temporarly store lengths */
wolfSSL 0:d92f9d21154c 5217
wolfSSL 0:d92f9d21154c 5218 #ifdef CHACHA_AEAD_TEST
wolfSSL 0:d92f9d21154c 5219 printf("Using old version of poly1305 input.\n");
wolfSSL 0:d92f9d21154c 5220 #endif
wolfSSL 0:d92f9d21154c 5221
wolfSSL 0:d92f9d21154c 5222 if (msglen < 0)
wolfSSL 0:d92f9d21154c 5223 return INPUT_CASE_ERROR;
wolfSSL 0:d92f9d21154c 5224
wolfSSL 0:d92f9d21154c 5225 if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0)
wolfSSL 0:d92f9d21154c 5226 return ret;
wolfSSL 0:d92f9d21154c 5227
wolfSSL 0:d92f9d21154c 5228 /* add TLS compressed length and additional input to poly1305 */
wolfSSL 0:d92f9d21154c 5229 additional[AEAD_AUTH_DATA_SZ - 2] = (msglen >> 8) & 0xff;
wolfSSL 0:d92f9d21154c 5230 additional[AEAD_AUTH_DATA_SZ - 1] = msglen & 0xff;
wolfSSL 0:d92f9d21154c 5231 if ((ret = wc_Poly1305Update(ssl->auth.poly1305, additional,
wolfSSL 0:d92f9d21154c 5232 AEAD_AUTH_DATA_SZ)) != 0)
wolfSSL 0:d92f9d21154c 5233 return ret;
wolfSSL 0:d92f9d21154c 5234
wolfSSL 0:d92f9d21154c 5235 /* length of additional input plus padding */
wolfSSL 0:d92f9d21154c 5236 XMEMSET(padding, 0, sizeof(padding));
wolfSSL 0:d92f9d21154c 5237 padding[0] = AEAD_AUTH_DATA_SZ;
wolfSSL 0:d92f9d21154c 5238 if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding,
wolfSSL 0:d92f9d21154c 5239 sizeof(padding))) != 0)
wolfSSL 0:d92f9d21154c 5240 return ret;
wolfSSL 0:d92f9d21154c 5241
wolfSSL 0:d92f9d21154c 5242
wolfSSL 0:d92f9d21154c 5243 /* add cipher info and then its length */
wolfSSL 0:d92f9d21154c 5244 XMEMSET(padding, 0, sizeof(padding));
wolfSSL 0:d92f9d21154c 5245 if ((ret = wc_Poly1305Update(ssl->auth.poly1305, out, msglen)) != 0)
wolfSSL 0:d92f9d21154c 5246 return ret;
wolfSSL 0:d92f9d21154c 5247
wolfSSL 0:d92f9d21154c 5248 /* 32 bit size of cipher to 64 bit endian */
wolfSSL 0:d92f9d21154c 5249 padding[0] = msglen & 0xff;
wolfSSL 0:d92f9d21154c 5250 padding[1] = (msglen >> 8) & 0xff;
wolfSSL 0:d92f9d21154c 5251 padding[2] = (msglen >> 16) & 0xff;
wolfSSL 0:d92f9d21154c 5252 padding[3] = (msglen >> 24) & 0xff;
wolfSSL 0:d92f9d21154c 5253 if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding)))
wolfSSL 0:d92f9d21154c 5254 != 0)
wolfSSL 0:d92f9d21154c 5255 return ret;
wolfSSL 0:d92f9d21154c 5256
wolfSSL 0:d92f9d21154c 5257 /* generate tag */
wolfSSL 0:d92f9d21154c 5258 if ((ret = wc_Poly1305Final(ssl->auth.poly1305, tag)) != 0)
wolfSSL 0:d92f9d21154c 5259 return ret;
wolfSSL 0:d92f9d21154c 5260
wolfSSL 0:d92f9d21154c 5261 return ret;
wolfSSL 0:d92f9d21154c 5262 }
wolfSSL 0:d92f9d21154c 5263
wolfSSL 0:d92f9d21154c 5264
wolfSSL 0:d92f9d21154c 5265 static int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input,
wolfSSL 0:d92f9d21154c 5266 word16 sz)
wolfSSL 0:d92f9d21154c 5267 {
wolfSSL 0:d92f9d21154c 5268 const byte* additionalSrc = input - RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 5269 int ret = 0;
wolfSSL 0:d92f9d21154c 5270 byte tag[POLY1305_AUTH_SZ];
wolfSSL 0:d92f9d21154c 5271 byte additional[CHACHA20_BLOCK_SIZE];
wolfSSL 0:d92f9d21154c 5272 byte nonce[AEAD_NONCE_SZ];
wolfSSL 0:d92f9d21154c 5273 byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for poly1305 */
wolfSSL 0:d92f9d21154c 5274 #ifdef CHACHA_AEAD_TEST
wolfSSL 0:d92f9d21154c 5275 int i;
wolfSSL 0:d92f9d21154c 5276 #endif
wolfSSL 0:d92f9d21154c 5277
wolfSSL 0:d92f9d21154c 5278 XMEMSET(tag, 0, sizeof(tag));
wolfSSL 0:d92f9d21154c 5279 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
wolfSSL 0:d92f9d21154c 5280 XMEMSET(cipher, 0, sizeof(cipher));
wolfSSL 0:d92f9d21154c 5281 XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE);
wolfSSL 0:d92f9d21154c 5282
wolfSSL 0:d92f9d21154c 5283 /* get nonce */
wolfSSL 0:d92f9d21154c 5284 c32toa(ssl->keys.sequence_number, nonce + AEAD_IMP_IV_SZ
wolfSSL 0:d92f9d21154c 5285 + AEAD_SEQ_OFFSET);
wolfSSL 0:d92f9d21154c 5286
wolfSSL 0:d92f9d21154c 5287 /* opaque SEQ number stored for AD */
wolfSSL 0:d92f9d21154c 5288 c32toa(GetSEQIncrement(ssl, 0), additional + AEAD_SEQ_OFFSET);
wolfSSL 0:d92f9d21154c 5289
wolfSSL 0:d92f9d21154c 5290 /* Store the type, version. Unfortunately, they are in
wolfSSL 0:d92f9d21154c 5291 * the input buffer ahead of the plaintext. */
wolfSSL 0:d92f9d21154c 5292 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 5293 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 5294 c16toa(ssl->keys.dtls_epoch, additional);
wolfSSL 0:d92f9d21154c 5295 additionalSrc -= DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 5296 }
wolfSSL 0:d92f9d21154c 5297 #endif
wolfSSL 0:d92f9d21154c 5298
wolfSSL 0:d92f9d21154c 5299 XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
wolfSSL 0:d92f9d21154c 5300
wolfSSL 0:d92f9d21154c 5301 #ifdef CHACHA_AEAD_TEST
wolfSSL 0:d92f9d21154c 5302 printf("Encrypt Additional : ");
wolfSSL 0:d92f9d21154c 5303 for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) {
wolfSSL 0:d92f9d21154c 5304 printf("%02x", additional[i]);
wolfSSL 0:d92f9d21154c 5305 }
wolfSSL 0:d92f9d21154c 5306 printf("\n\n");
wolfSSL 0:d92f9d21154c 5307 printf("input before encryption :\n");
wolfSSL 0:d92f9d21154c 5308 for (i = 0; i < sz; i++) {
wolfSSL 0:d92f9d21154c 5309 printf("%02x", input[i]);
wolfSSL 0:d92f9d21154c 5310 if ((i + 1) % 16 == 0)
wolfSSL 0:d92f9d21154c 5311 printf("\n");
wolfSSL 0:d92f9d21154c 5312 }
wolfSSL 0:d92f9d21154c 5313 printf("\n");
wolfSSL 0:d92f9d21154c 5314 #endif
wolfSSL 0:d92f9d21154c 5315
wolfSSL 0:d92f9d21154c 5316 /* set the nonce for chacha and get poly1305 key */
wolfSSL 0:d92f9d21154c 5317 if ((ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 0)) != 0)
wolfSSL 0:d92f9d21154c 5318 return ret;
wolfSSL 0:d92f9d21154c 5319
wolfSSL 0:d92f9d21154c 5320 if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, cipher,
wolfSSL 0:d92f9d21154c 5321 cipher, sizeof(cipher))) != 0)
wolfSSL 0:d92f9d21154c 5322 return ret;
wolfSSL 0:d92f9d21154c 5323
wolfSSL 0:d92f9d21154c 5324 /* encrypt the plain text */
wolfSSL 0:d92f9d21154c 5325 if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, out, input,
wolfSSL 0:d92f9d21154c 5326 sz - ssl->specs.aead_mac_size)) != 0)
wolfSSL 0:d92f9d21154c 5327 return ret;
wolfSSL 0:d92f9d21154c 5328
wolfSSL 0:d92f9d21154c 5329 /* get the tag : future use of hmac could go here*/
wolfSSL 0:d92f9d21154c 5330 if (ssl->options.oldPoly == 1) {
wolfSSL 0:d92f9d21154c 5331 if ((ret = Poly1305TagOld(ssl, additional, (const byte* )out,
wolfSSL 0:d92f9d21154c 5332 cipher, sz, tag)) != 0)
wolfSSL 0:d92f9d21154c 5333 return ret;
wolfSSL 0:d92f9d21154c 5334 }
wolfSSL 0:d92f9d21154c 5335 else {
wolfSSL 0:d92f9d21154c 5336 if ((ret = Poly1305Tag(ssl, additional, (const byte* )out,
wolfSSL 0:d92f9d21154c 5337 cipher, sz, tag)) != 0)
wolfSSL 0:d92f9d21154c 5338 return ret;
wolfSSL 0:d92f9d21154c 5339 }
wolfSSL 0:d92f9d21154c 5340
wolfSSL 0:d92f9d21154c 5341 /* append tag to ciphertext */
wolfSSL 0:d92f9d21154c 5342 XMEMCPY(out + sz - ssl->specs.aead_mac_size, tag, sizeof(tag));
wolfSSL 0:d92f9d21154c 5343
wolfSSL 0:d92f9d21154c 5344 AeadIncrementExpIV(ssl);
wolfSSL 0:d92f9d21154c 5345 ForceZero(nonce, AEAD_NONCE_SZ);
wolfSSL 0:d92f9d21154c 5346
wolfSSL 0:d92f9d21154c 5347 #ifdef CHACHA_AEAD_TEST
wolfSSL 0:d92f9d21154c 5348 printf("mac tag :\n");
wolfSSL 0:d92f9d21154c 5349 for (i = 0; i < 16; i++) {
wolfSSL 0:d92f9d21154c 5350 printf("%02x", tag[i]);
wolfSSL 0:d92f9d21154c 5351 if ((i + 1) % 16 == 0)
wolfSSL 0:d92f9d21154c 5352 printf("\n");
wolfSSL 0:d92f9d21154c 5353 }
wolfSSL 0:d92f9d21154c 5354 printf("\n\noutput after encrypt :\n");
wolfSSL 0:d92f9d21154c 5355 for (i = 0; i < sz; i++) {
wolfSSL 0:d92f9d21154c 5356 printf("%02x", out[i]);
wolfSSL 0:d92f9d21154c 5357 if ((i + 1) % 16 == 0)
wolfSSL 0:d92f9d21154c 5358 printf("\n");
wolfSSL 0:d92f9d21154c 5359 }
wolfSSL 0:d92f9d21154c 5360 printf("\n");
wolfSSL 0:d92f9d21154c 5361 #endif
wolfSSL 0:d92f9d21154c 5362
wolfSSL 0:d92f9d21154c 5363 return ret;
wolfSSL 0:d92f9d21154c 5364 }
wolfSSL 0:d92f9d21154c 5365
wolfSSL 0:d92f9d21154c 5366
wolfSSL 0:d92f9d21154c 5367 static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input,
wolfSSL 0:d92f9d21154c 5368 word16 sz)
wolfSSL 0:d92f9d21154c 5369 {
wolfSSL 0:d92f9d21154c 5370 byte additional[CHACHA20_BLOCK_SIZE];
wolfSSL 0:d92f9d21154c 5371 byte nonce[AEAD_NONCE_SZ];
wolfSSL 0:d92f9d21154c 5372 byte tag[POLY1305_AUTH_SZ];
wolfSSL 0:d92f9d21154c 5373 byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for mac */
wolfSSL 0:d92f9d21154c 5374 int ret = 0;
wolfSSL 0:d92f9d21154c 5375
wolfSSL 0:d92f9d21154c 5376 XMEMSET(tag, 0, sizeof(tag));
wolfSSL 0:d92f9d21154c 5377 XMEMSET(cipher, 0, sizeof(cipher));
wolfSSL 0:d92f9d21154c 5378 XMEMSET(nonce, 0, AEAD_NONCE_SZ);
wolfSSL 0:d92f9d21154c 5379 XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE);
wolfSSL 0:d92f9d21154c 5380
wolfSSL 0:d92f9d21154c 5381 #ifdef CHACHA_AEAD_TEST
wolfSSL 0:d92f9d21154c 5382 int i;
wolfSSL 0:d92f9d21154c 5383 printf("input before decrypt :\n");
wolfSSL 0:d92f9d21154c 5384 for (i = 0; i < sz; i++) {
wolfSSL 0:d92f9d21154c 5385 printf("%02x", input[i]);
wolfSSL 0:d92f9d21154c 5386 if ((i + 1) % 16 == 0)
wolfSSL 0:d92f9d21154c 5387 printf("\n");
wolfSSL 0:d92f9d21154c 5388 }
wolfSSL 0:d92f9d21154c 5389 printf("\n");
wolfSSL 0:d92f9d21154c 5390 #endif
wolfSSL 0:d92f9d21154c 5391
wolfSSL 0:d92f9d21154c 5392 /* get nonce */
wolfSSL 0:d92f9d21154c 5393 c32toa(ssl->keys.peer_sequence_number, nonce + AEAD_IMP_IV_SZ
wolfSSL 0:d92f9d21154c 5394 + AEAD_SEQ_OFFSET);
wolfSSL 0:d92f9d21154c 5395
wolfSSL 0:d92f9d21154c 5396 /* sequence number field is 64-bits, we only use 32-bits */
wolfSSL 0:d92f9d21154c 5397 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
wolfSSL 0:d92f9d21154c 5398
wolfSSL 0:d92f9d21154c 5399 /* get AD info */
wolfSSL 0:d92f9d21154c 5400 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
wolfSSL 0:d92f9d21154c 5401 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
wolfSSL 0:d92f9d21154c 5402 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
wolfSSL 0:d92f9d21154c 5403
wolfSSL 0:d92f9d21154c 5404 /* Store the type, version. */
wolfSSL 0:d92f9d21154c 5405 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 5406 if (ssl->options.dtls)
wolfSSL 0:d92f9d21154c 5407 c16toa(ssl->keys.dtls_state.curEpoch, additional);
wolfSSL 0:d92f9d21154c 5408 #endif
wolfSSL 0:d92f9d21154c 5409
wolfSSL 0:d92f9d21154c 5410 #ifdef CHACHA_AEAD_TEST
wolfSSL 0:d92f9d21154c 5411 printf("Decrypt Additional : ");
wolfSSL 0:d92f9d21154c 5412 for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) {
wolfSSL 0:d92f9d21154c 5413 printf("%02x", additional[i]);
wolfSSL 0:d92f9d21154c 5414 }
wolfSSL 0:d92f9d21154c 5415 printf("\n\n");
wolfSSL 0:d92f9d21154c 5416 #endif
wolfSSL 0:d92f9d21154c 5417
wolfSSL 0:d92f9d21154c 5418 /* set nonce and get poly1305 key */
wolfSSL 0:d92f9d21154c 5419 if ((ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 0)) != 0)
wolfSSL 0:d92f9d21154c 5420 return ret;
wolfSSL 0:d92f9d21154c 5421
wolfSSL 0:d92f9d21154c 5422 if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, cipher,
wolfSSL 0:d92f9d21154c 5423 cipher, sizeof(cipher))) != 0)
wolfSSL 0:d92f9d21154c 5424 return ret;
wolfSSL 0:d92f9d21154c 5425
wolfSSL 0:d92f9d21154c 5426 /* get the tag : future use of hmac could go here*/
wolfSSL 0:d92f9d21154c 5427 if (ssl->options.oldPoly == 1) {
wolfSSL 0:d92f9d21154c 5428 if ((ret = Poly1305TagOld(ssl, additional, input, cipher,
wolfSSL 0:d92f9d21154c 5429 sz, tag)) != 0)
wolfSSL 0:d92f9d21154c 5430 return ret;
wolfSSL 0:d92f9d21154c 5431 }
wolfSSL 0:d92f9d21154c 5432 else {
wolfSSL 0:d92f9d21154c 5433 if ((ret = Poly1305Tag(ssl, additional, input, cipher,
wolfSSL 0:d92f9d21154c 5434 sz, tag)) != 0)
wolfSSL 0:d92f9d21154c 5435 return ret;
wolfSSL 0:d92f9d21154c 5436 }
wolfSSL 0:d92f9d21154c 5437
wolfSSL 0:d92f9d21154c 5438 /* check mac sent along with packet */
wolfSSL 0:d92f9d21154c 5439 if (ConstantCompare(input + sz - ssl->specs.aead_mac_size, tag,
wolfSSL 0:d92f9d21154c 5440 ssl->specs.aead_mac_size) != 0) {
wolfSSL 0:d92f9d21154c 5441 WOLFSSL_MSG("Mac did not match");
wolfSSL 0:d92f9d21154c 5442 SendAlert(ssl, alert_fatal, bad_record_mac);
wolfSSL 0:d92f9d21154c 5443 ForceZero(nonce, AEAD_NONCE_SZ);
wolfSSL 0:d92f9d21154c 5444 return VERIFY_MAC_ERROR;
wolfSSL 0:d92f9d21154c 5445 }
wolfSSL 0:d92f9d21154c 5446
wolfSSL 0:d92f9d21154c 5447 /* if mac was good decrypt message */
wolfSSL 0:d92f9d21154c 5448 if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, plain, input,
wolfSSL 0:d92f9d21154c 5449 sz - ssl->specs.aead_mac_size)) != 0)
wolfSSL 0:d92f9d21154c 5450 return ret;
wolfSSL 0:d92f9d21154c 5451
wolfSSL 0:d92f9d21154c 5452 #ifdef CHACHA_AEAD_TEST
wolfSSL 0:d92f9d21154c 5453 printf("plain after decrypt :\n");
wolfSSL 0:d92f9d21154c 5454 for (i = 0; i < sz; i++) {
wolfSSL 0:d92f9d21154c 5455 printf("%02x", plain[i]);
wolfSSL 0:d92f9d21154c 5456 if ((i + 1) % 16 == 0)
wolfSSL 0:d92f9d21154c 5457 printf("\n");
wolfSSL 0:d92f9d21154c 5458 }
wolfSSL 0:d92f9d21154c 5459 printf("\n");
wolfSSL 0:d92f9d21154c 5460 #endif
wolfSSL 0:d92f9d21154c 5461
wolfSSL 0:d92f9d21154c 5462 return ret;
wolfSSL 0:d92f9d21154c 5463 }
wolfSSL 0:d92f9d21154c 5464 #endif /* HAVE_CHACHA && HAVE_POLY1305 */
wolfSSL 0:d92f9d21154c 5465 #endif /* HAVE_AEAD */
wolfSSL 0:d92f9d21154c 5466
wolfSSL 0:d92f9d21154c 5467
wolfSSL 0:d92f9d21154c 5468 static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz)
wolfSSL 0:d92f9d21154c 5469 {
wolfSSL 0:d92f9d21154c 5470 int ret = 0;
wolfSSL 0:d92f9d21154c 5471
wolfSSL 0:d92f9d21154c 5472 (void)out;
wolfSSL 0:d92f9d21154c 5473 (void)input;
wolfSSL 0:d92f9d21154c 5474 (void)sz;
wolfSSL 0:d92f9d21154c 5475
wolfSSL 0:d92f9d21154c 5476 if (ssl->encrypt.setup == 0) {
wolfSSL 0:d92f9d21154c 5477 WOLFSSL_MSG("Encrypt ciphers not setup");
wolfSSL 0:d92f9d21154c 5478 return ENCRYPT_ERROR;
wolfSSL 0:d92f9d21154c 5479 }
wolfSSL 0:d92f9d21154c 5480
wolfSSL 0:d92f9d21154c 5481 #ifdef HAVE_FUZZER
wolfSSL 0:d92f9d21154c 5482 if (ssl->fuzzerCb)
wolfSSL 0:d92f9d21154c 5483 ssl->fuzzerCb(ssl, input, sz, FUZZ_ENCRYPT, ssl->fuzzerCtx);
wolfSSL 0:d92f9d21154c 5484 #endif
wolfSSL 0:d92f9d21154c 5485
wolfSSL 0:d92f9d21154c 5486 switch (ssl->specs.bulk_cipher_algorithm) {
wolfSSL 0:d92f9d21154c 5487 #ifdef BUILD_ARC4
wolfSSL 0:d92f9d21154c 5488 case wolfssl_rc4:
wolfSSL 0:d92f9d21154c 5489 wc_Arc4Process(ssl->encrypt.arc4, out, input, sz);
wolfSSL 0:d92f9d21154c 5490 break;
wolfSSL 0:d92f9d21154c 5491 #endif
wolfSSL 0:d92f9d21154c 5492
wolfSSL 0:d92f9d21154c 5493 #ifdef BUILD_DES3
wolfSSL 0:d92f9d21154c 5494 case wolfssl_triple_des:
wolfSSL 0:d92f9d21154c 5495 ret = wc_Des3_CbcEncrypt(ssl->encrypt.des3, out, input, sz);
wolfSSL 0:d92f9d21154c 5496 break;
wolfSSL 0:d92f9d21154c 5497 #endif
wolfSSL 0:d92f9d21154c 5498
wolfSSL 0:d92f9d21154c 5499 #ifdef BUILD_AES
wolfSSL 0:d92f9d21154c 5500 case wolfssl_aes:
wolfSSL 0:d92f9d21154c 5501 ret = wc_AesCbcEncrypt(ssl->encrypt.aes, out, input, sz);
wolfSSL 0:d92f9d21154c 5502 break;
wolfSSL 0:d92f9d21154c 5503 #endif
wolfSSL 0:d92f9d21154c 5504
wolfSSL 0:d92f9d21154c 5505 #ifdef BUILD_AESGCM
wolfSSL 0:d92f9d21154c 5506 case wolfssl_aes_gcm:
wolfSSL 0:d92f9d21154c 5507 {
wolfSSL 0:d92f9d21154c 5508 byte additional[AEAD_AUTH_DATA_SZ];
wolfSSL 0:d92f9d21154c 5509 byte nonce[AEAD_NONCE_SZ];
wolfSSL 0:d92f9d21154c 5510 const byte* additionalSrc = input - 5;
wolfSSL 0:d92f9d21154c 5511
wolfSSL 0:d92f9d21154c 5512 XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
wolfSSL 0:d92f9d21154c 5513
wolfSSL 0:d92f9d21154c 5514 /* sequence number field is 64-bits, we only use 32-bits */
wolfSSL 0:d92f9d21154c 5515 c32toa(GetSEQIncrement(ssl, 0),
wolfSSL 0:d92f9d21154c 5516 additional + AEAD_SEQ_OFFSET);
wolfSSL 0:d92f9d21154c 5517
wolfSSL 0:d92f9d21154c 5518 /* Store the type, version. Unfortunately, they are in
wolfSSL 0:d92f9d21154c 5519 * the input buffer ahead of the plaintext. */
wolfSSL 0:d92f9d21154c 5520 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 5521 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 5522 c16toa(ssl->keys.dtls_epoch, additional);
wolfSSL 0:d92f9d21154c 5523 additionalSrc -= DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 5524 }
wolfSSL 0:d92f9d21154c 5525 #endif
wolfSSL 0:d92f9d21154c 5526 XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
wolfSSL 0:d92f9d21154c 5527
wolfSSL 0:d92f9d21154c 5528 /* Store the length of the plain text minus the explicit
wolfSSL 0:d92f9d21154c 5529 * IV length minus the authentication tag size. */
wolfSSL 0:d92f9d21154c 5530 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5531 additional + AEAD_LEN_OFFSET);
wolfSSL 0:d92f9d21154c 5532 XMEMCPY(nonce,
wolfSSL 0:d92f9d21154c 5533 ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ);
wolfSSL 0:d92f9d21154c 5534 XMEMCPY(nonce + AEAD_IMP_IV_SZ,
wolfSSL 0:d92f9d21154c 5535 ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
wolfSSL 0:d92f9d21154c 5536 ret = wc_AesGcmEncrypt(ssl->encrypt.aes,
wolfSSL 0:d92f9d21154c 5537 out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ,
wolfSSL 0:d92f9d21154c 5538 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5539 nonce, AEAD_NONCE_SZ,
wolfSSL 0:d92f9d21154c 5540 out + sz - ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5541 ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5542 additional, AEAD_AUTH_DATA_SZ);
wolfSSL 0:d92f9d21154c 5543 if (ret == 0)
wolfSSL 0:d92f9d21154c 5544 AeadIncrementExpIV(ssl);
wolfSSL 0:d92f9d21154c 5545 ForceZero(nonce, AEAD_NONCE_SZ);
wolfSSL 0:d92f9d21154c 5546 }
wolfSSL 0:d92f9d21154c 5547 break;
wolfSSL 0:d92f9d21154c 5548 #endif
wolfSSL 0:d92f9d21154c 5549
wolfSSL 0:d92f9d21154c 5550 #ifdef HAVE_AESCCM
wolfSSL 0:d92f9d21154c 5551 case wolfssl_aes_ccm:
wolfSSL 0:d92f9d21154c 5552 {
wolfSSL 0:d92f9d21154c 5553 byte additional[AEAD_AUTH_DATA_SZ];
wolfSSL 0:d92f9d21154c 5554 byte nonce[AEAD_NONCE_SZ];
wolfSSL 0:d92f9d21154c 5555 const byte* additionalSrc = input - 5;
wolfSSL 0:d92f9d21154c 5556
wolfSSL 0:d92f9d21154c 5557 XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
wolfSSL 0:d92f9d21154c 5558
wolfSSL 0:d92f9d21154c 5559 /* sequence number field is 64-bits, we only use 32-bits */
wolfSSL 0:d92f9d21154c 5560 c32toa(GetSEQIncrement(ssl, 0),
wolfSSL 0:d92f9d21154c 5561 additional + AEAD_SEQ_OFFSET);
wolfSSL 0:d92f9d21154c 5562
wolfSSL 0:d92f9d21154c 5563 /* Store the type, version. Unfortunately, they are in
wolfSSL 0:d92f9d21154c 5564 * the input buffer ahead of the plaintext. */
wolfSSL 0:d92f9d21154c 5565 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 5566 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 5567 c16toa(ssl->keys.dtls_epoch, additional);
wolfSSL 0:d92f9d21154c 5568 additionalSrc -= DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 5569 }
wolfSSL 0:d92f9d21154c 5570 #endif
wolfSSL 0:d92f9d21154c 5571 XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3);
wolfSSL 0:d92f9d21154c 5572
wolfSSL 0:d92f9d21154c 5573 /* Store the length of the plain text minus the explicit
wolfSSL 0:d92f9d21154c 5574 * IV length minus the authentication tag size. */
wolfSSL 0:d92f9d21154c 5575 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5576 additional + AEAD_LEN_OFFSET);
wolfSSL 0:d92f9d21154c 5577 XMEMCPY(nonce,
wolfSSL 0:d92f9d21154c 5578 ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ);
wolfSSL 0:d92f9d21154c 5579 XMEMCPY(nonce + AEAD_IMP_IV_SZ,
wolfSSL 0:d92f9d21154c 5580 ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
wolfSSL 0:d92f9d21154c 5581 wc_AesCcmEncrypt(ssl->encrypt.aes,
wolfSSL 0:d92f9d21154c 5582 out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ,
wolfSSL 0:d92f9d21154c 5583 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5584 nonce, AEAD_NONCE_SZ,
wolfSSL 0:d92f9d21154c 5585 out + sz - ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5586 ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5587 additional, AEAD_AUTH_DATA_SZ);
wolfSSL 0:d92f9d21154c 5588 AeadIncrementExpIV(ssl);
wolfSSL 0:d92f9d21154c 5589 ForceZero(nonce, AEAD_NONCE_SZ);
wolfSSL 0:d92f9d21154c 5590 }
wolfSSL 0:d92f9d21154c 5591 break;
wolfSSL 0:d92f9d21154c 5592 #endif
wolfSSL 0:d92f9d21154c 5593
wolfSSL 0:d92f9d21154c 5594 #ifdef HAVE_CAMELLIA
wolfSSL 0:d92f9d21154c 5595 case wolfssl_camellia:
wolfSSL 0:d92f9d21154c 5596 wc_CamelliaCbcEncrypt(ssl->encrypt.cam, out, input, sz);
wolfSSL 0:d92f9d21154c 5597 break;
wolfSSL 0:d92f9d21154c 5598 #endif
wolfSSL 0:d92f9d21154c 5599
wolfSSL 0:d92f9d21154c 5600 #ifdef HAVE_HC128
wolfSSL 0:d92f9d21154c 5601 case wolfssl_hc128:
wolfSSL 0:d92f9d21154c 5602 ret = wc_Hc128_Process(ssl->encrypt.hc128, out, input, sz);
wolfSSL 0:d92f9d21154c 5603 break;
wolfSSL 0:d92f9d21154c 5604 #endif
wolfSSL 0:d92f9d21154c 5605
wolfSSL 0:d92f9d21154c 5606 #ifdef BUILD_RABBIT
wolfSSL 0:d92f9d21154c 5607 case wolfssl_rabbit:
wolfSSL 0:d92f9d21154c 5608 ret = wc_RabbitProcess(ssl->encrypt.rabbit, out, input, sz);
wolfSSL 0:d92f9d21154c 5609 break;
wolfSSL 0:d92f9d21154c 5610 #endif
wolfSSL 0:d92f9d21154c 5611
wolfSSL 0:d92f9d21154c 5612 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
wolfSSL 0:d92f9d21154c 5613 case wolfssl_chacha:
wolfSSL 0:d92f9d21154c 5614 ret = ChachaAEADEncrypt(ssl, out, input, sz);
wolfSSL 0:d92f9d21154c 5615 break;
wolfSSL 0:d92f9d21154c 5616 #endif
wolfSSL 0:d92f9d21154c 5617
wolfSSL 0:d92f9d21154c 5618 #ifdef HAVE_NULL_CIPHER
wolfSSL 0:d92f9d21154c 5619 case wolfssl_cipher_null:
wolfSSL 0:d92f9d21154c 5620 if (input != out) {
wolfSSL 0:d92f9d21154c 5621 XMEMMOVE(out, input, sz);
wolfSSL 0:d92f9d21154c 5622 }
wolfSSL 0:d92f9d21154c 5623 break;
wolfSSL 0:d92f9d21154c 5624 #endif
wolfSSL 0:d92f9d21154c 5625
wolfSSL 0:d92f9d21154c 5626 default:
wolfSSL 0:d92f9d21154c 5627 WOLFSSL_MSG("wolfSSL Encrypt programming error");
wolfSSL 0:d92f9d21154c 5628 ret = ENCRYPT_ERROR;
wolfSSL 0:d92f9d21154c 5629 }
wolfSSL 0:d92f9d21154c 5630
wolfSSL 0:d92f9d21154c 5631 return ret;
wolfSSL 0:d92f9d21154c 5632 }
wolfSSL 0:d92f9d21154c 5633
wolfSSL 0:d92f9d21154c 5634
wolfSSL 0:d92f9d21154c 5635
wolfSSL 0:d92f9d21154c 5636 static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input,
wolfSSL 0:d92f9d21154c 5637 word16 sz)
wolfSSL 0:d92f9d21154c 5638 {
wolfSSL 0:d92f9d21154c 5639 int ret = 0;
wolfSSL 0:d92f9d21154c 5640
wolfSSL 0:d92f9d21154c 5641 (void)plain;
wolfSSL 0:d92f9d21154c 5642 (void)input;
wolfSSL 0:d92f9d21154c 5643 (void)sz;
wolfSSL 0:d92f9d21154c 5644
wolfSSL 0:d92f9d21154c 5645 if (ssl->decrypt.setup == 0) {
wolfSSL 0:d92f9d21154c 5646 WOLFSSL_MSG("Decrypt ciphers not setup");
wolfSSL 0:d92f9d21154c 5647 return DECRYPT_ERROR;
wolfSSL 0:d92f9d21154c 5648 }
wolfSSL 0:d92f9d21154c 5649
wolfSSL 0:d92f9d21154c 5650 switch (ssl->specs.bulk_cipher_algorithm) {
wolfSSL 0:d92f9d21154c 5651 #ifdef BUILD_ARC4
wolfSSL 0:d92f9d21154c 5652 case wolfssl_rc4:
wolfSSL 0:d92f9d21154c 5653 wc_Arc4Process(ssl->decrypt.arc4, plain, input, sz);
wolfSSL 0:d92f9d21154c 5654 break;
wolfSSL 0:d92f9d21154c 5655 #endif
wolfSSL 0:d92f9d21154c 5656
wolfSSL 0:d92f9d21154c 5657 #ifdef BUILD_DES3
wolfSSL 0:d92f9d21154c 5658 case wolfssl_triple_des:
wolfSSL 0:d92f9d21154c 5659 ret = wc_Des3_CbcDecrypt(ssl->decrypt.des3, plain, input, sz);
wolfSSL 0:d92f9d21154c 5660 break;
wolfSSL 0:d92f9d21154c 5661 #endif
wolfSSL 0:d92f9d21154c 5662
wolfSSL 0:d92f9d21154c 5663 #ifdef BUILD_AES
wolfSSL 0:d92f9d21154c 5664 case wolfssl_aes:
wolfSSL 0:d92f9d21154c 5665 ret = wc_AesCbcDecrypt(ssl->decrypt.aes, plain, input, sz);
wolfSSL 0:d92f9d21154c 5666 break;
wolfSSL 0:d92f9d21154c 5667 #endif
wolfSSL 0:d92f9d21154c 5668
wolfSSL 0:d92f9d21154c 5669 #ifdef BUILD_AESGCM
wolfSSL 0:d92f9d21154c 5670 case wolfssl_aes_gcm:
wolfSSL 0:d92f9d21154c 5671 {
wolfSSL 0:d92f9d21154c 5672 byte additional[AEAD_AUTH_DATA_SZ];
wolfSSL 0:d92f9d21154c 5673 byte nonce[AEAD_NONCE_SZ];
wolfSSL 0:d92f9d21154c 5674
wolfSSL 0:d92f9d21154c 5675 XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
wolfSSL 0:d92f9d21154c 5676
wolfSSL 0:d92f9d21154c 5677 /* sequence number field is 64-bits, we only use 32-bits */
wolfSSL 0:d92f9d21154c 5678 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
wolfSSL 0:d92f9d21154c 5679
wolfSSL 0:d92f9d21154c 5680 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 5681 if (ssl->options.dtls)
wolfSSL 0:d92f9d21154c 5682 c16toa(ssl->keys.dtls_state.curEpoch, additional);
wolfSSL 0:d92f9d21154c 5683 #endif
wolfSSL 0:d92f9d21154c 5684
wolfSSL 0:d92f9d21154c 5685 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
wolfSSL 0:d92f9d21154c 5686 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
wolfSSL 0:d92f9d21154c 5687 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
wolfSSL 0:d92f9d21154c 5688
wolfSSL 0:d92f9d21154c 5689 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5690 additional + AEAD_LEN_OFFSET);
wolfSSL 0:d92f9d21154c 5691 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
wolfSSL 0:d92f9d21154c 5692 XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
wolfSSL 0:d92f9d21154c 5693 if (wc_AesGcmDecrypt(ssl->decrypt.aes,
wolfSSL 0:d92f9d21154c 5694 plain + AEAD_EXP_IV_SZ,
wolfSSL 0:d92f9d21154c 5695 input + AEAD_EXP_IV_SZ,
wolfSSL 0:d92f9d21154c 5696 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5697 nonce, AEAD_NONCE_SZ,
wolfSSL 0:d92f9d21154c 5698 input + sz - ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5699 ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5700 additional, AEAD_AUTH_DATA_SZ) < 0) {
wolfSSL 0:d92f9d21154c 5701 SendAlert(ssl, alert_fatal, bad_record_mac);
wolfSSL 0:d92f9d21154c 5702 ret = VERIFY_MAC_ERROR;
wolfSSL 0:d92f9d21154c 5703 }
wolfSSL 0:d92f9d21154c 5704 ForceZero(nonce, AEAD_NONCE_SZ);
wolfSSL 0:d92f9d21154c 5705 }
wolfSSL 0:d92f9d21154c 5706 break;
wolfSSL 0:d92f9d21154c 5707 #endif
wolfSSL 0:d92f9d21154c 5708
wolfSSL 0:d92f9d21154c 5709 #ifdef HAVE_AESCCM
wolfSSL 0:d92f9d21154c 5710 case wolfssl_aes_ccm:
wolfSSL 0:d92f9d21154c 5711 {
wolfSSL 0:d92f9d21154c 5712 byte additional[AEAD_AUTH_DATA_SZ];
wolfSSL 0:d92f9d21154c 5713 byte nonce[AEAD_NONCE_SZ];
wolfSSL 0:d92f9d21154c 5714
wolfSSL 0:d92f9d21154c 5715 XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ);
wolfSSL 0:d92f9d21154c 5716
wolfSSL 0:d92f9d21154c 5717 /* sequence number field is 64-bits, we only use 32-bits */
wolfSSL 0:d92f9d21154c 5718 c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET);
wolfSSL 0:d92f9d21154c 5719
wolfSSL 0:d92f9d21154c 5720 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 5721 if (ssl->options.dtls)
wolfSSL 0:d92f9d21154c 5722 c16toa(ssl->keys.dtls_state.curEpoch, additional);
wolfSSL 0:d92f9d21154c 5723 #endif
wolfSSL 0:d92f9d21154c 5724
wolfSSL 0:d92f9d21154c 5725 additional[AEAD_TYPE_OFFSET] = ssl->curRL.type;
wolfSSL 0:d92f9d21154c 5726 additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor;
wolfSSL 0:d92f9d21154c 5727 additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor;
wolfSSL 0:d92f9d21154c 5728
wolfSSL 0:d92f9d21154c 5729 c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5730 additional + AEAD_LEN_OFFSET);
wolfSSL 0:d92f9d21154c 5731 XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ);
wolfSSL 0:d92f9d21154c 5732 XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ);
wolfSSL 0:d92f9d21154c 5733 if (wc_AesCcmDecrypt(ssl->decrypt.aes,
wolfSSL 0:d92f9d21154c 5734 plain + AEAD_EXP_IV_SZ,
wolfSSL 0:d92f9d21154c 5735 input + AEAD_EXP_IV_SZ,
wolfSSL 0:d92f9d21154c 5736 sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5737 nonce, AEAD_NONCE_SZ,
wolfSSL 0:d92f9d21154c 5738 input + sz - ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5739 ssl->specs.aead_mac_size,
wolfSSL 0:d92f9d21154c 5740 additional, AEAD_AUTH_DATA_SZ) < 0) {
wolfSSL 0:d92f9d21154c 5741 SendAlert(ssl, alert_fatal, bad_record_mac);
wolfSSL 0:d92f9d21154c 5742 ret = VERIFY_MAC_ERROR;
wolfSSL 0:d92f9d21154c 5743 }
wolfSSL 0:d92f9d21154c 5744 ForceZero(nonce, AEAD_NONCE_SZ);
wolfSSL 0:d92f9d21154c 5745 }
wolfSSL 0:d92f9d21154c 5746 break;
wolfSSL 0:d92f9d21154c 5747 #endif
wolfSSL 0:d92f9d21154c 5748
wolfSSL 0:d92f9d21154c 5749 #ifdef HAVE_CAMELLIA
wolfSSL 0:d92f9d21154c 5750 case wolfssl_camellia:
wolfSSL 0:d92f9d21154c 5751 wc_CamelliaCbcDecrypt(ssl->decrypt.cam, plain, input, sz);
wolfSSL 0:d92f9d21154c 5752 break;
wolfSSL 0:d92f9d21154c 5753 #endif
wolfSSL 0:d92f9d21154c 5754
wolfSSL 0:d92f9d21154c 5755 #ifdef HAVE_HC128
wolfSSL 0:d92f9d21154c 5756 case wolfssl_hc128:
wolfSSL 0:d92f9d21154c 5757 ret = wc_Hc128_Process(ssl->decrypt.hc128, plain, input, sz);
wolfSSL 0:d92f9d21154c 5758 break;
wolfSSL 0:d92f9d21154c 5759 #endif
wolfSSL 0:d92f9d21154c 5760
wolfSSL 0:d92f9d21154c 5761 #ifdef BUILD_RABBIT
wolfSSL 0:d92f9d21154c 5762 case wolfssl_rabbit:
wolfSSL 0:d92f9d21154c 5763 ret = wc_RabbitProcess(ssl->decrypt.rabbit, plain, input, sz);
wolfSSL 0:d92f9d21154c 5764 break;
wolfSSL 0:d92f9d21154c 5765 #endif
wolfSSL 0:d92f9d21154c 5766
wolfSSL 0:d92f9d21154c 5767 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
wolfSSL 0:d92f9d21154c 5768 case wolfssl_chacha:
wolfSSL 0:d92f9d21154c 5769 ret = ChachaAEADDecrypt(ssl, plain, input, sz);
wolfSSL 0:d92f9d21154c 5770 break;
wolfSSL 0:d92f9d21154c 5771 #endif
wolfSSL 0:d92f9d21154c 5772
wolfSSL 0:d92f9d21154c 5773 #ifdef HAVE_NULL_CIPHER
wolfSSL 0:d92f9d21154c 5774 case wolfssl_cipher_null:
wolfSSL 0:d92f9d21154c 5775 if (input != plain) {
wolfSSL 0:d92f9d21154c 5776 XMEMMOVE(plain, input, sz);
wolfSSL 0:d92f9d21154c 5777 }
wolfSSL 0:d92f9d21154c 5778 break;
wolfSSL 0:d92f9d21154c 5779 #endif
wolfSSL 0:d92f9d21154c 5780
wolfSSL 0:d92f9d21154c 5781 default:
wolfSSL 0:d92f9d21154c 5782 WOLFSSL_MSG("wolfSSL Decrypt programming error");
wolfSSL 0:d92f9d21154c 5783 ret = DECRYPT_ERROR;
wolfSSL 0:d92f9d21154c 5784 }
wolfSSL 0:d92f9d21154c 5785
wolfSSL 0:d92f9d21154c 5786 return ret;
wolfSSL 0:d92f9d21154c 5787 }
wolfSSL 0:d92f9d21154c 5788
wolfSSL 0:d92f9d21154c 5789
wolfSSL 0:d92f9d21154c 5790 /* check cipher text size for sanity */
wolfSSL 0:d92f9d21154c 5791 static int SanityCheckCipherText(WOLFSSL* ssl, word32 encryptSz)
wolfSSL 0:d92f9d21154c 5792 {
wolfSSL 0:d92f9d21154c 5793 #ifdef HAVE_TRUNCATED_HMAC
wolfSSL 0:d92f9d21154c 5794 word32 minLength = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ
wolfSSL 0:d92f9d21154c 5795 : ssl->specs.hash_size;
wolfSSL 0:d92f9d21154c 5796 #else
wolfSSL 0:d92f9d21154c 5797 word32 minLength = ssl->specs.hash_size; /* covers stream */
wolfSSL 0:d92f9d21154c 5798 #endif
wolfSSL 0:d92f9d21154c 5799
wolfSSL 0:d92f9d21154c 5800 if (ssl->specs.cipher_type == block) {
wolfSSL 0:d92f9d21154c 5801 if (encryptSz % ssl->specs.block_size) {
wolfSSL 0:d92f9d21154c 5802 WOLFSSL_MSG("Block ciphertext not block size");
wolfSSL 0:d92f9d21154c 5803 return SANITY_CIPHER_E;
wolfSSL 0:d92f9d21154c 5804 }
wolfSSL 0:d92f9d21154c 5805
wolfSSL 0:d92f9d21154c 5806 minLength++; /* pad byte */
wolfSSL 0:d92f9d21154c 5807
wolfSSL 0:d92f9d21154c 5808 if (ssl->specs.block_size > minLength)
wolfSSL 0:d92f9d21154c 5809 minLength = ssl->specs.block_size;
wolfSSL 0:d92f9d21154c 5810
wolfSSL 0:d92f9d21154c 5811 if (ssl->options.tls1_1)
wolfSSL 0:d92f9d21154c 5812 minLength += ssl->specs.block_size; /* explicit IV */
wolfSSL 0:d92f9d21154c 5813 }
wolfSSL 0:d92f9d21154c 5814 else if (ssl->specs.cipher_type == aead) {
wolfSSL 0:d92f9d21154c 5815 minLength = ssl->specs.aead_mac_size; /* authTag size */
wolfSSL 0:d92f9d21154c 5816 if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
wolfSSL 0:d92f9d21154c 5817 minLength += AEAD_EXP_IV_SZ; /* explicit IV */
wolfSSL 0:d92f9d21154c 5818 }
wolfSSL 0:d92f9d21154c 5819
wolfSSL 0:d92f9d21154c 5820 if (encryptSz < minLength) {
wolfSSL 0:d92f9d21154c 5821 WOLFSSL_MSG("Ciphertext not minimum size");
wolfSSL 0:d92f9d21154c 5822 return SANITY_CIPHER_E;
wolfSSL 0:d92f9d21154c 5823 }
wolfSSL 0:d92f9d21154c 5824
wolfSSL 0:d92f9d21154c 5825 return 0;
wolfSSL 0:d92f9d21154c 5826 }
wolfSSL 0:d92f9d21154c 5827
wolfSSL 0:d92f9d21154c 5828
wolfSSL 0:d92f9d21154c 5829 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 5830
wolfSSL 0:d92f9d21154c 5831 static INLINE void Md5Rounds(int rounds, const byte* data, int sz)
wolfSSL 0:d92f9d21154c 5832 {
wolfSSL 0:d92f9d21154c 5833 Md5 md5;
wolfSSL 0:d92f9d21154c 5834 int i;
wolfSSL 0:d92f9d21154c 5835
wolfSSL 0:d92f9d21154c 5836 wc_InitMd5(&md5);
wolfSSL 0:d92f9d21154c 5837
wolfSSL 0:d92f9d21154c 5838 for (i = 0; i < rounds; i++)
wolfSSL 0:d92f9d21154c 5839 wc_Md5Update(&md5, data, sz);
wolfSSL 0:d92f9d21154c 5840 }
wolfSSL 0:d92f9d21154c 5841
wolfSSL 0:d92f9d21154c 5842
wolfSSL 0:d92f9d21154c 5843
wolfSSL 0:d92f9d21154c 5844 /* do a dummy sha round */
wolfSSL 0:d92f9d21154c 5845 static INLINE void ShaRounds(int rounds, const byte* data, int sz)
wolfSSL 0:d92f9d21154c 5846 {
wolfSSL 0:d92f9d21154c 5847 Sha sha;
wolfSSL 0:d92f9d21154c 5848 int i;
wolfSSL 0:d92f9d21154c 5849
wolfSSL 0:d92f9d21154c 5850 wc_InitSha(&sha); /* no error check on purpose, dummy round */
wolfSSL 0:d92f9d21154c 5851
wolfSSL 0:d92f9d21154c 5852 for (i = 0; i < rounds; i++)
wolfSSL 0:d92f9d21154c 5853 wc_ShaUpdate(&sha, data, sz);
wolfSSL 0:d92f9d21154c 5854 }
wolfSSL 0:d92f9d21154c 5855 #endif
wolfSSL 0:d92f9d21154c 5856
wolfSSL 0:d92f9d21154c 5857
wolfSSL 0:d92f9d21154c 5858 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 5859
wolfSSL 0:d92f9d21154c 5860 static INLINE void Sha256Rounds(int rounds, const byte* data, int sz)
wolfSSL 0:d92f9d21154c 5861 {
wolfSSL 0:d92f9d21154c 5862 Sha256 sha256;
wolfSSL 0:d92f9d21154c 5863 int i;
wolfSSL 0:d92f9d21154c 5864
wolfSSL 0:d92f9d21154c 5865 wc_InitSha256(&sha256); /* no error check on purpose, dummy round */
wolfSSL 0:d92f9d21154c 5866
wolfSSL 0:d92f9d21154c 5867 for (i = 0; i < rounds; i++) {
wolfSSL 0:d92f9d21154c 5868 wc_Sha256Update(&sha256, data, sz);
wolfSSL 0:d92f9d21154c 5869 /* no error check on purpose, dummy round */
wolfSSL 0:d92f9d21154c 5870 }
wolfSSL 0:d92f9d21154c 5871
wolfSSL 0:d92f9d21154c 5872 }
wolfSSL 0:d92f9d21154c 5873
wolfSSL 0:d92f9d21154c 5874 #endif
wolfSSL 0:d92f9d21154c 5875
wolfSSL 0:d92f9d21154c 5876
wolfSSL 0:d92f9d21154c 5877 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 5878
wolfSSL 0:d92f9d21154c 5879 static INLINE void Sha384Rounds(int rounds, const byte* data, int sz)
wolfSSL 0:d92f9d21154c 5880 {
wolfSSL 0:d92f9d21154c 5881 Sha384 sha384;
wolfSSL 0:d92f9d21154c 5882 int i;
wolfSSL 0:d92f9d21154c 5883
wolfSSL 0:d92f9d21154c 5884 wc_InitSha384(&sha384); /* no error check on purpose, dummy round */
wolfSSL 0:d92f9d21154c 5885
wolfSSL 0:d92f9d21154c 5886 for (i = 0; i < rounds; i++) {
wolfSSL 0:d92f9d21154c 5887 wc_Sha384Update(&sha384, data, sz);
wolfSSL 0:d92f9d21154c 5888 /* no error check on purpose, dummy round */
wolfSSL 0:d92f9d21154c 5889 }
wolfSSL 0:d92f9d21154c 5890 }
wolfSSL 0:d92f9d21154c 5891
wolfSSL 0:d92f9d21154c 5892 #endif
wolfSSL 0:d92f9d21154c 5893
wolfSSL 0:d92f9d21154c 5894
wolfSSL 0:d92f9d21154c 5895 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 5896
wolfSSL 0:d92f9d21154c 5897 static INLINE void Sha512Rounds(int rounds, const byte* data, int sz)
wolfSSL 0:d92f9d21154c 5898 {
wolfSSL 0:d92f9d21154c 5899 Sha512 sha512;
wolfSSL 0:d92f9d21154c 5900 int i;
wolfSSL 0:d92f9d21154c 5901
wolfSSL 0:d92f9d21154c 5902 wc_InitSha512(&sha512); /* no error check on purpose, dummy round */
wolfSSL 0:d92f9d21154c 5903
wolfSSL 0:d92f9d21154c 5904 for (i = 0; i < rounds; i++) {
wolfSSL 0:d92f9d21154c 5905 wc_Sha512Update(&sha512, data, sz);
wolfSSL 0:d92f9d21154c 5906 /* no error check on purpose, dummy round */
wolfSSL 0:d92f9d21154c 5907 }
wolfSSL 0:d92f9d21154c 5908 }
wolfSSL 0:d92f9d21154c 5909
wolfSSL 0:d92f9d21154c 5910 #endif
wolfSSL 0:d92f9d21154c 5911
wolfSSL 0:d92f9d21154c 5912
wolfSSL 0:d92f9d21154c 5913 #ifdef WOLFSSL_RIPEMD
wolfSSL 0:d92f9d21154c 5914
wolfSSL 0:d92f9d21154c 5915 static INLINE void RmdRounds(int rounds, const byte* data, int sz)
wolfSSL 0:d92f9d21154c 5916 {
wolfSSL 0:d92f9d21154c 5917 RipeMd ripemd;
wolfSSL 0:d92f9d21154c 5918 int i;
wolfSSL 0:d92f9d21154c 5919
wolfSSL 0:d92f9d21154c 5920 wc_InitRipeMd(&ripemd);
wolfSSL 0:d92f9d21154c 5921
wolfSSL 0:d92f9d21154c 5922 for (i = 0; i < rounds; i++)
wolfSSL 0:d92f9d21154c 5923 wc_RipeMdUpdate(&ripemd, data, sz);
wolfSSL 0:d92f9d21154c 5924 }
wolfSSL 0:d92f9d21154c 5925
wolfSSL 0:d92f9d21154c 5926 #endif
wolfSSL 0:d92f9d21154c 5927
wolfSSL 0:d92f9d21154c 5928
wolfSSL 0:d92f9d21154c 5929 /* Do dummy rounds */
wolfSSL 0:d92f9d21154c 5930 static INLINE void DoRounds(int type, int rounds, const byte* data, int sz)
wolfSSL 0:d92f9d21154c 5931 {
wolfSSL 0:d92f9d21154c 5932 switch (type) {
wolfSSL 0:d92f9d21154c 5933
wolfSSL 0:d92f9d21154c 5934 case no_mac :
wolfSSL 0:d92f9d21154c 5935 break;
wolfSSL 0:d92f9d21154c 5936
wolfSSL 0:d92f9d21154c 5937 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 5938 #ifndef NO_MD5
wolfSSL 0:d92f9d21154c 5939 case md5_mac :
wolfSSL 0:d92f9d21154c 5940 Md5Rounds(rounds, data, sz);
wolfSSL 0:d92f9d21154c 5941 break;
wolfSSL 0:d92f9d21154c 5942 #endif
wolfSSL 0:d92f9d21154c 5943
wolfSSL 0:d92f9d21154c 5944 #ifndef NO_SHA
wolfSSL 0:d92f9d21154c 5945 case sha_mac :
wolfSSL 0:d92f9d21154c 5946 ShaRounds(rounds, data, sz);
wolfSSL 0:d92f9d21154c 5947 break;
wolfSSL 0:d92f9d21154c 5948 #endif
wolfSSL 0:d92f9d21154c 5949 #endif
wolfSSL 0:d92f9d21154c 5950
wolfSSL 0:d92f9d21154c 5951 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 5952 case sha256_mac :
wolfSSL 0:d92f9d21154c 5953 Sha256Rounds(rounds, data, sz);
wolfSSL 0:d92f9d21154c 5954 break;
wolfSSL 0:d92f9d21154c 5955 #endif
wolfSSL 0:d92f9d21154c 5956
wolfSSL 0:d92f9d21154c 5957 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 5958 case sha384_mac :
wolfSSL 0:d92f9d21154c 5959 Sha384Rounds(rounds, data, sz);
wolfSSL 0:d92f9d21154c 5960 break;
wolfSSL 0:d92f9d21154c 5961 #endif
wolfSSL 0:d92f9d21154c 5962
wolfSSL 0:d92f9d21154c 5963 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 5964 case sha512_mac :
wolfSSL 0:d92f9d21154c 5965 Sha512Rounds(rounds, data, sz);
wolfSSL 0:d92f9d21154c 5966 break;
wolfSSL 0:d92f9d21154c 5967 #endif
wolfSSL 0:d92f9d21154c 5968
wolfSSL 0:d92f9d21154c 5969 #ifdef WOLFSSL_RIPEMD
wolfSSL 0:d92f9d21154c 5970 case rmd_mac :
wolfSSL 0:d92f9d21154c 5971 RmdRounds(rounds, data, sz);
wolfSSL 0:d92f9d21154c 5972 break;
wolfSSL 0:d92f9d21154c 5973 #endif
wolfSSL 0:d92f9d21154c 5974
wolfSSL 0:d92f9d21154c 5975 default:
wolfSSL 0:d92f9d21154c 5976 WOLFSSL_MSG("Bad round type");
wolfSSL 0:d92f9d21154c 5977 break;
wolfSSL 0:d92f9d21154c 5978 }
wolfSSL 0:d92f9d21154c 5979 }
wolfSSL 0:d92f9d21154c 5980
wolfSSL 0:d92f9d21154c 5981
wolfSSL 0:d92f9d21154c 5982 /* do number of compression rounds on dummy data */
wolfSSL 0:d92f9d21154c 5983 static INLINE void CompressRounds(WOLFSSL* ssl, int rounds, const byte* dummy)
wolfSSL 0:d92f9d21154c 5984 {
wolfSSL 0:d92f9d21154c 5985 if (rounds)
wolfSSL 0:d92f9d21154c 5986 DoRounds(ssl->specs.mac_algorithm, rounds, dummy, COMPRESS_LOWER);
wolfSSL 0:d92f9d21154c 5987 }
wolfSSL 0:d92f9d21154c 5988
wolfSSL 0:d92f9d21154c 5989
wolfSSL 0:d92f9d21154c 5990 /* check all length bytes for the pad value, return 0 on success */
wolfSSL 0:d92f9d21154c 5991 static int PadCheck(const byte* a, byte pad, int length)
wolfSSL 0:d92f9d21154c 5992 {
wolfSSL 0:d92f9d21154c 5993 int i;
wolfSSL 0:d92f9d21154c 5994 int compareSum = 0;
wolfSSL 0:d92f9d21154c 5995
wolfSSL 0:d92f9d21154c 5996 for (i = 0; i < length; i++) {
wolfSSL 0:d92f9d21154c 5997 compareSum |= a[i] ^ pad;
wolfSSL 0:d92f9d21154c 5998 }
wolfSSL 0:d92f9d21154c 5999
wolfSSL 0:d92f9d21154c 6000 return compareSum;
wolfSSL 0:d92f9d21154c 6001 }
wolfSSL 0:d92f9d21154c 6002
wolfSSL 0:d92f9d21154c 6003
wolfSSL 0:d92f9d21154c 6004 /* get compression extra rounds */
wolfSSL 0:d92f9d21154c 6005 static INLINE int GetRounds(int pLen, int padLen, int t)
wolfSSL 0:d92f9d21154c 6006 {
wolfSSL 0:d92f9d21154c 6007 int roundL1 = 1; /* round up flags */
wolfSSL 0:d92f9d21154c 6008 int roundL2 = 1;
wolfSSL 0:d92f9d21154c 6009
wolfSSL 0:d92f9d21154c 6010 int L1 = COMPRESS_CONSTANT + pLen - t;
wolfSSL 0:d92f9d21154c 6011 int L2 = COMPRESS_CONSTANT + pLen - padLen - 1 - t;
wolfSSL 0:d92f9d21154c 6012
wolfSSL 0:d92f9d21154c 6013 L1 -= COMPRESS_UPPER;
wolfSSL 0:d92f9d21154c 6014 L2 -= COMPRESS_UPPER;
wolfSSL 0:d92f9d21154c 6015
wolfSSL 0:d92f9d21154c 6016 if ( (L1 % COMPRESS_LOWER) == 0)
wolfSSL 0:d92f9d21154c 6017 roundL1 = 0;
wolfSSL 0:d92f9d21154c 6018 if ( (L2 % COMPRESS_LOWER) == 0)
wolfSSL 0:d92f9d21154c 6019 roundL2 = 0;
wolfSSL 0:d92f9d21154c 6020
wolfSSL 0:d92f9d21154c 6021 L1 /= COMPRESS_LOWER;
wolfSSL 0:d92f9d21154c 6022 L2 /= COMPRESS_LOWER;
wolfSSL 0:d92f9d21154c 6023
wolfSSL 0:d92f9d21154c 6024 L1 += roundL1;
wolfSSL 0:d92f9d21154c 6025 L2 += roundL2;
wolfSSL 0:d92f9d21154c 6026
wolfSSL 0:d92f9d21154c 6027 return L1 - L2;
wolfSSL 0:d92f9d21154c 6028 }
wolfSSL 0:d92f9d21154c 6029
wolfSSL 0:d92f9d21154c 6030
wolfSSL 0:d92f9d21154c 6031 /* timing resistant pad/verify check, return 0 on success */
wolfSSL 0:d92f9d21154c 6032 static int TimingPadVerify(WOLFSSL* ssl, const byte* input, int padLen, int t,
wolfSSL 0:d92f9d21154c 6033 int pLen, int content)
wolfSSL 0:d92f9d21154c 6034 {
wolfSSL 0:d92f9d21154c 6035 byte verify[MAX_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 6036 byte dmy[sizeof(WOLFSSL) >= MAX_PAD_SIZE ? 1 : MAX_PAD_SIZE] = {0};
wolfSSL 0:d92f9d21154c 6037 byte* dummy = sizeof(dmy) < MAX_PAD_SIZE ? (byte*) ssl : dmy;
wolfSSL 0:d92f9d21154c 6038 int ret = 0;
wolfSSL 0:d92f9d21154c 6039
wolfSSL 0:d92f9d21154c 6040 (void)dmy;
wolfSSL 0:d92f9d21154c 6041
wolfSSL 0:d92f9d21154c 6042 if ( (t + padLen + 1) > pLen) {
wolfSSL 0:d92f9d21154c 6043 WOLFSSL_MSG("Plain Len not long enough for pad/mac");
wolfSSL 0:d92f9d21154c 6044 PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE);
wolfSSL 0:d92f9d21154c 6045 ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */
wolfSSL 0:d92f9d21154c 6046 ConstantCompare(verify, input + pLen - t, t);
wolfSSL 0:d92f9d21154c 6047
wolfSSL 0:d92f9d21154c 6048 return VERIFY_MAC_ERROR;
wolfSSL 0:d92f9d21154c 6049 }
wolfSSL 0:d92f9d21154c 6050
wolfSSL 0:d92f9d21154c 6051 if (PadCheck(input + pLen - (padLen + 1), (byte)padLen, padLen + 1) != 0) {
wolfSSL 0:d92f9d21154c 6052 WOLFSSL_MSG("PadCheck failed");
wolfSSL 0:d92f9d21154c 6053 PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
wolfSSL 0:d92f9d21154c 6054 ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */
wolfSSL 0:d92f9d21154c 6055 ConstantCompare(verify, input + pLen - t, t);
wolfSSL 0:d92f9d21154c 6056
wolfSSL 0:d92f9d21154c 6057 return VERIFY_MAC_ERROR;
wolfSSL 0:d92f9d21154c 6058 }
wolfSSL 0:d92f9d21154c 6059
wolfSSL 0:d92f9d21154c 6060 PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1);
wolfSSL 0:d92f9d21154c 6061 ret = ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, content, 1);
wolfSSL 0:d92f9d21154c 6062
wolfSSL 0:d92f9d21154c 6063 CompressRounds(ssl, GetRounds(pLen, padLen, t), dummy);
wolfSSL 0:d92f9d21154c 6064
wolfSSL 0:d92f9d21154c 6065 if (ConstantCompare(verify, input + (pLen - padLen - 1 - t), t) != 0) {
wolfSSL 0:d92f9d21154c 6066 WOLFSSL_MSG("Verify MAC compare failed");
wolfSSL 0:d92f9d21154c 6067 return VERIFY_MAC_ERROR;
wolfSSL 0:d92f9d21154c 6068 }
wolfSSL 0:d92f9d21154c 6069
wolfSSL 0:d92f9d21154c 6070 if (ret != 0)
wolfSSL 0:d92f9d21154c 6071 return VERIFY_MAC_ERROR;
wolfSSL 0:d92f9d21154c 6072 return 0;
wolfSSL 0:d92f9d21154c 6073 }
wolfSSL 0:d92f9d21154c 6074
wolfSSL 0:d92f9d21154c 6075
wolfSSL 0:d92f9d21154c 6076 int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx)
wolfSSL 0:d92f9d21154c 6077 {
wolfSSL 0:d92f9d21154c 6078 word32 msgSz = ssl->keys.encryptSz;
wolfSSL 0:d92f9d21154c 6079 word32 idx = *inOutIdx;
wolfSSL 0:d92f9d21154c 6080 int dataSz;
wolfSSL 0:d92f9d21154c 6081 int ivExtra = 0;
wolfSSL 0:d92f9d21154c 6082 byte* rawData = input + idx; /* keep current for hmac */
wolfSSL 0:d92f9d21154c 6083 #ifdef HAVE_LIBZ
wolfSSL 0:d92f9d21154c 6084 byte decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
wolfSSL 0:d92f9d21154c 6085 #endif
wolfSSL 0:d92f9d21154c 6086
wolfSSL 0:d92f9d21154c 6087 if (ssl->options.handShakeDone == 0) {
wolfSSL 0:d92f9d21154c 6088 WOLFSSL_MSG("Received App data before a handshake completed");
wolfSSL 0:d92f9d21154c 6089 SendAlert(ssl, alert_fatal, unexpected_message);
wolfSSL 0:d92f9d21154c 6090 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 6091 }
wolfSSL 0:d92f9d21154c 6092
wolfSSL 0:d92f9d21154c 6093 if (ssl->specs.cipher_type == block) {
wolfSSL 0:d92f9d21154c 6094 if (ssl->options.tls1_1)
wolfSSL 0:d92f9d21154c 6095 ivExtra = ssl->specs.block_size;
wolfSSL 0:d92f9d21154c 6096 }
wolfSSL 0:d92f9d21154c 6097 else if (ssl->specs.cipher_type == aead) {
wolfSSL 0:d92f9d21154c 6098 if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
wolfSSL 0:d92f9d21154c 6099 ivExtra = AEAD_EXP_IV_SZ;
wolfSSL 0:d92f9d21154c 6100 }
wolfSSL 0:d92f9d21154c 6101
wolfSSL 0:d92f9d21154c 6102 dataSz = msgSz - ivExtra - ssl->keys.padSz;
wolfSSL 0:d92f9d21154c 6103 if (dataSz < 0) {
wolfSSL 0:d92f9d21154c 6104 WOLFSSL_MSG("App data buffer error, malicious input?");
wolfSSL 0:d92f9d21154c 6105 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 6106 }
wolfSSL 0:d92f9d21154c 6107
wolfSSL 0:d92f9d21154c 6108 /* read data */
wolfSSL 0:d92f9d21154c 6109 if (dataSz) {
wolfSSL 0:d92f9d21154c 6110 int rawSz = dataSz; /* keep raw size for idx adjustment */
wolfSSL 0:d92f9d21154c 6111
wolfSSL 0:d92f9d21154c 6112 #ifdef HAVE_LIBZ
wolfSSL 0:d92f9d21154c 6113 if (ssl->options.usingCompression) {
wolfSSL 0:d92f9d21154c 6114 dataSz = myDeCompress(ssl, rawData, dataSz, decomp, sizeof(decomp));
wolfSSL 0:d92f9d21154c 6115 if (dataSz < 0) return dataSz;
wolfSSL 0:d92f9d21154c 6116 }
wolfSSL 0:d92f9d21154c 6117 #endif
wolfSSL 0:d92f9d21154c 6118 idx += rawSz;
wolfSSL 0:d92f9d21154c 6119
wolfSSL 0:d92f9d21154c 6120 ssl->buffers.clearOutputBuffer.buffer = rawData;
wolfSSL 0:d92f9d21154c 6121 ssl->buffers.clearOutputBuffer.length = dataSz;
wolfSSL 0:d92f9d21154c 6122 }
wolfSSL 0:d92f9d21154c 6123
wolfSSL 0:d92f9d21154c 6124 idx += ssl->keys.padSz;
wolfSSL 0:d92f9d21154c 6125
wolfSSL 0:d92f9d21154c 6126 #ifdef HAVE_LIBZ
wolfSSL 0:d92f9d21154c 6127 /* decompress could be bigger, overwrite after verify */
wolfSSL 0:d92f9d21154c 6128 if (ssl->options.usingCompression)
wolfSSL 0:d92f9d21154c 6129 XMEMMOVE(rawData, decomp, dataSz);
wolfSSL 0:d92f9d21154c 6130 #endif
wolfSSL 0:d92f9d21154c 6131
wolfSSL 0:d92f9d21154c 6132 *inOutIdx = idx;
wolfSSL 0:d92f9d21154c 6133 return 0;
wolfSSL 0:d92f9d21154c 6134 }
wolfSSL 0:d92f9d21154c 6135
wolfSSL 0:d92f9d21154c 6136
wolfSSL 0:d92f9d21154c 6137 /* process alert, return level */
wolfSSL 0:d92f9d21154c 6138 static int DoAlert(WOLFSSL* ssl, byte* input, word32* inOutIdx, int* type,
wolfSSL 0:d92f9d21154c 6139 word32 totalSz)
wolfSSL 0:d92f9d21154c 6140 {
wolfSSL 0:d92f9d21154c 6141 byte level;
wolfSSL 0:d92f9d21154c 6142 byte code;
wolfSSL 0:d92f9d21154c 6143
wolfSSL 0:d92f9d21154c 6144 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 6145 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 6146 AddPacketName("Alert", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 6147 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 6148 /* add record header back on to info + 2 byte level, data */
wolfSSL 0:d92f9d21154c 6149 AddPacketInfo("Alert", &ssl->timeoutInfo, input + *inOutIdx -
wolfSSL 0:d92f9d21154c 6150 RECORD_HEADER_SZ, 2 + RECORD_HEADER_SZ, ssl->heap);
wolfSSL 0:d92f9d21154c 6151 #endif
wolfSSL 0:d92f9d21154c 6152
wolfSSL 0:d92f9d21154c 6153 /* make sure can read the message */
wolfSSL 0:d92f9d21154c 6154 if (*inOutIdx + ALERT_SIZE > totalSz)
wolfSSL 0:d92f9d21154c 6155 return BUFFER_E;
wolfSSL 0:d92f9d21154c 6156
wolfSSL 0:d92f9d21154c 6157 level = input[(*inOutIdx)++];
wolfSSL 0:d92f9d21154c 6158 code = input[(*inOutIdx)++];
wolfSSL 0:d92f9d21154c 6159 ssl->alert_history.last_rx.code = code;
wolfSSL 0:d92f9d21154c 6160 ssl->alert_history.last_rx.level = level;
wolfSSL 0:d92f9d21154c 6161 *type = code;
wolfSSL 0:d92f9d21154c 6162 if (level == alert_fatal) {
wolfSSL 0:d92f9d21154c 6163 ssl->options.isClosed = 1; /* Don't send close_notify */
wolfSSL 0:d92f9d21154c 6164 }
wolfSSL 0:d92f9d21154c 6165
wolfSSL 0:d92f9d21154c 6166 WOLFSSL_MSG("Got alert");
wolfSSL 0:d92f9d21154c 6167 if (*type == close_notify) {
wolfSSL 0:d92f9d21154c 6168 WOLFSSL_MSG(" close notify");
wolfSSL 0:d92f9d21154c 6169 ssl->options.closeNotify = 1;
wolfSSL 0:d92f9d21154c 6170 }
wolfSSL 0:d92f9d21154c 6171 WOLFSSL_ERROR(*type);
wolfSSL 0:d92f9d21154c 6172 if (ssl->keys.encryptionOn) {
wolfSSL 0:d92f9d21154c 6173 if (*inOutIdx + ssl->keys.padSz > totalSz)
wolfSSL 0:d92f9d21154c 6174 return BUFFER_E;
wolfSSL 0:d92f9d21154c 6175 *inOutIdx += ssl->keys.padSz;
wolfSSL 0:d92f9d21154c 6176 }
wolfSSL 0:d92f9d21154c 6177
wolfSSL 0:d92f9d21154c 6178 return level;
wolfSSL 0:d92f9d21154c 6179 }
wolfSSL 0:d92f9d21154c 6180
wolfSSL 0:d92f9d21154c 6181 static int GetInputData(WOLFSSL *ssl, word32 size)
wolfSSL 0:d92f9d21154c 6182 {
wolfSSL 0:d92f9d21154c 6183 int in;
wolfSSL 0:d92f9d21154c 6184 int inSz;
wolfSSL 0:d92f9d21154c 6185 int maxLength;
wolfSSL 0:d92f9d21154c 6186 int usedLength;
wolfSSL 0:d92f9d21154c 6187 int dtlsExtra = 0;
wolfSSL 0:d92f9d21154c 6188
wolfSSL 0:d92f9d21154c 6189
wolfSSL 0:d92f9d21154c 6190 /* check max input length */
wolfSSL 0:d92f9d21154c 6191 usedLength = ssl->buffers.inputBuffer.length - ssl->buffers.inputBuffer.idx;
wolfSSL 0:d92f9d21154c 6192 maxLength = ssl->buffers.inputBuffer.bufferSize - usedLength;
wolfSSL 0:d92f9d21154c 6193 inSz = (int)(size - usedLength); /* from last partial read */
wolfSSL 0:d92f9d21154c 6194
wolfSSL 0:d92f9d21154c 6195 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6196 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 6197 if (size < ssl->dtls_expected_rx)
wolfSSL 0:d92f9d21154c 6198 dtlsExtra = (int)(ssl->dtls_expected_rx - size);
wolfSSL 0:d92f9d21154c 6199 inSz = ssl->dtls_expected_rx;
wolfSSL 0:d92f9d21154c 6200 }
wolfSSL 0:d92f9d21154c 6201 #endif
wolfSSL 0:d92f9d21154c 6202
wolfSSL 0:d92f9d21154c 6203 if (inSz > maxLength) {
wolfSSL 0:d92f9d21154c 6204 if (GrowInputBuffer(ssl, size + dtlsExtra, usedLength) < 0)
wolfSSL 0:d92f9d21154c 6205 return MEMORY_E;
wolfSSL 0:d92f9d21154c 6206 }
wolfSSL 0:d92f9d21154c 6207
wolfSSL 0:d92f9d21154c 6208 if (inSz <= 0)
wolfSSL 0:d92f9d21154c 6209 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 6210
wolfSSL 0:d92f9d21154c 6211 /* Put buffer data at start if not there */
wolfSSL 0:d92f9d21154c 6212 if (usedLength > 0 && ssl->buffers.inputBuffer.idx != 0)
wolfSSL 0:d92f9d21154c 6213 XMEMMOVE(ssl->buffers.inputBuffer.buffer,
wolfSSL 0:d92f9d21154c 6214 ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx,
wolfSSL 0:d92f9d21154c 6215 usedLength);
wolfSSL 0:d92f9d21154c 6216
wolfSSL 0:d92f9d21154c 6217 /* remove processed data */
wolfSSL 0:d92f9d21154c 6218 ssl->buffers.inputBuffer.idx = 0;
wolfSSL 0:d92f9d21154c 6219 ssl->buffers.inputBuffer.length = usedLength;
wolfSSL 0:d92f9d21154c 6220
wolfSSL 0:d92f9d21154c 6221 /* read data from network */
wolfSSL 0:d92f9d21154c 6222 do {
wolfSSL 0:d92f9d21154c 6223 in = Receive(ssl,
wolfSSL 0:d92f9d21154c 6224 ssl->buffers.inputBuffer.buffer +
wolfSSL 0:d92f9d21154c 6225 ssl->buffers.inputBuffer.length,
wolfSSL 0:d92f9d21154c 6226 inSz);
wolfSSL 0:d92f9d21154c 6227 if (in == -1)
wolfSSL 0:d92f9d21154c 6228 return SOCKET_ERROR_E;
wolfSSL 0:d92f9d21154c 6229
wolfSSL 0:d92f9d21154c 6230 if (in == WANT_READ)
wolfSSL 0:d92f9d21154c 6231 return WANT_READ;
wolfSSL 0:d92f9d21154c 6232
wolfSSL 0:d92f9d21154c 6233 if (in > inSz)
wolfSSL 0:d92f9d21154c 6234 return RECV_OVERFLOW_E;
wolfSSL 0:d92f9d21154c 6235
wolfSSL 0:d92f9d21154c 6236 ssl->buffers.inputBuffer.length += in;
wolfSSL 0:d92f9d21154c 6237 inSz -= in;
wolfSSL 0:d92f9d21154c 6238
wolfSSL 0:d92f9d21154c 6239 } while (ssl->buffers.inputBuffer.length < size);
wolfSSL 0:d92f9d21154c 6240
wolfSSL 0:d92f9d21154c 6241 return 0;
wolfSSL 0:d92f9d21154c 6242 }
wolfSSL 0:d92f9d21154c 6243
wolfSSL 0:d92f9d21154c 6244
wolfSSL 0:d92f9d21154c 6245 static INLINE int VerifyMac(WOLFSSL* ssl, const byte* input, word32 msgSz,
wolfSSL 0:d92f9d21154c 6246 int content, word32* padSz)
wolfSSL 0:d92f9d21154c 6247 {
wolfSSL 0:d92f9d21154c 6248 int ivExtra = 0;
wolfSSL 0:d92f9d21154c 6249 int ret;
wolfSSL 0:d92f9d21154c 6250 word32 pad = 0;
wolfSSL 0:d92f9d21154c 6251 word32 padByte = 0;
wolfSSL 0:d92f9d21154c 6252 #ifdef HAVE_TRUNCATED_HMAC
wolfSSL 0:d92f9d21154c 6253 word32 digestSz = ssl->truncated_hmac ? TRUNCATED_HMAC_SZ
wolfSSL 0:d92f9d21154c 6254 : ssl->specs.hash_size;
wolfSSL 0:d92f9d21154c 6255 #else
wolfSSL 0:d92f9d21154c 6256 word32 digestSz = ssl->specs.hash_size;
wolfSSL 0:d92f9d21154c 6257 #endif
wolfSSL 0:d92f9d21154c 6258 byte verify[MAX_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 6259
wolfSSL 0:d92f9d21154c 6260 if (ssl->specs.cipher_type == block) {
wolfSSL 0:d92f9d21154c 6261 if (ssl->options.tls1_1)
wolfSSL 0:d92f9d21154c 6262 ivExtra = ssl->specs.block_size;
wolfSSL 0:d92f9d21154c 6263 pad = *(input + msgSz - ivExtra - 1);
wolfSSL 0:d92f9d21154c 6264 padByte = 1;
wolfSSL 0:d92f9d21154c 6265
wolfSSL 0:d92f9d21154c 6266 if (ssl->options.tls) {
wolfSSL 0:d92f9d21154c 6267 ret = TimingPadVerify(ssl, input, pad, digestSz, msgSz - ivExtra,
wolfSSL 0:d92f9d21154c 6268 content);
wolfSSL 0:d92f9d21154c 6269 if (ret != 0)
wolfSSL 0:d92f9d21154c 6270 return ret;
wolfSSL 0:d92f9d21154c 6271 }
wolfSSL 0:d92f9d21154c 6272 else { /* sslv3, some implementations have bad padding, but don't
wolfSSL 0:d92f9d21154c 6273 * allow bad read */
wolfSSL 0:d92f9d21154c 6274 int badPadLen = 0;
wolfSSL 0:d92f9d21154c 6275 byte dmy[sizeof(WOLFSSL) >= MAX_PAD_SIZE ? 1 : MAX_PAD_SIZE] = {0};
wolfSSL 0:d92f9d21154c 6276 byte* dummy = sizeof(dmy) < MAX_PAD_SIZE ? (byte*) ssl : dmy;
wolfSSL 0:d92f9d21154c 6277
wolfSSL 0:d92f9d21154c 6278 (void)dmy;
wolfSSL 0:d92f9d21154c 6279
wolfSSL 0:d92f9d21154c 6280 if (pad > (msgSz - digestSz - 1)) {
wolfSSL 0:d92f9d21154c 6281 WOLFSSL_MSG("Plain Len not long enough for pad/mac");
wolfSSL 0:d92f9d21154c 6282 pad = 0; /* no bad read */
wolfSSL 0:d92f9d21154c 6283 badPadLen = 1;
wolfSSL 0:d92f9d21154c 6284 }
wolfSSL 0:d92f9d21154c 6285 PadCheck(dummy, (byte)pad, MAX_PAD_SIZE); /* timing only */
wolfSSL 0:d92f9d21154c 6286 ret = ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1,
wolfSSL 0:d92f9d21154c 6287 content, 1);
wolfSSL 0:d92f9d21154c 6288 if (ConstantCompare(verify, input + msgSz - digestSz - pad - 1,
wolfSSL 0:d92f9d21154c 6289 digestSz) != 0)
wolfSSL 0:d92f9d21154c 6290 return VERIFY_MAC_ERROR;
wolfSSL 0:d92f9d21154c 6291 if (ret != 0 || badPadLen)
wolfSSL 0:d92f9d21154c 6292 return VERIFY_MAC_ERROR;
wolfSSL 0:d92f9d21154c 6293 }
wolfSSL 0:d92f9d21154c 6294 }
wolfSSL 0:d92f9d21154c 6295 else if (ssl->specs.cipher_type == stream) {
wolfSSL 0:d92f9d21154c 6296 ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, content, 1);
wolfSSL 0:d92f9d21154c 6297 if (ConstantCompare(verify, input + msgSz - digestSz, digestSz) != 0){
wolfSSL 0:d92f9d21154c 6298 return VERIFY_MAC_ERROR;
wolfSSL 0:d92f9d21154c 6299 }
wolfSSL 0:d92f9d21154c 6300 if (ret != 0)
wolfSSL 0:d92f9d21154c 6301 return VERIFY_MAC_ERROR;
wolfSSL 0:d92f9d21154c 6302 }
wolfSSL 0:d92f9d21154c 6303
wolfSSL 0:d92f9d21154c 6304 if (ssl->specs.cipher_type == aead) {
wolfSSL 0:d92f9d21154c 6305 *padSz = ssl->specs.aead_mac_size;
wolfSSL 0:d92f9d21154c 6306 }
wolfSSL 0:d92f9d21154c 6307 else {
wolfSSL 0:d92f9d21154c 6308 *padSz = digestSz + pad + padByte;
wolfSSL 0:d92f9d21154c 6309 }
wolfSSL 0:d92f9d21154c 6310
wolfSSL 0:d92f9d21154c 6311 return 0;
wolfSSL 0:d92f9d21154c 6312 }
wolfSSL 0:d92f9d21154c 6313
wolfSSL 0:d92f9d21154c 6314
wolfSSL 0:d92f9d21154c 6315 /* process input requests, return 0 is done, 1 is call again to complete, and
wolfSSL 0:d92f9d21154c 6316 negative number is error */
wolfSSL 0:d92f9d21154c 6317 int ProcessReply(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 6318 {
wolfSSL 0:d92f9d21154c 6319 int ret = 0, type, readSz;
wolfSSL 0:d92f9d21154c 6320 int atomicUser = 0;
wolfSSL 0:d92f9d21154c 6321 word32 startIdx = 0;
wolfSSL 0:d92f9d21154c 6322 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6323 int used;
wolfSSL 0:d92f9d21154c 6324 #endif
wolfSSL 0:d92f9d21154c 6325
wolfSSL 0:d92f9d21154c 6326 #ifdef ATOMIC_USER
wolfSSL 0:d92f9d21154c 6327 if (ssl->ctx->DecryptVerifyCb)
wolfSSL 0:d92f9d21154c 6328 atomicUser = 1;
wolfSSL 0:d92f9d21154c 6329 #endif
wolfSSL 0:d92f9d21154c 6330
wolfSSL 0:d92f9d21154c 6331 if (ssl->error != 0 && ssl->error != WANT_READ && ssl->error != WANT_WRITE){
wolfSSL 0:d92f9d21154c 6332 WOLFSSL_MSG("ProcessReply retry in error state, not allowed");
wolfSSL 0:d92f9d21154c 6333 return ssl->error;
wolfSSL 0:d92f9d21154c 6334 }
wolfSSL 0:d92f9d21154c 6335
wolfSSL 0:d92f9d21154c 6336 for (;;) {
wolfSSL 0:d92f9d21154c 6337 switch (ssl->options.processReply) {
wolfSSL 0:d92f9d21154c 6338
wolfSSL 0:d92f9d21154c 6339 /* in the WOLFSSL_SERVER case, get the first byte for detecting
wolfSSL 0:d92f9d21154c 6340 * old client hello */
wolfSSL 0:d92f9d21154c 6341 case doProcessInit:
wolfSSL 0:d92f9d21154c 6342
wolfSSL 0:d92f9d21154c 6343 readSz = RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 6344
wolfSSL 0:d92f9d21154c 6345 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6346 if (ssl->options.dtls)
wolfSSL 0:d92f9d21154c 6347 readSz = DTLS_RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 6348 #endif
wolfSSL 0:d92f9d21154c 6349
wolfSSL 0:d92f9d21154c 6350 /* get header or return error */
wolfSSL 0:d92f9d21154c 6351 if (!ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 6352 if ((ret = GetInputData(ssl, readSz)) < 0)
wolfSSL 0:d92f9d21154c 6353 return ret;
wolfSSL 0:d92f9d21154c 6354 } else {
wolfSSL 0:d92f9d21154c 6355 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6356 /* read ahead may already have header */
wolfSSL 0:d92f9d21154c 6357 used = ssl->buffers.inputBuffer.length -
wolfSSL 0:d92f9d21154c 6358 ssl->buffers.inputBuffer.idx;
wolfSSL 0:d92f9d21154c 6359 if (used < readSz)
wolfSSL 0:d92f9d21154c 6360 if ((ret = GetInputData(ssl, readSz)) < 0)
wolfSSL 0:d92f9d21154c 6361 return ret;
wolfSSL 0:d92f9d21154c 6362 #endif
wolfSSL 0:d92f9d21154c 6363 }
wolfSSL 0:d92f9d21154c 6364
wolfSSL 0:d92f9d21154c 6365 #ifdef OLD_HELLO_ALLOWED
wolfSSL 0:d92f9d21154c 6366
wolfSSL 0:d92f9d21154c 6367 /* see if sending SSLv2 client hello */
wolfSSL 0:d92f9d21154c 6368 if ( ssl->options.side == WOLFSSL_SERVER_END &&
wolfSSL 0:d92f9d21154c 6369 ssl->options.clientState == NULL_STATE &&
wolfSSL 0:d92f9d21154c 6370 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx]
wolfSSL 0:d92f9d21154c 6371 != handshake) {
wolfSSL 0:d92f9d21154c 6372 byte b0, b1;
wolfSSL 0:d92f9d21154c 6373
wolfSSL 0:d92f9d21154c 6374 ssl->options.processReply = runProcessOldClientHello;
wolfSSL 0:d92f9d21154c 6375
wolfSSL 0:d92f9d21154c 6376 /* sanity checks before getting size at front */
wolfSSL 0:d92f9d21154c 6377 if (ssl->buffers.inputBuffer.buffer[
wolfSSL 0:d92f9d21154c 6378 ssl->buffers.inputBuffer.idx + 2] != OLD_HELLO_ID) {
wolfSSL 0:d92f9d21154c 6379 WOLFSSL_MSG("Not a valid old client hello");
wolfSSL 0:d92f9d21154c 6380 return PARSE_ERROR;
wolfSSL 0:d92f9d21154c 6381 }
wolfSSL 0:d92f9d21154c 6382
wolfSSL 0:d92f9d21154c 6383 if (ssl->buffers.inputBuffer.buffer[
wolfSSL 0:d92f9d21154c 6384 ssl->buffers.inputBuffer.idx + 3] != SSLv3_MAJOR &&
wolfSSL 0:d92f9d21154c 6385 ssl->buffers.inputBuffer.buffer[
wolfSSL 0:d92f9d21154c 6386 ssl->buffers.inputBuffer.idx + 3] != DTLS_MAJOR) {
wolfSSL 0:d92f9d21154c 6387 WOLFSSL_MSG("Not a valid version in old client hello");
wolfSSL 0:d92f9d21154c 6388 return PARSE_ERROR;
wolfSSL 0:d92f9d21154c 6389 }
wolfSSL 0:d92f9d21154c 6390
wolfSSL 0:d92f9d21154c 6391 /* how many bytes need ProcessOldClientHello */
wolfSSL 0:d92f9d21154c 6392 b0 =
wolfSSL 0:d92f9d21154c 6393 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
wolfSSL 0:d92f9d21154c 6394 b1 =
wolfSSL 0:d92f9d21154c 6395 ssl->buffers.inputBuffer.buffer[ssl->buffers.inputBuffer.idx++];
wolfSSL 0:d92f9d21154c 6396 ssl->curSize = (word16)(((b0 & 0x7f) << 8) | b1);
wolfSSL 0:d92f9d21154c 6397 }
wolfSSL 0:d92f9d21154c 6398 else {
wolfSSL 0:d92f9d21154c 6399 ssl->options.processReply = getRecordLayerHeader;
wolfSSL 0:d92f9d21154c 6400 continue;
wolfSSL 0:d92f9d21154c 6401 }
wolfSSL 0:d92f9d21154c 6402
wolfSSL 0:d92f9d21154c 6403 /* in the WOLFSSL_SERVER case, run the old client hello */
wolfSSL 0:d92f9d21154c 6404 case runProcessOldClientHello:
wolfSSL 0:d92f9d21154c 6405
wolfSSL 0:d92f9d21154c 6406 /* get sz bytes or return error */
wolfSSL 0:d92f9d21154c 6407 if (!ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 6408 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
wolfSSL 0:d92f9d21154c 6409 return ret;
wolfSSL 0:d92f9d21154c 6410 } else {
wolfSSL 0:d92f9d21154c 6411 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6412 /* read ahead may already have */
wolfSSL 0:d92f9d21154c 6413 used = ssl->buffers.inputBuffer.length -
wolfSSL 0:d92f9d21154c 6414 ssl->buffers.inputBuffer.idx;
wolfSSL 0:d92f9d21154c 6415 if (used < ssl->curSize)
wolfSSL 0:d92f9d21154c 6416 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
wolfSSL 0:d92f9d21154c 6417 return ret;
wolfSSL 0:d92f9d21154c 6418 #endif /* WOLFSSL_DTLS */
wolfSSL 0:d92f9d21154c 6419 }
wolfSSL 0:d92f9d21154c 6420
wolfSSL 0:d92f9d21154c 6421 ret = ProcessOldClientHello(ssl, ssl->buffers.inputBuffer.buffer,
wolfSSL 0:d92f9d21154c 6422 &ssl->buffers.inputBuffer.idx,
wolfSSL 0:d92f9d21154c 6423 ssl->buffers.inputBuffer.length -
wolfSSL 0:d92f9d21154c 6424 ssl->buffers.inputBuffer.idx,
wolfSSL 0:d92f9d21154c 6425 ssl->curSize);
wolfSSL 0:d92f9d21154c 6426 if (ret < 0)
wolfSSL 0:d92f9d21154c 6427 return ret;
wolfSSL 0:d92f9d21154c 6428
wolfSSL 0:d92f9d21154c 6429 else if (ssl->buffers.inputBuffer.idx ==
wolfSSL 0:d92f9d21154c 6430 ssl->buffers.inputBuffer.length) {
wolfSSL 0:d92f9d21154c 6431 ssl->options.processReply = doProcessInit;
wolfSSL 0:d92f9d21154c 6432 return 0;
wolfSSL 0:d92f9d21154c 6433 }
wolfSSL 0:d92f9d21154c 6434
wolfSSL 0:d92f9d21154c 6435 #endif /* OLD_HELLO_ALLOWED */
wolfSSL 0:d92f9d21154c 6436
wolfSSL 0:d92f9d21154c 6437 /* get the record layer header */
wolfSSL 0:d92f9d21154c 6438 case getRecordLayerHeader:
wolfSSL 0:d92f9d21154c 6439
wolfSSL 0:d92f9d21154c 6440 ret = GetRecordHeader(ssl, ssl->buffers.inputBuffer.buffer,
wolfSSL 0:d92f9d21154c 6441 &ssl->buffers.inputBuffer.idx,
wolfSSL 0:d92f9d21154c 6442 &ssl->curRL, &ssl->curSize);
wolfSSL 0:d92f9d21154c 6443 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6444 if (ssl->options.dtls && ret == SEQUENCE_ERROR) {
wolfSSL 0:d92f9d21154c 6445 ssl->options.processReply = doProcessInit;
wolfSSL 0:d92f9d21154c 6446 ssl->buffers.inputBuffer.length = 0;
wolfSSL 0:d92f9d21154c 6447 ssl->buffers.inputBuffer.idx = 0;
wolfSSL 0:d92f9d21154c 6448 continue;
wolfSSL 0:d92f9d21154c 6449 }
wolfSSL 0:d92f9d21154c 6450 #endif
wolfSSL 0:d92f9d21154c 6451 if (ret != 0)
wolfSSL 0:d92f9d21154c 6452 return ret;
wolfSSL 0:d92f9d21154c 6453
wolfSSL 0:d92f9d21154c 6454 ssl->options.processReply = getData;
wolfSSL 0:d92f9d21154c 6455
wolfSSL 0:d92f9d21154c 6456 /* retrieve record layer data */
wolfSSL 0:d92f9d21154c 6457 case getData:
wolfSSL 0:d92f9d21154c 6458
wolfSSL 0:d92f9d21154c 6459 /* get sz bytes or return error */
wolfSSL 0:d92f9d21154c 6460 if (!ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 6461 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
wolfSSL 0:d92f9d21154c 6462 return ret;
wolfSSL 0:d92f9d21154c 6463 } else {
wolfSSL 0:d92f9d21154c 6464 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6465 /* read ahead may already have */
wolfSSL 0:d92f9d21154c 6466 used = ssl->buffers.inputBuffer.length -
wolfSSL 0:d92f9d21154c 6467 ssl->buffers.inputBuffer.idx;
wolfSSL 0:d92f9d21154c 6468 if (used < ssl->curSize)
wolfSSL 0:d92f9d21154c 6469 if ((ret = GetInputData(ssl, ssl->curSize)) < 0)
wolfSSL 0:d92f9d21154c 6470 return ret;
wolfSSL 0:d92f9d21154c 6471 #endif
wolfSSL 0:d92f9d21154c 6472 }
wolfSSL 0:d92f9d21154c 6473
wolfSSL 0:d92f9d21154c 6474 ssl->options.processReply = runProcessingOneMessage;
wolfSSL 0:d92f9d21154c 6475 startIdx = ssl->buffers.inputBuffer.idx; /* in case > 1 msg per */
wolfSSL 0:d92f9d21154c 6476
wolfSSL 0:d92f9d21154c 6477 /* the record layer is here */
wolfSSL 0:d92f9d21154c 6478 case runProcessingOneMessage:
wolfSSL 0:d92f9d21154c 6479
wolfSSL 0:d92f9d21154c 6480 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6481 if (ssl->options.dtls &&
wolfSSL 0:d92f9d21154c 6482 ssl->keys.dtls_state.curEpoch < ssl->keys.dtls_state.nextEpoch)
wolfSSL 0:d92f9d21154c 6483 ssl->keys.decryptedCur = 1;
wolfSSL 0:d92f9d21154c 6484 #endif
wolfSSL 0:d92f9d21154c 6485
wolfSSL 0:d92f9d21154c 6486 if (ssl->keys.encryptionOn && ssl->keys.decryptedCur == 0)
wolfSSL 0:d92f9d21154c 6487 {
wolfSSL 0:d92f9d21154c 6488 ret = SanityCheckCipherText(ssl, ssl->curSize);
wolfSSL 0:d92f9d21154c 6489 if (ret < 0)
wolfSSL 0:d92f9d21154c 6490 return ret;
wolfSSL 0:d92f9d21154c 6491
wolfSSL 0:d92f9d21154c 6492 if (atomicUser) {
wolfSSL 0:d92f9d21154c 6493 #ifdef ATOMIC_USER
wolfSSL 0:d92f9d21154c 6494 ret = ssl->ctx->DecryptVerifyCb(ssl,
wolfSSL 0:d92f9d21154c 6495 ssl->buffers.inputBuffer.buffer +
wolfSSL 0:d92f9d21154c 6496 ssl->buffers.inputBuffer.idx,
wolfSSL 0:d92f9d21154c 6497 ssl->buffers.inputBuffer.buffer +
wolfSSL 0:d92f9d21154c 6498 ssl->buffers.inputBuffer.idx,
wolfSSL 0:d92f9d21154c 6499 ssl->curSize, ssl->curRL.type, 1,
wolfSSL 0:d92f9d21154c 6500 &ssl->keys.padSz, ssl->DecryptVerifyCtx);
wolfSSL 0:d92f9d21154c 6501 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
wolfSSL 0:d92f9d21154c 6502 ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
wolfSSL 0:d92f9d21154c 6503 /* go past TLSv1.1 IV */
wolfSSL 0:d92f9d21154c 6504 if (ssl->specs.cipher_type == aead &&
wolfSSL 0:d92f9d21154c 6505 ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
wolfSSL 0:d92f9d21154c 6506 ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ;
wolfSSL 0:d92f9d21154c 6507 #endif /* ATOMIC_USER */
wolfSSL 0:d92f9d21154c 6508 }
wolfSSL 0:d92f9d21154c 6509 else {
wolfSSL 0:d92f9d21154c 6510 ret = Decrypt(ssl, ssl->buffers.inputBuffer.buffer +
wolfSSL 0:d92f9d21154c 6511 ssl->buffers.inputBuffer.idx,
wolfSSL 0:d92f9d21154c 6512 ssl->buffers.inputBuffer.buffer +
wolfSSL 0:d92f9d21154c 6513 ssl->buffers.inputBuffer.idx,
wolfSSL 0:d92f9d21154c 6514 ssl->curSize);
wolfSSL 0:d92f9d21154c 6515 if (ret < 0) {
wolfSSL 0:d92f9d21154c 6516 WOLFSSL_ERROR(ret);
wolfSSL 0:d92f9d21154c 6517 return DECRYPT_ERROR;
wolfSSL 0:d92f9d21154c 6518 }
wolfSSL 0:d92f9d21154c 6519 if (ssl->options.tls1_1 && ssl->specs.cipher_type == block)
wolfSSL 0:d92f9d21154c 6520 ssl->buffers.inputBuffer.idx += ssl->specs.block_size;
wolfSSL 0:d92f9d21154c 6521 /* go past TLSv1.1 IV */
wolfSSL 0:d92f9d21154c 6522 if (ssl->specs.cipher_type == aead &&
wolfSSL 0:d92f9d21154c 6523 ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
wolfSSL 0:d92f9d21154c 6524 ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ;
wolfSSL 0:d92f9d21154c 6525
wolfSSL 0:d92f9d21154c 6526 ret = VerifyMac(ssl, ssl->buffers.inputBuffer.buffer +
wolfSSL 0:d92f9d21154c 6527 ssl->buffers.inputBuffer.idx,
wolfSSL 0:d92f9d21154c 6528 ssl->curSize, ssl->curRL.type,
wolfSSL 0:d92f9d21154c 6529 &ssl->keys.padSz);
wolfSSL 0:d92f9d21154c 6530 }
wolfSSL 0:d92f9d21154c 6531 if (ret < 0) {
wolfSSL 0:d92f9d21154c 6532 WOLFSSL_ERROR(ret);
wolfSSL 0:d92f9d21154c 6533 return DECRYPT_ERROR;
wolfSSL 0:d92f9d21154c 6534 }
wolfSSL 0:d92f9d21154c 6535 ssl->keys.encryptSz = ssl->curSize;
wolfSSL 0:d92f9d21154c 6536 ssl->keys.decryptedCur = 1;
wolfSSL 0:d92f9d21154c 6537 }
wolfSSL 0:d92f9d21154c 6538
wolfSSL 0:d92f9d21154c 6539 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 6540 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6541 DtlsUpdateWindow(&ssl->keys.dtls_state);
wolfSSL 0:d92f9d21154c 6542 #endif /* WOLFSSL_DTLS */
wolfSSL 0:d92f9d21154c 6543 }
wolfSSL 0:d92f9d21154c 6544
wolfSSL 0:d92f9d21154c 6545 WOLFSSL_MSG("received record layer msg");
wolfSSL 0:d92f9d21154c 6546
wolfSSL 0:d92f9d21154c 6547 switch (ssl->curRL.type) {
wolfSSL 0:d92f9d21154c 6548 case handshake :
wolfSSL 0:d92f9d21154c 6549 /* debugging in DoHandShakeMsg */
wolfSSL 0:d92f9d21154c 6550 if (!ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 6551 ret = DoHandShakeMsg(ssl,
wolfSSL 0:d92f9d21154c 6552 ssl->buffers.inputBuffer.buffer,
wolfSSL 0:d92f9d21154c 6553 &ssl->buffers.inputBuffer.idx,
wolfSSL 0:d92f9d21154c 6554 ssl->buffers.inputBuffer.length);
wolfSSL 0:d92f9d21154c 6555 }
wolfSSL 0:d92f9d21154c 6556 else {
wolfSSL 0:d92f9d21154c 6557 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6558 ret = DoDtlsHandShakeMsg(ssl,
wolfSSL 0:d92f9d21154c 6559 ssl->buffers.inputBuffer.buffer,
wolfSSL 0:d92f9d21154c 6560 &ssl->buffers.inputBuffer.idx,
wolfSSL 0:d92f9d21154c 6561 ssl->buffers.inputBuffer.length);
wolfSSL 0:d92f9d21154c 6562 #endif
wolfSSL 0:d92f9d21154c 6563 }
wolfSSL 0:d92f9d21154c 6564 if (ret != 0)
wolfSSL 0:d92f9d21154c 6565 return ret;
wolfSSL 0:d92f9d21154c 6566 break;
wolfSSL 0:d92f9d21154c 6567
wolfSSL 0:d92f9d21154c 6568 case change_cipher_spec:
wolfSSL 0:d92f9d21154c 6569 WOLFSSL_MSG("got CHANGE CIPHER SPEC");
wolfSSL 0:d92f9d21154c 6570 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 6571 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 6572 AddPacketName("ChangeCipher", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 6573 /* add record header back on info */
wolfSSL 0:d92f9d21154c 6574 if (ssl->toInfoOn) {
wolfSSL 0:d92f9d21154c 6575 AddPacketInfo("ChangeCipher", &ssl->timeoutInfo,
wolfSSL 0:d92f9d21154c 6576 ssl->buffers.inputBuffer.buffer +
wolfSSL 0:d92f9d21154c 6577 ssl->buffers.inputBuffer.idx - RECORD_HEADER_SZ,
wolfSSL 0:d92f9d21154c 6578 1 + RECORD_HEADER_SZ, ssl->heap);
wolfSSL 0:d92f9d21154c 6579 AddLateRecordHeader(&ssl->curRL, &ssl->timeoutInfo);
wolfSSL 0:d92f9d21154c 6580 }
wolfSSL 0:d92f9d21154c 6581 #endif
wolfSSL 0:d92f9d21154c 6582
wolfSSL 0:d92f9d21154c 6583 ret = SanityCheckMsgReceived(ssl, change_cipher_hs);
wolfSSL 0:d92f9d21154c 6584 if (ret != 0)
wolfSSL 0:d92f9d21154c 6585 return ret;
wolfSSL 0:d92f9d21154c 6586
wolfSSL 0:d92f9d21154c 6587 #ifdef HAVE_SESSION_TICKET
wolfSSL 0:d92f9d21154c 6588 if (ssl->options.side == WOLFSSL_CLIENT_END &&
wolfSSL 0:d92f9d21154c 6589 ssl->expect_session_ticket) {
wolfSSL 0:d92f9d21154c 6590 WOLFSSL_MSG("Expected session ticket missing");
wolfSSL 0:d92f9d21154c 6591 return SESSION_TICKET_EXPECT_E;
wolfSSL 0:d92f9d21154c 6592 }
wolfSSL 0:d92f9d21154c 6593 #endif
wolfSSL 0:d92f9d21154c 6594
wolfSSL 0:d92f9d21154c 6595 if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
wolfSSL 0:d92f9d21154c 6596 ssl->buffers.inputBuffer.idx += ssl->keys.padSz;
wolfSSL 0:d92f9d21154c 6597 ssl->curSize -= (word16) ssl->buffers.inputBuffer.idx;
wolfSSL 0:d92f9d21154c 6598 }
wolfSSL 0:d92f9d21154c 6599
wolfSSL 0:d92f9d21154c 6600 if (ssl->curSize != 1) {
wolfSSL 0:d92f9d21154c 6601 WOLFSSL_MSG("Malicious or corrupted ChangeCipher msg");
wolfSSL 0:d92f9d21154c 6602 return LENGTH_ERROR;
wolfSSL 0:d92f9d21154c 6603 }
wolfSSL 0:d92f9d21154c 6604 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 6605 if (ssl->options.side == WOLFSSL_SERVER_END &&
wolfSSL 0:d92f9d21154c 6606 ssl->options.verifyPeer &&
wolfSSL 0:d92f9d21154c 6607 ssl->options.havePeerCert)
wolfSSL 0:d92f9d21154c 6608 if (!ssl->options.havePeerVerify) {
wolfSSL 0:d92f9d21154c 6609 WOLFSSL_MSG("client didn't send cert verify");
wolfSSL 0:d92f9d21154c 6610 return NO_PEER_VERIFY;
wolfSSL 0:d92f9d21154c 6611 }
wolfSSL 0:d92f9d21154c 6612 #endif
wolfSSL 0:d92f9d21154c 6613
wolfSSL 0:d92f9d21154c 6614
wolfSSL 0:d92f9d21154c 6615 ssl->buffers.inputBuffer.idx++;
wolfSSL 0:d92f9d21154c 6616 ssl->keys.encryptionOn = 1;
wolfSSL 0:d92f9d21154c 6617
wolfSSL 0:d92f9d21154c 6618 /* setup decrypt keys for following messages */
wolfSSL 0:d92f9d21154c 6619 if ((ret = SetKeysSide(ssl, DECRYPT_SIDE_ONLY)) != 0)
wolfSSL 0:d92f9d21154c 6620 return ret;
wolfSSL 0:d92f9d21154c 6621
wolfSSL 0:d92f9d21154c 6622 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6623 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 6624 DtlsPoolReset(ssl);
wolfSSL 0:d92f9d21154c 6625 ssl->keys.dtls_state.nextEpoch++;
wolfSSL 0:d92f9d21154c 6626 ssl->keys.dtls_state.nextSeq = 0;
wolfSSL 0:d92f9d21154c 6627 }
wolfSSL 0:d92f9d21154c 6628 #endif
wolfSSL 0:d92f9d21154c 6629
wolfSSL 0:d92f9d21154c 6630 #ifdef HAVE_LIBZ
wolfSSL 0:d92f9d21154c 6631 if (ssl->options.usingCompression)
wolfSSL 0:d92f9d21154c 6632 if ( (ret = InitStreams(ssl)) != 0)
wolfSSL 0:d92f9d21154c 6633 return ret;
wolfSSL 0:d92f9d21154c 6634 #endif
wolfSSL 0:d92f9d21154c 6635 ret = BuildFinished(ssl, &ssl->hsHashes->verifyHashes,
wolfSSL 0:d92f9d21154c 6636 ssl->options.side == WOLFSSL_CLIENT_END ?
wolfSSL 0:d92f9d21154c 6637 server : client);
wolfSSL 0:d92f9d21154c 6638 if (ret != 0)
wolfSSL 0:d92f9d21154c 6639 return ret;
wolfSSL 0:d92f9d21154c 6640 break;
wolfSSL 0:d92f9d21154c 6641
wolfSSL 0:d92f9d21154c 6642 case application_data:
wolfSSL 0:d92f9d21154c 6643 WOLFSSL_MSG("got app DATA");
wolfSSL 0:d92f9d21154c 6644 if ((ret = DoApplicationData(ssl,
wolfSSL 0:d92f9d21154c 6645 ssl->buffers.inputBuffer.buffer,
wolfSSL 0:d92f9d21154c 6646 &ssl->buffers.inputBuffer.idx))
wolfSSL 0:d92f9d21154c 6647 != 0) {
wolfSSL 0:d92f9d21154c 6648 WOLFSSL_ERROR(ret);
wolfSSL 0:d92f9d21154c 6649 return ret;
wolfSSL 0:d92f9d21154c 6650 }
wolfSSL 0:d92f9d21154c 6651 break;
wolfSSL 0:d92f9d21154c 6652
wolfSSL 0:d92f9d21154c 6653 case alert:
wolfSSL 0:d92f9d21154c 6654 WOLFSSL_MSG("got ALERT!");
wolfSSL 0:d92f9d21154c 6655 ret = DoAlert(ssl, ssl->buffers.inputBuffer.buffer,
wolfSSL 0:d92f9d21154c 6656 &ssl->buffers.inputBuffer.idx, &type,
wolfSSL 0:d92f9d21154c 6657 ssl->buffers.inputBuffer.length);
wolfSSL 0:d92f9d21154c 6658 if (ret == alert_fatal)
wolfSSL 0:d92f9d21154c 6659 return FATAL_ERROR;
wolfSSL 0:d92f9d21154c 6660 else if (ret < 0)
wolfSSL 0:d92f9d21154c 6661 return ret;
wolfSSL 0:d92f9d21154c 6662
wolfSSL 0:d92f9d21154c 6663 /* catch warnings that are handled as errors */
wolfSSL 0:d92f9d21154c 6664 if (type == close_notify)
wolfSSL 0:d92f9d21154c 6665 return ssl->error = ZERO_RETURN;
wolfSSL 0:d92f9d21154c 6666
wolfSSL 0:d92f9d21154c 6667 if (type == decrypt_error)
wolfSSL 0:d92f9d21154c 6668 return FATAL_ERROR;
wolfSSL 0:d92f9d21154c 6669 break;
wolfSSL 0:d92f9d21154c 6670
wolfSSL 0:d92f9d21154c 6671 default:
wolfSSL 0:d92f9d21154c 6672 WOLFSSL_ERROR(UNKNOWN_RECORD_TYPE);
wolfSSL 0:d92f9d21154c 6673 return UNKNOWN_RECORD_TYPE;
wolfSSL 0:d92f9d21154c 6674 }
wolfSSL 0:d92f9d21154c 6675
wolfSSL 0:d92f9d21154c 6676 ssl->options.processReply = doProcessInit;
wolfSSL 0:d92f9d21154c 6677
wolfSSL 0:d92f9d21154c 6678 /* input exhausted? */
wolfSSL 0:d92f9d21154c 6679 if (ssl->buffers.inputBuffer.idx == ssl->buffers.inputBuffer.length)
wolfSSL 0:d92f9d21154c 6680 return 0;
wolfSSL 0:d92f9d21154c 6681
wolfSSL 0:d92f9d21154c 6682 /* more messages per record */
wolfSSL 0:d92f9d21154c 6683 else if ((ssl->buffers.inputBuffer.idx - startIdx) < ssl->curSize) {
wolfSSL 0:d92f9d21154c 6684 WOLFSSL_MSG("More messages in record");
wolfSSL 0:d92f9d21154c 6685 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6686 /* read-ahead but dtls doesn't bundle messages per record */
wolfSSL 0:d92f9d21154c 6687 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 6688 ssl->options.processReply = doProcessInit;
wolfSSL 0:d92f9d21154c 6689 continue;
wolfSSL 0:d92f9d21154c 6690 }
wolfSSL 0:d92f9d21154c 6691 #endif
wolfSSL 0:d92f9d21154c 6692 ssl->options.processReply = runProcessingOneMessage;
wolfSSL 0:d92f9d21154c 6693
wolfSSL 0:d92f9d21154c 6694 if (ssl->keys.encryptionOn) {
wolfSSL 0:d92f9d21154c 6695 WOLFSSL_MSG("Bundled encrypted messages, remove middle pad");
wolfSSL 0:d92f9d21154c 6696 ssl->buffers.inputBuffer.idx -= ssl->keys.padSz;
wolfSSL 0:d92f9d21154c 6697 }
wolfSSL 0:d92f9d21154c 6698
wolfSSL 0:d92f9d21154c 6699 continue;
wolfSSL 0:d92f9d21154c 6700 }
wolfSSL 0:d92f9d21154c 6701 /* more records */
wolfSSL 0:d92f9d21154c 6702 else {
wolfSSL 0:d92f9d21154c 6703 WOLFSSL_MSG("More records in input");
wolfSSL 0:d92f9d21154c 6704 ssl->options.processReply = doProcessInit;
wolfSSL 0:d92f9d21154c 6705 continue;
wolfSSL 0:d92f9d21154c 6706 }
wolfSSL 0:d92f9d21154c 6707
wolfSSL 0:d92f9d21154c 6708 default:
wolfSSL 0:d92f9d21154c 6709 WOLFSSL_MSG("Bad process input state, programming error");
wolfSSL 0:d92f9d21154c 6710 return INPUT_CASE_ERROR;
wolfSSL 0:d92f9d21154c 6711 }
wolfSSL 0:d92f9d21154c 6712 }
wolfSSL 0:d92f9d21154c 6713 }
wolfSSL 0:d92f9d21154c 6714
wolfSSL 0:d92f9d21154c 6715
wolfSSL 0:d92f9d21154c 6716 int SendChangeCipher(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 6717 {
wolfSSL 0:d92f9d21154c 6718 byte *output;
wolfSSL 0:d92f9d21154c 6719 int sendSz = RECORD_HEADER_SZ + ENUM_LEN;
wolfSSL 0:d92f9d21154c 6720 int idx = RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 6721 int ret;
wolfSSL 0:d92f9d21154c 6722
wolfSSL 0:d92f9d21154c 6723 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6724 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 6725 sendSz += DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 6726 idx += DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 6727 }
wolfSSL 0:d92f9d21154c 6728 #endif
wolfSSL 0:d92f9d21154c 6729
wolfSSL 0:d92f9d21154c 6730 /* are we in scr */
wolfSSL 0:d92f9d21154c 6731 if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
wolfSSL 0:d92f9d21154c 6732 sendSz += MAX_MSG_EXTRA;
wolfSSL 0:d92f9d21154c 6733 }
wolfSSL 0:d92f9d21154c 6734
wolfSSL 0:d92f9d21154c 6735 /* check for avalaible size */
wolfSSL 0:d92f9d21154c 6736 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 6737 return ret;
wolfSSL 0:d92f9d21154c 6738
wolfSSL 0:d92f9d21154c 6739 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 6740 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 6741 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 6742
wolfSSL 0:d92f9d21154c 6743 AddRecordHeader(output, 1, change_cipher_spec, ssl);
wolfSSL 0:d92f9d21154c 6744
wolfSSL 0:d92f9d21154c 6745 output[idx] = 1; /* turn it on */
wolfSSL 0:d92f9d21154c 6746
wolfSSL 0:d92f9d21154c 6747 if (ssl->keys.encryptionOn && ssl->options.handShakeDone) {
wolfSSL 0:d92f9d21154c 6748 byte input[ENUM_LEN];
wolfSSL 0:d92f9d21154c 6749 int inputSz = ENUM_LEN;
wolfSSL 0:d92f9d21154c 6750
wolfSSL 0:d92f9d21154c 6751 input[0] = 1; /* turn it on */
wolfSSL 0:d92f9d21154c 6752 sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
wolfSSL 0:d92f9d21154c 6753 change_cipher_spec);
wolfSSL 0:d92f9d21154c 6754 if (sendSz < 0)
wolfSSL 0:d92f9d21154c 6755 return sendSz;
wolfSSL 0:d92f9d21154c 6756 }
wolfSSL 0:d92f9d21154c 6757
wolfSSL 0:d92f9d21154c 6758 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6759 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 6760 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 6761 return ret;
wolfSSL 0:d92f9d21154c 6762 }
wolfSSL 0:d92f9d21154c 6763 #endif
wolfSSL 0:d92f9d21154c 6764 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 6765 if (ssl->hsInfoOn) AddPacketName("ChangeCipher", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 6766 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 6767 AddPacketInfo("ChangeCipher", &ssl->timeoutInfo, output, sendSz,
wolfSSL 0:d92f9d21154c 6768 ssl->heap);
wolfSSL 0:d92f9d21154c 6769 #endif
wolfSSL 0:d92f9d21154c 6770 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 6771
wolfSSL 0:d92f9d21154c 6772 if (ssl->options.groupMessages)
wolfSSL 0:d92f9d21154c 6773 return 0;
wolfSSL 0:d92f9d21154c 6774 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 6775 else if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 6776 /* If using DTLS, force the ChangeCipherSpec message to be in the
wolfSSL 0:d92f9d21154c 6777 * same datagram as the finished message. */
wolfSSL 0:d92f9d21154c 6778 return 0;
wolfSSL 0:d92f9d21154c 6779 }
wolfSSL 0:d92f9d21154c 6780 #endif
wolfSSL 0:d92f9d21154c 6781 else
wolfSSL 0:d92f9d21154c 6782 return SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 6783 }
wolfSSL 0:d92f9d21154c 6784
wolfSSL 0:d92f9d21154c 6785
wolfSSL 0:d92f9d21154c 6786 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 6787 static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
wolfSSL 0:d92f9d21154c 6788 int content, int verify)
wolfSSL 0:d92f9d21154c 6789 {
wolfSSL 0:d92f9d21154c 6790 byte result[MAX_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 6791 word32 digestSz = ssl->specs.hash_size; /* actual sizes */
wolfSSL 0:d92f9d21154c 6792 word32 padSz = ssl->specs.pad_size;
wolfSSL 0:d92f9d21154c 6793 int ret = 0;
wolfSSL 0:d92f9d21154c 6794
wolfSSL 0:d92f9d21154c 6795 Md5 md5;
wolfSSL 0:d92f9d21154c 6796 Sha sha;
wolfSSL 0:d92f9d21154c 6797
wolfSSL 0:d92f9d21154c 6798 /* data */
wolfSSL 0:d92f9d21154c 6799 byte seq[SEQ_SZ];
wolfSSL 0:d92f9d21154c 6800 byte conLen[ENUM_LEN + LENGTH_SZ]; /* content & length */
wolfSSL 0:d92f9d21154c 6801 const byte* macSecret = wolfSSL_GetMacSecret(ssl, verify);
wolfSSL 0:d92f9d21154c 6802
wolfSSL 0:d92f9d21154c 6803 #ifdef HAVE_FUZZER
wolfSSL 0:d92f9d21154c 6804 if (ssl->fuzzerCb)
wolfSSL 0:d92f9d21154c 6805 ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
wolfSSL 0:d92f9d21154c 6806 #endif
wolfSSL 0:d92f9d21154c 6807
wolfSSL 0:d92f9d21154c 6808 XMEMSET(seq, 0, SEQ_SZ);
wolfSSL 0:d92f9d21154c 6809 conLen[0] = (byte)content;
wolfSSL 0:d92f9d21154c 6810 c16toa((word16)sz, &conLen[ENUM_LEN]);
wolfSSL 0:d92f9d21154c 6811 c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]);
wolfSSL 0:d92f9d21154c 6812
wolfSSL 0:d92f9d21154c 6813 if (ssl->specs.mac_algorithm == md5_mac) {
wolfSSL 0:d92f9d21154c 6814 wc_InitMd5(&md5);
wolfSSL 0:d92f9d21154c 6815 /* inner */
wolfSSL 0:d92f9d21154c 6816 wc_Md5Update(&md5, macSecret, digestSz);
wolfSSL 0:d92f9d21154c 6817 wc_Md5Update(&md5, PAD1, padSz);
wolfSSL 0:d92f9d21154c 6818 wc_Md5Update(&md5, seq, SEQ_SZ);
wolfSSL 0:d92f9d21154c 6819 wc_Md5Update(&md5, conLen, sizeof(conLen));
wolfSSL 0:d92f9d21154c 6820 /* in buffer */
wolfSSL 0:d92f9d21154c 6821 wc_Md5Update(&md5, in, sz);
wolfSSL 0:d92f9d21154c 6822 wc_Md5Final(&md5, result);
wolfSSL 0:d92f9d21154c 6823 /* outer */
wolfSSL 0:d92f9d21154c 6824 wc_Md5Update(&md5, macSecret, digestSz);
wolfSSL 0:d92f9d21154c 6825 wc_Md5Update(&md5, PAD2, padSz);
wolfSSL 0:d92f9d21154c 6826 wc_Md5Update(&md5, result, digestSz);
wolfSSL 0:d92f9d21154c 6827 wc_Md5Final(&md5, digest);
wolfSSL 0:d92f9d21154c 6828 }
wolfSSL 0:d92f9d21154c 6829 else {
wolfSSL 0:d92f9d21154c 6830 ret = wc_InitSha(&sha);
wolfSSL 0:d92f9d21154c 6831 if (ret != 0)
wolfSSL 0:d92f9d21154c 6832 return ret;
wolfSSL 0:d92f9d21154c 6833 /* inner */
wolfSSL 0:d92f9d21154c 6834 wc_ShaUpdate(&sha, macSecret, digestSz);
wolfSSL 0:d92f9d21154c 6835 wc_ShaUpdate(&sha, PAD1, padSz);
wolfSSL 0:d92f9d21154c 6836 wc_ShaUpdate(&sha, seq, SEQ_SZ);
wolfSSL 0:d92f9d21154c 6837 wc_ShaUpdate(&sha, conLen, sizeof(conLen));
wolfSSL 0:d92f9d21154c 6838 /* in buffer */
wolfSSL 0:d92f9d21154c 6839 wc_ShaUpdate(&sha, in, sz);
wolfSSL 0:d92f9d21154c 6840 wc_ShaFinal(&sha, result);
wolfSSL 0:d92f9d21154c 6841 /* outer */
wolfSSL 0:d92f9d21154c 6842 wc_ShaUpdate(&sha, macSecret, digestSz);
wolfSSL 0:d92f9d21154c 6843 wc_ShaUpdate(&sha, PAD2, padSz);
wolfSSL 0:d92f9d21154c 6844 wc_ShaUpdate(&sha, result, digestSz);
wolfSSL 0:d92f9d21154c 6845 wc_ShaFinal(&sha, digest);
wolfSSL 0:d92f9d21154c 6846 }
wolfSSL 0:d92f9d21154c 6847 return 0;
wolfSSL 0:d92f9d21154c 6848 }
wolfSSL 0:d92f9d21154c 6849
wolfSSL 0:d92f9d21154c 6850 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 6851 static void BuildMD5_CertVerify(WOLFSSL* ssl, byte* digest)
wolfSSL 0:d92f9d21154c 6852 {
wolfSSL 0:d92f9d21154c 6853 byte md5_result[MD5_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 6854
wolfSSL 0:d92f9d21154c 6855 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 6856 Md5* md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 6857 Md5* md5_2 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 6858 #else
wolfSSL 0:d92f9d21154c 6859 Md5 md5[1];
wolfSSL 0:d92f9d21154c 6860 Md5 md5_2[1];
wolfSSL 0:d92f9d21154c 6861 #endif
wolfSSL 0:d92f9d21154c 6862
wolfSSL 0:d92f9d21154c 6863 /* make md5 inner */
wolfSSL 0:d92f9d21154c 6864 md5[0] = ssl->hsHashes->hashMd5 ; /* Save current position */
wolfSSL 0:d92f9d21154c 6865 wc_Md5Update(&ssl->hsHashes->hashMd5, ssl->arrays->masterSecret,SECRET_LEN);
wolfSSL 0:d92f9d21154c 6866 wc_Md5Update(&ssl->hsHashes->hashMd5, PAD1, PAD_MD5);
wolfSSL 0:d92f9d21154c 6867 wc_Md5GetHash(&ssl->hsHashes->hashMd5, md5_result);
wolfSSL 0:d92f9d21154c 6868 wc_Md5RestorePos(&ssl->hsHashes->hashMd5, md5) ; /* Restore current position */
wolfSSL 0:d92f9d21154c 6869
wolfSSL 0:d92f9d21154c 6870 /* make md5 outer */
wolfSSL 0:d92f9d21154c 6871 wc_InitMd5(md5_2) ;
wolfSSL 0:d92f9d21154c 6872 wc_Md5Update(md5_2, ssl->arrays->masterSecret, SECRET_LEN);
wolfSSL 0:d92f9d21154c 6873 wc_Md5Update(md5_2, PAD2, PAD_MD5);
wolfSSL 0:d92f9d21154c 6874 wc_Md5Update(md5_2, md5_result, MD5_DIGEST_SIZE);
wolfSSL 0:d92f9d21154c 6875
wolfSSL 0:d92f9d21154c 6876 wc_Md5Final(md5_2, digest);
wolfSSL 0:d92f9d21154c 6877
wolfSSL 0:d92f9d21154c 6878 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 6879 XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 6880 XFREE(md5_2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 6881 #endif
wolfSSL 0:d92f9d21154c 6882 }
wolfSSL 0:d92f9d21154c 6883
wolfSSL 0:d92f9d21154c 6884
wolfSSL 0:d92f9d21154c 6885 static void BuildSHA_CertVerify(WOLFSSL* ssl, byte* digest)
wolfSSL 0:d92f9d21154c 6886 {
wolfSSL 0:d92f9d21154c 6887 byte sha_result[SHA_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 6888
wolfSSL 0:d92f9d21154c 6889 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 6890 Sha* sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 6891 Sha* sha2 = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 6892 #else
wolfSSL 0:d92f9d21154c 6893 Sha sha[1];
wolfSSL 0:d92f9d21154c 6894 Sha sha2[1];
wolfSSL 0:d92f9d21154c 6895 #endif
wolfSSL 0:d92f9d21154c 6896
wolfSSL 0:d92f9d21154c 6897 /* make sha inner */
wolfSSL 0:d92f9d21154c 6898 sha[0] = ssl->hsHashes->hashSha ; /* Save current position */
wolfSSL 0:d92f9d21154c 6899 wc_ShaUpdate(&ssl->hsHashes->hashSha, ssl->arrays->masterSecret,SECRET_LEN);
wolfSSL 0:d92f9d21154c 6900 wc_ShaUpdate(&ssl->hsHashes->hashSha, PAD1, PAD_SHA);
wolfSSL 0:d92f9d21154c 6901 wc_ShaGetHash(&ssl->hsHashes->hashSha, sha_result);
wolfSSL 0:d92f9d21154c 6902 wc_ShaRestorePos(&ssl->hsHashes->hashSha, sha) ; /* Restore current position */
wolfSSL 0:d92f9d21154c 6903
wolfSSL 0:d92f9d21154c 6904 /* make sha outer */
wolfSSL 0:d92f9d21154c 6905 wc_InitSha(sha2) ;
wolfSSL 0:d92f9d21154c 6906 wc_ShaUpdate(sha2, ssl->arrays->masterSecret,SECRET_LEN);
wolfSSL 0:d92f9d21154c 6907 wc_ShaUpdate(sha2, PAD2, PAD_SHA);
wolfSSL 0:d92f9d21154c 6908 wc_ShaUpdate(sha2, sha_result, SHA_DIGEST_SIZE);
wolfSSL 0:d92f9d21154c 6909
wolfSSL 0:d92f9d21154c 6910 wc_ShaFinal(sha2, digest);
wolfSSL 0:d92f9d21154c 6911
wolfSSL 0:d92f9d21154c 6912 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 6913 XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 6914 XFREE(sha2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 6915 #endif
wolfSSL 0:d92f9d21154c 6916
wolfSSL 0:d92f9d21154c 6917 }
wolfSSL 0:d92f9d21154c 6918 #endif /* NO_CERTS */
wolfSSL 0:d92f9d21154c 6919 #endif /* NO_OLD_TLS */
wolfSSL 0:d92f9d21154c 6920
wolfSSL 0:d92f9d21154c 6921
wolfSSL 0:d92f9d21154c 6922 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 6923
wolfSSL 0:d92f9d21154c 6924 static int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes)
wolfSSL 0:d92f9d21154c 6925 {
wolfSSL 0:d92f9d21154c 6926 /* store current states, building requires get_digest which resets state */
wolfSSL 0:d92f9d21154c 6927 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 6928 Sha384 sha384 = ssl->hsHashes->hashSha384;
wolfSSL 0:d92f9d21154c 6929 #endif
wolfSSL 0:d92f9d21154c 6930 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 6931 Sha512 sha512 = ssl->hsHashes->hashSha512;
wolfSSL 0:d92f9d21154c 6932 #endif
wolfSSL 0:d92f9d21154c 6933
wolfSSL 0:d92f9d21154c 6934 if (ssl->options.tls) {
wolfSSL 0:d92f9d21154c 6935 #if ! defined( NO_OLD_TLS )
wolfSSL 0:d92f9d21154c 6936 wc_Md5GetHash(&ssl->hsHashes->hashMd5, hashes->md5);
wolfSSL 0:d92f9d21154c 6937 wc_ShaGetHash(&ssl->hsHashes->hashSha, hashes->sha);
wolfSSL 0:d92f9d21154c 6938 #endif
wolfSSL 0:d92f9d21154c 6939 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 6940 int ret;
wolfSSL 0:d92f9d21154c 6941
wolfSSL 0:d92f9d21154c 6942 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 6943 ret = wc_Sha256GetHash(&ssl->hsHashes->hashSha256,hashes->sha256);
wolfSSL 0:d92f9d21154c 6944 if (ret != 0)
wolfSSL 0:d92f9d21154c 6945 return ret;
wolfSSL 0:d92f9d21154c 6946 #endif
wolfSSL 0:d92f9d21154c 6947 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 6948 ret = wc_Sha384Final(&ssl->hsHashes->hashSha384,hashes->sha384);
wolfSSL 0:d92f9d21154c 6949 if (ret != 0)
wolfSSL 0:d92f9d21154c 6950 return ret;
wolfSSL 0:d92f9d21154c 6951 #endif
wolfSSL 0:d92f9d21154c 6952 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 6953 ret = wc_Sha512Final(&ssl->hsHashes->hashSha512,hashes->sha512);
wolfSSL 0:d92f9d21154c 6954 if (ret != 0)
wolfSSL 0:d92f9d21154c 6955 return ret;
wolfSSL 0:d92f9d21154c 6956 #endif
wolfSSL 0:d92f9d21154c 6957 }
wolfSSL 0:d92f9d21154c 6958 }
wolfSSL 0:d92f9d21154c 6959 #if ! defined( NO_OLD_TLS )
wolfSSL 0:d92f9d21154c 6960 else {
wolfSSL 0:d92f9d21154c 6961 BuildMD5_CertVerify(ssl, hashes->md5);
wolfSSL 0:d92f9d21154c 6962 BuildSHA_CertVerify(ssl, hashes->sha);
wolfSSL 0:d92f9d21154c 6963 }
wolfSSL 0:d92f9d21154c 6964
wolfSSL 0:d92f9d21154c 6965 /* restore */
wolfSSL 0:d92f9d21154c 6966 #endif
wolfSSL 0:d92f9d21154c 6967 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 6968 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 6969 ssl->hsHashes->hashSha384 = sha384;
wolfSSL 0:d92f9d21154c 6970 #endif
wolfSSL 0:d92f9d21154c 6971 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 6972 ssl->hsHashes->hashSha512 = sha512;
wolfSSL 0:d92f9d21154c 6973 #endif
wolfSSL 0:d92f9d21154c 6974 }
wolfSSL 0:d92f9d21154c 6975
wolfSSL 0:d92f9d21154c 6976 return 0;
wolfSSL 0:d92f9d21154c 6977 }
wolfSSL 0:d92f9d21154c 6978
wolfSSL 0:d92f9d21154c 6979 #endif /* WOLFSSL_LEANPSK */
wolfSSL 0:d92f9d21154c 6980
wolfSSL 0:d92f9d21154c 6981 /* Build SSL Message, encrypted */
wolfSSL 0:d92f9d21154c 6982 static int BuildMessage(WOLFSSL* ssl, byte* output, int outSz,
wolfSSL 0:d92f9d21154c 6983 const byte* input, int inSz, int type)
wolfSSL 0:d92f9d21154c 6984 {
wolfSSL 0:d92f9d21154c 6985 #ifdef HAVE_TRUNCATED_HMAC
wolfSSL 0:d92f9d21154c 6986 word32 digestSz = min(ssl->specs.hash_size,
wolfSSL 0:d92f9d21154c 6987 ssl->truncated_hmac ? TRUNCATED_HMAC_SZ : ssl->specs.hash_size);
wolfSSL 0:d92f9d21154c 6988 #else
wolfSSL 0:d92f9d21154c 6989 word32 digestSz = ssl->specs.hash_size;
wolfSSL 0:d92f9d21154c 6990 #endif
wolfSSL 0:d92f9d21154c 6991 word32 sz = RECORD_HEADER_SZ + inSz + digestSz;
wolfSSL 0:d92f9d21154c 6992 word32 pad = 0, i;
wolfSSL 0:d92f9d21154c 6993 word32 idx = RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 6994 word32 ivSz = 0; /* TLSv1.1 IV */
wolfSSL 0:d92f9d21154c 6995 word32 headerSz = RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 6996 word16 size;
wolfSSL 0:d92f9d21154c 6997 byte iv[AES_BLOCK_SIZE]; /* max size */
wolfSSL 0:d92f9d21154c 6998 int ret = 0;
wolfSSL 0:d92f9d21154c 6999 int atomicUser = 0;
wolfSSL 0:d92f9d21154c 7000
wolfSSL 0:d92f9d21154c 7001 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7002 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 7003 sz += DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 7004 idx += DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 7005 headerSz += DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 7006 }
wolfSSL 0:d92f9d21154c 7007 #endif
wolfSSL 0:d92f9d21154c 7008
wolfSSL 0:d92f9d21154c 7009 #ifdef ATOMIC_USER
wolfSSL 0:d92f9d21154c 7010 if (ssl->ctx->MacEncryptCb)
wolfSSL 0:d92f9d21154c 7011 atomicUser = 1;
wolfSSL 0:d92f9d21154c 7012 #endif
wolfSSL 0:d92f9d21154c 7013
wolfSSL 0:d92f9d21154c 7014 if (ssl->specs.cipher_type == block) {
wolfSSL 0:d92f9d21154c 7015 word32 blockSz = ssl->specs.block_size;
wolfSSL 0:d92f9d21154c 7016 if (ssl->options.tls1_1) {
wolfSSL 0:d92f9d21154c 7017 ivSz = blockSz;
wolfSSL 0:d92f9d21154c 7018 sz += ivSz;
wolfSSL 0:d92f9d21154c 7019
wolfSSL 0:d92f9d21154c 7020 if (ivSz > (word32)sizeof(iv))
wolfSSL 0:d92f9d21154c 7021 return BUFFER_E;
wolfSSL 0:d92f9d21154c 7022
wolfSSL 0:d92f9d21154c 7023 ret = wc_RNG_GenerateBlock(ssl->rng, iv, ivSz);
wolfSSL 0:d92f9d21154c 7024 if (ret != 0)
wolfSSL 0:d92f9d21154c 7025 return ret;
wolfSSL 0:d92f9d21154c 7026
wolfSSL 0:d92f9d21154c 7027 }
wolfSSL 0:d92f9d21154c 7028 sz += 1; /* pad byte */
wolfSSL 0:d92f9d21154c 7029 pad = (sz - headerSz) % blockSz;
wolfSSL 0:d92f9d21154c 7030 pad = blockSz - pad;
wolfSSL 0:d92f9d21154c 7031 sz += pad;
wolfSSL 0:d92f9d21154c 7032 }
wolfSSL 0:d92f9d21154c 7033
wolfSSL 0:d92f9d21154c 7034 #ifdef HAVE_AEAD
wolfSSL 0:d92f9d21154c 7035 if (ssl->specs.cipher_type == aead) {
wolfSSL 0:d92f9d21154c 7036 if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha)
wolfSSL 0:d92f9d21154c 7037 ivSz = AEAD_EXP_IV_SZ;
wolfSSL 0:d92f9d21154c 7038
wolfSSL 0:d92f9d21154c 7039 sz += (ivSz + ssl->specs.aead_mac_size - digestSz);
wolfSSL 0:d92f9d21154c 7040 XMEMCPY(iv, ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ);
wolfSSL 0:d92f9d21154c 7041 }
wolfSSL 0:d92f9d21154c 7042 #endif
wolfSSL 0:d92f9d21154c 7043 if (sz > (word32)outSz) {
wolfSSL 0:d92f9d21154c 7044 WOLFSSL_MSG("Oops, want to write past output buffer size");
wolfSSL 0:d92f9d21154c 7045 return BUFFER_E;
wolfSSL 0:d92f9d21154c 7046 }
wolfSSL 0:d92f9d21154c 7047 size = (word16)(sz - headerSz); /* include mac and digest */
wolfSSL 0:d92f9d21154c 7048 AddRecordHeader(output, size, (byte)type, ssl);
wolfSSL 0:d92f9d21154c 7049
wolfSSL 0:d92f9d21154c 7050 /* write to output */
wolfSSL 0:d92f9d21154c 7051 if (ivSz) {
wolfSSL 0:d92f9d21154c 7052 XMEMCPY(output + idx, iv, min(ivSz, sizeof(iv)));
wolfSSL 0:d92f9d21154c 7053 idx += ivSz;
wolfSSL 0:d92f9d21154c 7054 }
wolfSSL 0:d92f9d21154c 7055 XMEMCPY(output + idx, input, inSz);
wolfSSL 0:d92f9d21154c 7056 idx += inSz;
wolfSSL 0:d92f9d21154c 7057
wolfSSL 0:d92f9d21154c 7058 if (type == handshake) {
wolfSSL 0:d92f9d21154c 7059 ret = HashOutput(ssl, output, headerSz + inSz, ivSz);
wolfSSL 0:d92f9d21154c 7060 if (ret != 0)
wolfSSL 0:d92f9d21154c 7061 return ret;
wolfSSL 0:d92f9d21154c 7062 }
wolfSSL 0:d92f9d21154c 7063
wolfSSL 0:d92f9d21154c 7064 if (ssl->specs.cipher_type == block) {
wolfSSL 0:d92f9d21154c 7065 word32 tmpIdx = idx + digestSz;
wolfSSL 0:d92f9d21154c 7066
wolfSSL 0:d92f9d21154c 7067 for (i = 0; i <= pad; i++)
wolfSSL 0:d92f9d21154c 7068 output[tmpIdx++] = (byte)pad; /* pad byte gets pad value too */
wolfSSL 0:d92f9d21154c 7069 }
wolfSSL 0:d92f9d21154c 7070
wolfSSL 0:d92f9d21154c 7071 if (atomicUser) { /* User Record Layer Callback handling */
wolfSSL 0:d92f9d21154c 7072 #ifdef ATOMIC_USER
wolfSSL 0:d92f9d21154c 7073 if ( (ret = ssl->ctx->MacEncryptCb(ssl, output + idx,
wolfSSL 0:d92f9d21154c 7074 output + headerSz + ivSz, inSz, type, 0,
wolfSSL 0:d92f9d21154c 7075 output + headerSz, output + headerSz, size,
wolfSSL 0:d92f9d21154c 7076 ssl->MacEncryptCtx)) != 0)
wolfSSL 0:d92f9d21154c 7077 return ret;
wolfSSL 0:d92f9d21154c 7078 #endif
wolfSSL 0:d92f9d21154c 7079 }
wolfSSL 0:d92f9d21154c 7080 else {
wolfSSL 0:d92f9d21154c 7081 if (ssl->specs.cipher_type != aead) {
wolfSSL 0:d92f9d21154c 7082 #ifdef HAVE_TRUNCATED_HMAC
wolfSSL 0:d92f9d21154c 7083 if (ssl->truncated_hmac && ssl->specs.hash_size > digestSz) {
wolfSSL 0:d92f9d21154c 7084 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 7085 byte* hmac = NULL;
wolfSSL 0:d92f9d21154c 7086 #else
wolfSSL 0:d92f9d21154c 7087 byte hmac[MAX_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 7088 #endif
wolfSSL 0:d92f9d21154c 7089
wolfSSL 0:d92f9d21154c 7090 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 7091 hmac = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL,
wolfSSL 0:d92f9d21154c 7092 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 7093 if (hmac == NULL)
wolfSSL 0:d92f9d21154c 7094 return MEMORY_E;
wolfSSL 0:d92f9d21154c 7095 #endif
wolfSSL 0:d92f9d21154c 7096
wolfSSL 0:d92f9d21154c 7097 ret = ssl->hmac(ssl, hmac, output + headerSz + ivSz, inSz,
wolfSSL 0:d92f9d21154c 7098 type, 0);
wolfSSL 0:d92f9d21154c 7099 XMEMCPY(output + idx, hmac, digestSz);
wolfSSL 0:d92f9d21154c 7100
wolfSSL 0:d92f9d21154c 7101 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 7102 XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 7103 #endif
wolfSSL 0:d92f9d21154c 7104 } else
wolfSSL 0:d92f9d21154c 7105 #endif
wolfSSL 0:d92f9d21154c 7106 ret = ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz,
wolfSSL 0:d92f9d21154c 7107 type, 0);
wolfSSL 0:d92f9d21154c 7108 }
wolfSSL 0:d92f9d21154c 7109 if (ret != 0)
wolfSSL 0:d92f9d21154c 7110 return ret;
wolfSSL 0:d92f9d21154c 7111
wolfSSL 0:d92f9d21154c 7112 if ( (ret = Encrypt(ssl, output + headerSz, output+headerSz,size)) != 0)
wolfSSL 0:d92f9d21154c 7113 return ret;
wolfSSL 0:d92f9d21154c 7114 }
wolfSSL 0:d92f9d21154c 7115
wolfSSL 0:d92f9d21154c 7116 return sz;
wolfSSL 0:d92f9d21154c 7117 }
wolfSSL 0:d92f9d21154c 7118
wolfSSL 0:d92f9d21154c 7119
wolfSSL 0:d92f9d21154c 7120 int SendFinished(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 7121 {
wolfSSL 0:d92f9d21154c 7122 int sendSz,
wolfSSL 0:d92f9d21154c 7123 finishedSz = ssl->options.tls ? TLS_FINISHED_SZ :
wolfSSL 0:d92f9d21154c 7124 FINISHED_SZ;
wolfSSL 0:d92f9d21154c 7125 byte input[FINISHED_SZ + DTLS_HANDSHAKE_HEADER_SZ]; /* max */
wolfSSL 0:d92f9d21154c 7126 byte *output;
wolfSSL 0:d92f9d21154c 7127 Hashes* hashes;
wolfSSL 0:d92f9d21154c 7128 int ret;
wolfSSL 0:d92f9d21154c 7129 int headerSz = HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 7130 int outputSz;
wolfSSL 0:d92f9d21154c 7131
wolfSSL 0:d92f9d21154c 7132 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7133 word32 sequence_number = ssl->keys.dtls_sequence_number;
wolfSSL 0:d92f9d21154c 7134 word16 epoch = ssl->keys.dtls_epoch;
wolfSSL 0:d92f9d21154c 7135 #endif
wolfSSL 0:d92f9d21154c 7136
wolfSSL 0:d92f9d21154c 7137 /* setup encrypt keys */
wolfSSL 0:d92f9d21154c 7138 if ((ret = SetKeysSide(ssl, ENCRYPT_SIDE_ONLY)) != 0)
wolfSSL 0:d92f9d21154c 7139 return ret;
wolfSSL 0:d92f9d21154c 7140
wolfSSL 0:d92f9d21154c 7141 /* check for available size */
wolfSSL 0:d92f9d21154c 7142 outputSz = sizeof(input) + MAX_MSG_EXTRA;
wolfSSL 0:d92f9d21154c 7143 if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
wolfSSL 0:d92f9d21154c 7144 return ret;
wolfSSL 0:d92f9d21154c 7145
wolfSSL 0:d92f9d21154c 7146 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7147 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 7148 /* Send Finished message with the next epoch, but don't commit that
wolfSSL 0:d92f9d21154c 7149 * change until the other end confirms its reception. */
wolfSSL 0:d92f9d21154c 7150 headerSz += DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 7151 ssl->keys.dtls_epoch++;
wolfSSL 0:d92f9d21154c 7152 ssl->keys.dtls_sequence_number = 0; /* reset after epoch change */
wolfSSL 0:d92f9d21154c 7153 }
wolfSSL 0:d92f9d21154c 7154 #endif
wolfSSL 0:d92f9d21154c 7155
wolfSSL 0:d92f9d21154c 7156 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 7157 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 7158 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 7159
wolfSSL 0:d92f9d21154c 7160 AddHandShakeHeader(input, finishedSz, finished, ssl);
wolfSSL 0:d92f9d21154c 7161
wolfSSL 0:d92f9d21154c 7162 /* make finished hashes */
wolfSSL 0:d92f9d21154c 7163 hashes = (Hashes*)&input[headerSz];
wolfSSL 0:d92f9d21154c 7164 ret = BuildFinished(ssl, hashes,
wolfSSL 0:d92f9d21154c 7165 ssl->options.side == WOLFSSL_CLIENT_END ? client : server);
wolfSSL 0:d92f9d21154c 7166 if (ret != 0) return ret;
wolfSSL 0:d92f9d21154c 7167
wolfSSL 0:d92f9d21154c 7168 #ifdef HAVE_SECURE_RENEGOTIATION
wolfSSL 0:d92f9d21154c 7169 if (ssl->secure_renegotiation) {
wolfSSL 0:d92f9d21154c 7170 if (ssl->options.side == WOLFSSL_CLIENT_END)
wolfSSL 0:d92f9d21154c 7171 XMEMCPY(ssl->secure_renegotiation->client_verify_data, hashes,
wolfSSL 0:d92f9d21154c 7172 TLS_FINISHED_SZ);
wolfSSL 0:d92f9d21154c 7173 else
wolfSSL 0:d92f9d21154c 7174 XMEMCPY(ssl->secure_renegotiation->server_verify_data, hashes,
wolfSSL 0:d92f9d21154c 7175 TLS_FINISHED_SZ);
wolfSSL 0:d92f9d21154c 7176 }
wolfSSL 0:d92f9d21154c 7177 #endif
wolfSSL 0:d92f9d21154c 7178
wolfSSL 0:d92f9d21154c 7179 sendSz = BuildMessage(ssl, output, outputSz, input, headerSz + finishedSz,
wolfSSL 0:d92f9d21154c 7180 handshake);
wolfSSL 0:d92f9d21154c 7181 if (sendSz < 0)
wolfSSL 0:d92f9d21154c 7182 return BUILD_MSG_ERROR;
wolfSSL 0:d92f9d21154c 7183
wolfSSL 0:d92f9d21154c 7184 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7185 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 7186 ssl->keys.dtls_epoch = epoch;
wolfSSL 0:d92f9d21154c 7187 ssl->keys.dtls_sequence_number = sequence_number;
wolfSSL 0:d92f9d21154c 7188 }
wolfSSL 0:d92f9d21154c 7189 #endif
wolfSSL 0:d92f9d21154c 7190
wolfSSL 0:d92f9d21154c 7191 if (!ssl->options.resuming) {
wolfSSL 0:d92f9d21154c 7192 #ifndef NO_SESSION_CACHE
wolfSSL 0:d92f9d21154c 7193 AddSession(ssl); /* just try */
wolfSSL 0:d92f9d21154c 7194 #endif
wolfSSL 0:d92f9d21154c 7195 if (ssl->options.side == WOLFSSL_SERVER_END) {
wolfSSL 0:d92f9d21154c 7196 ssl->options.handShakeState = HANDSHAKE_DONE;
wolfSSL 0:d92f9d21154c 7197 ssl->options.handShakeDone = 1;
wolfSSL 0:d92f9d21154c 7198 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7199 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 7200 /* Other side will soon receive our Finished, go to next
wolfSSL 0:d92f9d21154c 7201 * epoch. */
wolfSSL 0:d92f9d21154c 7202 ssl->keys.dtls_epoch++;
wolfSSL 0:d92f9d21154c 7203 ssl->keys.dtls_sequence_number = 1;
wolfSSL 0:d92f9d21154c 7204 }
wolfSSL 0:d92f9d21154c 7205 #endif
wolfSSL 0:d92f9d21154c 7206 }
wolfSSL 0:d92f9d21154c 7207 }
wolfSSL 0:d92f9d21154c 7208 else {
wolfSSL 0:d92f9d21154c 7209 if (ssl->options.side == WOLFSSL_CLIENT_END) {
wolfSSL 0:d92f9d21154c 7210 ssl->options.handShakeState = HANDSHAKE_DONE;
wolfSSL 0:d92f9d21154c 7211 ssl->options.handShakeDone = 1;
wolfSSL 0:d92f9d21154c 7212 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7213 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 7214 /* Other side will soon receive our Finished, go to next
wolfSSL 0:d92f9d21154c 7215 * epoch. */
wolfSSL 0:d92f9d21154c 7216 ssl->keys.dtls_epoch++;
wolfSSL 0:d92f9d21154c 7217 ssl->keys.dtls_sequence_number = 1;
wolfSSL 0:d92f9d21154c 7218 }
wolfSSL 0:d92f9d21154c 7219 #endif
wolfSSL 0:d92f9d21154c 7220 }
wolfSSL 0:d92f9d21154c 7221 }
wolfSSL 0:d92f9d21154c 7222 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7223 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 7224 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 7225 return ret;
wolfSSL 0:d92f9d21154c 7226 }
wolfSSL 0:d92f9d21154c 7227 #endif
wolfSSL 0:d92f9d21154c 7228
wolfSSL 0:d92f9d21154c 7229 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 7230 if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 7231 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 7232 AddPacketInfo("Finished", &ssl->timeoutInfo, output, sendSz,
wolfSSL 0:d92f9d21154c 7233 ssl->heap);
wolfSSL 0:d92f9d21154c 7234 #endif
wolfSSL 0:d92f9d21154c 7235
wolfSSL 0:d92f9d21154c 7236 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 7237
wolfSSL 0:d92f9d21154c 7238 return SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 7239 }
wolfSSL 0:d92f9d21154c 7240
wolfSSL 0:d92f9d21154c 7241 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 7242 int SendCertificate(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 7243 {
wolfSSL 0:d92f9d21154c 7244 int sendSz, length, ret = 0;
wolfSSL 0:d92f9d21154c 7245 word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 7246 word32 certSz, listSz;
wolfSSL 0:d92f9d21154c 7247 byte* output = 0;
wolfSSL 0:d92f9d21154c 7248
wolfSSL 0:d92f9d21154c 7249 if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
wolfSSL 0:d92f9d21154c 7250 return 0; /* not needed */
wolfSSL 0:d92f9d21154c 7251
wolfSSL 0:d92f9d21154c 7252 if (ssl->options.sendVerify == SEND_BLANK_CERT) {
wolfSSL 0:d92f9d21154c 7253 certSz = 0;
wolfSSL 0:d92f9d21154c 7254 length = CERT_HEADER_SZ;
wolfSSL 0:d92f9d21154c 7255 listSz = 0;
wolfSSL 0:d92f9d21154c 7256 }
wolfSSL 0:d92f9d21154c 7257 else {
wolfSSL 0:d92f9d21154c 7258 certSz = ssl->buffers.certificate.length;
wolfSSL 0:d92f9d21154c 7259 /* list + cert size */
wolfSSL 0:d92f9d21154c 7260 length = certSz + 2 * CERT_HEADER_SZ;
wolfSSL 0:d92f9d21154c 7261 listSz = certSz + CERT_HEADER_SZ;
wolfSSL 0:d92f9d21154c 7262
wolfSSL 0:d92f9d21154c 7263 /* may need to send rest of chain, already has leading size(s) */
wolfSSL 0:d92f9d21154c 7264 if (ssl->buffers.certChain.buffer) {
wolfSSL 0:d92f9d21154c 7265 length += ssl->buffers.certChain.length;
wolfSSL 0:d92f9d21154c 7266 listSz += ssl->buffers.certChain.length;
wolfSSL 0:d92f9d21154c 7267 }
wolfSSL 0:d92f9d21154c 7268 }
wolfSSL 0:d92f9d21154c 7269 sendSz = length + RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 7270
wolfSSL 0:d92f9d21154c 7271 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7272 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 7273 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 7274 i += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 7275 }
wolfSSL 0:d92f9d21154c 7276 #endif
wolfSSL 0:d92f9d21154c 7277
wolfSSL 0:d92f9d21154c 7278 if (ssl->keys.encryptionOn)
wolfSSL 0:d92f9d21154c 7279 sendSz += MAX_MSG_EXTRA;
wolfSSL 0:d92f9d21154c 7280
wolfSSL 0:d92f9d21154c 7281 /* check for available size */
wolfSSL 0:d92f9d21154c 7282 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 7283 return ret;
wolfSSL 0:d92f9d21154c 7284
wolfSSL 0:d92f9d21154c 7285 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 7286 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 7287 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 7288
wolfSSL 0:d92f9d21154c 7289 AddHeaders(output, length, certificate, ssl);
wolfSSL 0:d92f9d21154c 7290
wolfSSL 0:d92f9d21154c 7291 /* list total */
wolfSSL 0:d92f9d21154c 7292 c32to24(listSz, output + i);
wolfSSL 0:d92f9d21154c 7293 i += CERT_HEADER_SZ;
wolfSSL 0:d92f9d21154c 7294
wolfSSL 0:d92f9d21154c 7295 /* member */
wolfSSL 0:d92f9d21154c 7296 if (certSz) {
wolfSSL 0:d92f9d21154c 7297 c32to24(certSz, output + i);
wolfSSL 0:d92f9d21154c 7298 i += CERT_HEADER_SZ;
wolfSSL 0:d92f9d21154c 7299 XMEMCPY(output + i, ssl->buffers.certificate.buffer, certSz);
wolfSSL 0:d92f9d21154c 7300 i += certSz;
wolfSSL 0:d92f9d21154c 7301
wolfSSL 0:d92f9d21154c 7302 /* send rest of chain? */
wolfSSL 0:d92f9d21154c 7303 if (ssl->buffers.certChain.buffer) {
wolfSSL 0:d92f9d21154c 7304 XMEMCPY(output + i, ssl->buffers.certChain.buffer,
wolfSSL 0:d92f9d21154c 7305 ssl->buffers.certChain.length);
wolfSSL 0:d92f9d21154c 7306 i += ssl->buffers.certChain.length;
wolfSSL 0:d92f9d21154c 7307 }
wolfSSL 0:d92f9d21154c 7308 }
wolfSSL 0:d92f9d21154c 7309
wolfSSL 0:d92f9d21154c 7310 if (ssl->keys.encryptionOn) {
wolfSSL 0:d92f9d21154c 7311 byte* input;
wolfSSL 0:d92f9d21154c 7312 int inputSz = i - RECORD_HEADER_SZ; /* build msg adds rec hdr */
wolfSSL 0:d92f9d21154c 7313
wolfSSL 0:d92f9d21154c 7314 input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 7315 if (input == NULL)
wolfSSL 0:d92f9d21154c 7316 return MEMORY_E;
wolfSSL 0:d92f9d21154c 7317
wolfSSL 0:d92f9d21154c 7318 XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
wolfSSL 0:d92f9d21154c 7319 sendSz = BuildMessage(ssl, output, sendSz, input,inputSz,handshake);
wolfSSL 0:d92f9d21154c 7320 XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 7321
wolfSSL 0:d92f9d21154c 7322 if (sendSz < 0)
wolfSSL 0:d92f9d21154c 7323 return sendSz;
wolfSSL 0:d92f9d21154c 7324 } else {
wolfSSL 0:d92f9d21154c 7325 ret = HashOutput(ssl, output, sendSz, 0);
wolfSSL 0:d92f9d21154c 7326 if (ret != 0)
wolfSSL 0:d92f9d21154c 7327 return ret;
wolfSSL 0:d92f9d21154c 7328 }
wolfSSL 0:d92f9d21154c 7329
wolfSSL 0:d92f9d21154c 7330 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7331 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 7332 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 7333 return ret;
wolfSSL 0:d92f9d21154c 7334 }
wolfSSL 0:d92f9d21154c 7335 #endif
wolfSSL 0:d92f9d21154c 7336
wolfSSL 0:d92f9d21154c 7337 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 7338 if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 7339 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 7340 AddPacketInfo("Certificate", &ssl->timeoutInfo, output, sendSz,
wolfSSL 0:d92f9d21154c 7341 ssl->heap);
wolfSSL 0:d92f9d21154c 7342 #endif
wolfSSL 0:d92f9d21154c 7343
wolfSSL 0:d92f9d21154c 7344 if (ssl->options.side == WOLFSSL_SERVER_END)
wolfSSL 0:d92f9d21154c 7345 ssl->options.serverState = SERVER_CERT_COMPLETE;
wolfSSL 0:d92f9d21154c 7346
wolfSSL 0:d92f9d21154c 7347 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 7348 if (ssl->options.groupMessages)
wolfSSL 0:d92f9d21154c 7349 return 0;
wolfSSL 0:d92f9d21154c 7350 else
wolfSSL 0:d92f9d21154c 7351 return SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 7352 }
wolfSSL 0:d92f9d21154c 7353
wolfSSL 0:d92f9d21154c 7354
wolfSSL 0:d92f9d21154c 7355 int SendCertificateRequest(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 7356 {
wolfSSL 0:d92f9d21154c 7357 byte *output;
wolfSSL 0:d92f9d21154c 7358 int ret;
wolfSSL 0:d92f9d21154c 7359 int sendSz;
wolfSSL 0:d92f9d21154c 7360 word32 i = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 7361
wolfSSL 0:d92f9d21154c 7362 int typeTotal = 1; /* only 1 for now */
wolfSSL 0:d92f9d21154c 7363 int reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ; /* add auth later */
wolfSSL 0:d92f9d21154c 7364
wolfSSL 0:d92f9d21154c 7365 if (IsAtLeastTLSv1_2(ssl))
wolfSSL 0:d92f9d21154c 7366 reqSz += LENGTH_SZ + ssl->suites->hashSigAlgoSz;
wolfSSL 0:d92f9d21154c 7367
wolfSSL 0:d92f9d21154c 7368 if (ssl->options.usingPSK_cipher || ssl->options.usingAnon_cipher)
wolfSSL 0:d92f9d21154c 7369 return 0; /* not needed */
wolfSSL 0:d92f9d21154c 7370
wolfSSL 0:d92f9d21154c 7371 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
wolfSSL 0:d92f9d21154c 7372
wolfSSL 0:d92f9d21154c 7373 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7374 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 7375 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 7376 i += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 7377 }
wolfSSL 0:d92f9d21154c 7378 #endif
wolfSSL 0:d92f9d21154c 7379 /* check for available size */
wolfSSL 0:d92f9d21154c 7380 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 7381 return ret;
wolfSSL 0:d92f9d21154c 7382
wolfSSL 0:d92f9d21154c 7383 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 7384 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 7385 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 7386
wolfSSL 0:d92f9d21154c 7387 AddHeaders(output, reqSz, certificate_request, ssl);
wolfSSL 0:d92f9d21154c 7388
wolfSSL 0:d92f9d21154c 7389 /* write to output */
wolfSSL 0:d92f9d21154c 7390 output[i++] = (byte)typeTotal; /* # of types */
wolfSSL 0:d92f9d21154c 7391 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 7392 if (ssl->options.cipherSuite0 == ECC_BYTE &&
wolfSSL 0:d92f9d21154c 7393 ssl->specs.sig_algo == ecc_dsa_sa_algo) {
wolfSSL 0:d92f9d21154c 7394 output[i++] = ecdsa_sign;
wolfSSL 0:d92f9d21154c 7395 } else
wolfSSL 0:d92f9d21154c 7396 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 7397 {
wolfSSL 0:d92f9d21154c 7398 output[i++] = rsa_sign;
wolfSSL 0:d92f9d21154c 7399 }
wolfSSL 0:d92f9d21154c 7400
wolfSSL 0:d92f9d21154c 7401 /* supported hash/sig */
wolfSSL 0:d92f9d21154c 7402 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 7403 c16toa(ssl->suites->hashSigAlgoSz, &output[i]);
wolfSSL 0:d92f9d21154c 7404 i += LENGTH_SZ;
wolfSSL 0:d92f9d21154c 7405
wolfSSL 0:d92f9d21154c 7406 XMEMCPY(&output[i],
wolfSSL 0:d92f9d21154c 7407 ssl->suites->hashSigAlgo, ssl->suites->hashSigAlgoSz);
wolfSSL 0:d92f9d21154c 7408 i += ssl->suites->hashSigAlgoSz;
wolfSSL 0:d92f9d21154c 7409 }
wolfSSL 0:d92f9d21154c 7410
wolfSSL 0:d92f9d21154c 7411 c16toa(0, &output[i]); /* auth's */
wolfSSL 0:d92f9d21154c 7412 /* if add more to output, adjust i
wolfSSL 0:d92f9d21154c 7413 i += REQ_HEADER_SZ; */
wolfSSL 0:d92f9d21154c 7414
wolfSSL 0:d92f9d21154c 7415 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7416 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 7417 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 7418 return ret;
wolfSSL 0:d92f9d21154c 7419 }
wolfSSL 0:d92f9d21154c 7420 #endif
wolfSSL 0:d92f9d21154c 7421
wolfSSL 0:d92f9d21154c 7422 ret = HashOutput(ssl, output, sendSz, 0);
wolfSSL 0:d92f9d21154c 7423 if (ret != 0)
wolfSSL 0:d92f9d21154c 7424 return ret;
wolfSSL 0:d92f9d21154c 7425
wolfSSL 0:d92f9d21154c 7426 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 7427 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 7428 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 7429 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 7430 AddPacketInfo("CertificateRequest", &ssl->timeoutInfo, output,
wolfSSL 0:d92f9d21154c 7431 sendSz, ssl->heap);
wolfSSL 0:d92f9d21154c 7432 #endif
wolfSSL 0:d92f9d21154c 7433 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 7434 if (ssl->options.groupMessages)
wolfSSL 0:d92f9d21154c 7435 return 0;
wolfSSL 0:d92f9d21154c 7436 else
wolfSSL 0:d92f9d21154c 7437 return SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 7438 }
wolfSSL 0:d92f9d21154c 7439 #endif /* !NO_CERTS */
wolfSSL 0:d92f9d21154c 7440
wolfSSL 0:d92f9d21154c 7441
wolfSSL 0:d92f9d21154c 7442 int SendData(WOLFSSL* ssl, const void* data, int sz)
wolfSSL 0:d92f9d21154c 7443 {
wolfSSL 0:d92f9d21154c 7444 int sent = 0, /* plainText size */
wolfSSL 0:d92f9d21154c 7445 sendSz,
wolfSSL 0:d92f9d21154c 7446 ret,
wolfSSL 0:d92f9d21154c 7447 dtlsExtra = 0;
wolfSSL 0:d92f9d21154c 7448
wolfSSL 0:d92f9d21154c 7449 if (ssl->error == WANT_WRITE)
wolfSSL 0:d92f9d21154c 7450 ssl->error = 0;
wolfSSL 0:d92f9d21154c 7451
wolfSSL 0:d92f9d21154c 7452 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
wolfSSL 0:d92f9d21154c 7453 int err;
wolfSSL 0:d92f9d21154c 7454 WOLFSSL_MSG("handshake not complete, trying to finish");
wolfSSL 0:d92f9d21154c 7455 if ( (err = wolfSSL_negotiate(ssl)) != SSL_SUCCESS)
wolfSSL 0:d92f9d21154c 7456 return err;
wolfSSL 0:d92f9d21154c 7457 }
wolfSSL 0:d92f9d21154c 7458
wolfSSL 0:d92f9d21154c 7459 /* last time system socket output buffer was full, try again to send */
wolfSSL 0:d92f9d21154c 7460 if (ssl->buffers.outputBuffer.length > 0) {
wolfSSL 0:d92f9d21154c 7461 WOLFSSL_MSG("output buffer was full, trying to send again");
wolfSSL 0:d92f9d21154c 7462 if ( (ssl->error = SendBuffered(ssl)) < 0) {
wolfSSL 0:d92f9d21154c 7463 WOLFSSL_ERROR(ssl->error);
wolfSSL 0:d92f9d21154c 7464 if (ssl->error == SOCKET_ERROR_E && ssl->options.connReset)
wolfSSL 0:d92f9d21154c 7465 return 0; /* peer reset */
wolfSSL 0:d92f9d21154c 7466 return ssl->error;
wolfSSL 0:d92f9d21154c 7467 }
wolfSSL 0:d92f9d21154c 7468 else {
wolfSSL 0:d92f9d21154c 7469 /* advance sent to previous sent + plain size just sent */
wolfSSL 0:d92f9d21154c 7470 sent = ssl->buffers.prevSent + ssl->buffers.plainSz;
wolfSSL 0:d92f9d21154c 7471 WOLFSSL_MSG("sent write buffered data");
wolfSSL 0:d92f9d21154c 7472
wolfSSL 0:d92f9d21154c 7473 if (sent > sz) {
wolfSSL 0:d92f9d21154c 7474 WOLFSSL_MSG("error: write() after WANT_WRITE with short size");
wolfSSL 0:d92f9d21154c 7475 return ssl->error = BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 7476 }
wolfSSL 0:d92f9d21154c 7477 }
wolfSSL 0:d92f9d21154c 7478 }
wolfSSL 0:d92f9d21154c 7479
wolfSSL 0:d92f9d21154c 7480 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7481 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 7482 dtlsExtra = DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 7483 }
wolfSSL 0:d92f9d21154c 7484 #endif
wolfSSL 0:d92f9d21154c 7485
wolfSSL 0:d92f9d21154c 7486 for (;;) {
wolfSSL 0:d92f9d21154c 7487 #ifdef HAVE_MAX_FRAGMENT
wolfSSL 0:d92f9d21154c 7488 int len = min(sz - sent, min(ssl->max_fragment, OUTPUT_RECORD_SIZE));
wolfSSL 0:d92f9d21154c 7489 #else
wolfSSL 0:d92f9d21154c 7490 int len = min(sz - sent, OUTPUT_RECORD_SIZE);
wolfSSL 0:d92f9d21154c 7491 #endif
wolfSSL 0:d92f9d21154c 7492 byte* out;
wolfSSL 0:d92f9d21154c 7493 byte* sendBuffer = (byte*)data + sent; /* may switch on comp */
wolfSSL 0:d92f9d21154c 7494 int buffSz = len; /* may switch on comp */
wolfSSL 0:d92f9d21154c 7495 int outputSz;
wolfSSL 0:d92f9d21154c 7496 #ifdef HAVE_LIBZ
wolfSSL 0:d92f9d21154c 7497 byte comp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
wolfSSL 0:d92f9d21154c 7498 #endif
wolfSSL 0:d92f9d21154c 7499
wolfSSL 0:d92f9d21154c 7500 if (sent == sz) break;
wolfSSL 0:d92f9d21154c 7501
wolfSSL 0:d92f9d21154c 7502 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7503 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 7504 len = min(len, MAX_UDP_SIZE);
wolfSSL 0:d92f9d21154c 7505 buffSz = len;
wolfSSL 0:d92f9d21154c 7506 }
wolfSSL 0:d92f9d21154c 7507 #endif
wolfSSL 0:d92f9d21154c 7508
wolfSSL 0:d92f9d21154c 7509 /* check for available size */
wolfSSL 0:d92f9d21154c 7510 outputSz = len + COMP_EXTRA + dtlsExtra + MAX_MSG_EXTRA;
wolfSSL 0:d92f9d21154c 7511 if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
wolfSSL 0:d92f9d21154c 7512 return ssl->error = ret;
wolfSSL 0:d92f9d21154c 7513
wolfSSL 0:d92f9d21154c 7514 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 7515 out = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 7516 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 7517
wolfSSL 0:d92f9d21154c 7518 #ifdef HAVE_LIBZ
wolfSSL 0:d92f9d21154c 7519 if (ssl->options.usingCompression) {
wolfSSL 0:d92f9d21154c 7520 buffSz = myCompress(ssl, sendBuffer, buffSz, comp, sizeof(comp));
wolfSSL 0:d92f9d21154c 7521 if (buffSz < 0) {
wolfSSL 0:d92f9d21154c 7522 return buffSz;
wolfSSL 0:d92f9d21154c 7523 }
wolfSSL 0:d92f9d21154c 7524 sendBuffer = comp;
wolfSSL 0:d92f9d21154c 7525 }
wolfSSL 0:d92f9d21154c 7526 #endif
wolfSSL 0:d92f9d21154c 7527 sendSz = BuildMessage(ssl, out, outputSz, sendBuffer, buffSz,
wolfSSL 0:d92f9d21154c 7528 application_data);
wolfSSL 0:d92f9d21154c 7529 if (sendSz < 0)
wolfSSL 0:d92f9d21154c 7530 return BUILD_MSG_ERROR;
wolfSSL 0:d92f9d21154c 7531
wolfSSL 0:d92f9d21154c 7532 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 7533
wolfSSL 0:d92f9d21154c 7534 if ( (ret = SendBuffered(ssl)) < 0) {
wolfSSL 0:d92f9d21154c 7535 WOLFSSL_ERROR(ret);
wolfSSL 0:d92f9d21154c 7536 /* store for next call if WANT_WRITE or user embedSend() that
wolfSSL 0:d92f9d21154c 7537 doesn't present like WANT_WRITE */
wolfSSL 0:d92f9d21154c 7538 ssl->buffers.plainSz = len;
wolfSSL 0:d92f9d21154c 7539 ssl->buffers.prevSent = sent;
wolfSSL 0:d92f9d21154c 7540 if (ret == SOCKET_ERROR_E && ssl->options.connReset)
wolfSSL 0:d92f9d21154c 7541 return 0; /* peer reset */
wolfSSL 0:d92f9d21154c 7542 return ssl->error = ret;
wolfSSL 0:d92f9d21154c 7543 }
wolfSSL 0:d92f9d21154c 7544
wolfSSL 0:d92f9d21154c 7545 sent += len;
wolfSSL 0:d92f9d21154c 7546
wolfSSL 0:d92f9d21154c 7547 /* only one message per attempt */
wolfSSL 0:d92f9d21154c 7548 if (ssl->options.partialWrite == 1) {
wolfSSL 0:d92f9d21154c 7549 WOLFSSL_MSG("Paritial Write on, only sending one record");
wolfSSL 0:d92f9d21154c 7550 break;
wolfSSL 0:d92f9d21154c 7551 }
wolfSSL 0:d92f9d21154c 7552 }
wolfSSL 0:d92f9d21154c 7553
wolfSSL 0:d92f9d21154c 7554 return sent;
wolfSSL 0:d92f9d21154c 7555 }
wolfSSL 0:d92f9d21154c 7556
wolfSSL 0:d92f9d21154c 7557 /* process input data */
wolfSSL 0:d92f9d21154c 7558 int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek)
wolfSSL 0:d92f9d21154c 7559 {
wolfSSL 0:d92f9d21154c 7560 int size;
wolfSSL 0:d92f9d21154c 7561
wolfSSL 0:d92f9d21154c 7562 WOLFSSL_ENTER("ReceiveData()");
wolfSSL 0:d92f9d21154c 7563
wolfSSL 0:d92f9d21154c 7564 if (ssl->error == WANT_READ)
wolfSSL 0:d92f9d21154c 7565 ssl->error = 0;
wolfSSL 0:d92f9d21154c 7566
wolfSSL 0:d92f9d21154c 7567 if (ssl->error != 0 && ssl->error != WANT_WRITE) {
wolfSSL 0:d92f9d21154c 7568 WOLFSSL_MSG("User calling wolfSSL_read in error state, not allowed");
wolfSSL 0:d92f9d21154c 7569 return ssl->error;
wolfSSL 0:d92f9d21154c 7570 }
wolfSSL 0:d92f9d21154c 7571
wolfSSL 0:d92f9d21154c 7572 if (ssl->options.handShakeState != HANDSHAKE_DONE) {
wolfSSL 0:d92f9d21154c 7573 int err;
wolfSSL 0:d92f9d21154c 7574 WOLFSSL_MSG("Handshake not complete, trying to finish");
wolfSSL 0:d92f9d21154c 7575 if ( (err = wolfSSL_negotiate(ssl)) != SSL_SUCCESS)
wolfSSL 0:d92f9d21154c 7576 return err;
wolfSSL 0:d92f9d21154c 7577 }
wolfSSL 0:d92f9d21154c 7578
wolfSSL 0:d92f9d21154c 7579 #ifdef HAVE_SECURE_RENEGOTIATION
wolfSSL 0:d92f9d21154c 7580 startScr:
wolfSSL 0:d92f9d21154c 7581 if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
wolfSSL 0:d92f9d21154c 7582 int err;
wolfSSL 0:d92f9d21154c 7583 ssl->secure_renegotiation->startScr = 0; /* only start once */
wolfSSL 0:d92f9d21154c 7584 WOLFSSL_MSG("Need to start scr, server requested");
wolfSSL 0:d92f9d21154c 7585 if ( (err = wolfSSL_Rehandshake(ssl)) != SSL_SUCCESS)
wolfSSL 0:d92f9d21154c 7586 return err;
wolfSSL 0:d92f9d21154c 7587 }
wolfSSL 0:d92f9d21154c 7588 #endif
wolfSSL 0:d92f9d21154c 7589
wolfSSL 0:d92f9d21154c 7590 while (ssl->buffers.clearOutputBuffer.length == 0) {
wolfSSL 0:d92f9d21154c 7591 if ( (ssl->error = ProcessReply(ssl)) < 0) {
wolfSSL 0:d92f9d21154c 7592 WOLFSSL_ERROR(ssl->error);
wolfSSL 0:d92f9d21154c 7593 if (ssl->error == ZERO_RETURN) {
wolfSSL 0:d92f9d21154c 7594 WOLFSSL_MSG("Zero return, no more data coming");
wolfSSL 0:d92f9d21154c 7595 return 0; /* no more data coming */
wolfSSL 0:d92f9d21154c 7596 }
wolfSSL 0:d92f9d21154c 7597 if (ssl->error == SOCKET_ERROR_E) {
wolfSSL 0:d92f9d21154c 7598 if (ssl->options.connReset || ssl->options.isClosed) {
wolfSSL 0:d92f9d21154c 7599 WOLFSSL_MSG("Peer reset or closed, connection done");
wolfSSL 0:d92f9d21154c 7600 ssl->error = SOCKET_PEER_CLOSED_E;
wolfSSL 0:d92f9d21154c 7601 WOLFSSL_ERROR(ssl->error);
wolfSSL 0:d92f9d21154c 7602 return 0; /* peer reset or closed */
wolfSSL 0:d92f9d21154c 7603 }
wolfSSL 0:d92f9d21154c 7604 }
wolfSSL 0:d92f9d21154c 7605 return ssl->error;
wolfSSL 0:d92f9d21154c 7606 }
wolfSSL 0:d92f9d21154c 7607 #ifdef HAVE_SECURE_RENEGOTIATION
wolfSSL 0:d92f9d21154c 7608 if (ssl->secure_renegotiation &&
wolfSSL 0:d92f9d21154c 7609 ssl->secure_renegotiation->startScr) {
wolfSSL 0:d92f9d21154c 7610 goto startScr;
wolfSSL 0:d92f9d21154c 7611 }
wolfSSL 0:d92f9d21154c 7612 #endif
wolfSSL 0:d92f9d21154c 7613 }
wolfSSL 0:d92f9d21154c 7614
wolfSSL 0:d92f9d21154c 7615 if (sz < (int)ssl->buffers.clearOutputBuffer.length)
wolfSSL 0:d92f9d21154c 7616 size = sz;
wolfSSL 0:d92f9d21154c 7617 else
wolfSSL 0:d92f9d21154c 7618 size = ssl->buffers.clearOutputBuffer.length;
wolfSSL 0:d92f9d21154c 7619
wolfSSL 0:d92f9d21154c 7620 XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size);
wolfSSL 0:d92f9d21154c 7621
wolfSSL 0:d92f9d21154c 7622 if (peek == 0) {
wolfSSL 0:d92f9d21154c 7623 ssl->buffers.clearOutputBuffer.length -= size;
wolfSSL 0:d92f9d21154c 7624 ssl->buffers.clearOutputBuffer.buffer += size;
wolfSSL 0:d92f9d21154c 7625 }
wolfSSL 0:d92f9d21154c 7626
wolfSSL 0:d92f9d21154c 7627 if (ssl->buffers.clearOutputBuffer.length == 0 &&
wolfSSL 0:d92f9d21154c 7628 ssl->buffers.inputBuffer.dynamicFlag)
wolfSSL 0:d92f9d21154c 7629 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
wolfSSL 0:d92f9d21154c 7630
wolfSSL 0:d92f9d21154c 7631 WOLFSSL_LEAVE("ReceiveData()", size);
wolfSSL 0:d92f9d21154c 7632 return size;
wolfSSL 0:d92f9d21154c 7633 }
wolfSSL 0:d92f9d21154c 7634
wolfSSL 0:d92f9d21154c 7635
wolfSSL 0:d92f9d21154c 7636 /* send alert message */
wolfSSL 0:d92f9d21154c 7637 int SendAlert(WOLFSSL* ssl, int severity, int type)
wolfSSL 0:d92f9d21154c 7638 {
wolfSSL 0:d92f9d21154c 7639 byte input[ALERT_SIZE];
wolfSSL 0:d92f9d21154c 7640 byte *output;
wolfSSL 0:d92f9d21154c 7641 int sendSz;
wolfSSL 0:d92f9d21154c 7642 int ret;
wolfSSL 0:d92f9d21154c 7643 int outputSz;
wolfSSL 0:d92f9d21154c 7644 int dtlsExtra = 0;
wolfSSL 0:d92f9d21154c 7645
wolfSSL 0:d92f9d21154c 7646 /* if sendalert is called again for nonbloking */
wolfSSL 0:d92f9d21154c 7647 if (ssl->options.sendAlertState != 0) {
wolfSSL 0:d92f9d21154c 7648 ret = SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 7649 if (ret == 0)
wolfSSL 0:d92f9d21154c 7650 ssl->options.sendAlertState = 0;
wolfSSL 0:d92f9d21154c 7651 return ret;
wolfSSL 0:d92f9d21154c 7652 }
wolfSSL 0:d92f9d21154c 7653
wolfSSL 0:d92f9d21154c 7654 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7655 if (ssl->options.dtls)
wolfSSL 0:d92f9d21154c 7656 dtlsExtra = DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 7657 #endif
wolfSSL 0:d92f9d21154c 7658
wolfSSL 0:d92f9d21154c 7659 /* check for available size */
wolfSSL 0:d92f9d21154c 7660 outputSz = ALERT_SIZE + MAX_MSG_EXTRA + dtlsExtra;
wolfSSL 0:d92f9d21154c 7661 if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
wolfSSL 0:d92f9d21154c 7662 return ret;
wolfSSL 0:d92f9d21154c 7663
wolfSSL 0:d92f9d21154c 7664 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 7665 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 7666 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 7667
wolfSSL 0:d92f9d21154c 7668 input[0] = (byte)severity;
wolfSSL 0:d92f9d21154c 7669 input[1] = (byte)type;
wolfSSL 0:d92f9d21154c 7670 ssl->alert_history.last_tx.code = type;
wolfSSL 0:d92f9d21154c 7671 ssl->alert_history.last_tx.level = severity;
wolfSSL 0:d92f9d21154c 7672 if (severity == alert_fatal) {
wolfSSL 0:d92f9d21154c 7673 ssl->options.isClosed = 1; /* Don't send close_notify */
wolfSSL 0:d92f9d21154c 7674 }
wolfSSL 0:d92f9d21154c 7675
wolfSSL 0:d92f9d21154c 7676 /* only send encrypted alert if handshake actually complete, otherwise
wolfSSL 0:d92f9d21154c 7677 other side may not be able to handle it */
wolfSSL 0:d92f9d21154c 7678 if (ssl->keys.encryptionOn && ssl->options.handShakeDone)
wolfSSL 0:d92f9d21154c 7679 sendSz = BuildMessage(ssl, output, outputSz, input, ALERT_SIZE, alert);
wolfSSL 0:d92f9d21154c 7680 else {
wolfSSL 0:d92f9d21154c 7681
wolfSSL 0:d92f9d21154c 7682 AddRecordHeader(output, ALERT_SIZE, alert, ssl);
wolfSSL 0:d92f9d21154c 7683 output += RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 7684 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7685 if (ssl->options.dtls)
wolfSSL 0:d92f9d21154c 7686 output += DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 7687 #endif
wolfSSL 0:d92f9d21154c 7688 XMEMCPY(output, input, ALERT_SIZE);
wolfSSL 0:d92f9d21154c 7689
wolfSSL 0:d92f9d21154c 7690 sendSz = RECORD_HEADER_SZ + ALERT_SIZE;
wolfSSL 0:d92f9d21154c 7691 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 7692 if (ssl->options.dtls)
wolfSSL 0:d92f9d21154c 7693 sendSz += DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 7694 #endif
wolfSSL 0:d92f9d21154c 7695 }
wolfSSL 0:d92f9d21154c 7696 if (sendSz < 0)
wolfSSL 0:d92f9d21154c 7697 return BUILD_MSG_ERROR;
wolfSSL 0:d92f9d21154c 7698
wolfSSL 0:d92f9d21154c 7699 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 7700 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 7701 AddPacketName("Alert", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 7702 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 7703 AddPacketInfo("Alert", &ssl->timeoutInfo, output, sendSz,ssl->heap);
wolfSSL 0:d92f9d21154c 7704 #endif
wolfSSL 0:d92f9d21154c 7705
wolfSSL 0:d92f9d21154c 7706 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 7707 ssl->options.sendAlertState = 1;
wolfSSL 0:d92f9d21154c 7708
wolfSSL 0:d92f9d21154c 7709 return SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 7710 }
wolfSSL 0:d92f9d21154c 7711
wolfSSL 0:d92f9d21154c 7712 const char* wolfSSL_ERR_reason_error_string(unsigned long e)
wolfSSL 0:d92f9d21154c 7713 {
wolfSSL 0:d92f9d21154c 7714 #ifdef NO_ERROR_STRINGS
wolfSSL 0:d92f9d21154c 7715
wolfSSL 0:d92f9d21154c 7716 (void)e;
wolfSSL 0:d92f9d21154c 7717 return "no support for error strings built in";
wolfSSL 0:d92f9d21154c 7718
wolfSSL 0:d92f9d21154c 7719 #else
wolfSSL 0:d92f9d21154c 7720
wolfSSL 0:d92f9d21154c 7721 int error = (int)e;
wolfSSL 0:d92f9d21154c 7722
wolfSSL 0:d92f9d21154c 7723 /* pass to wolfCrypt */
wolfSSL 0:d92f9d21154c 7724 if (error < MAX_CODE_E && error > MIN_CODE_E) {
wolfSSL 0:d92f9d21154c 7725 return wc_GetErrorString(error);
wolfSSL 0:d92f9d21154c 7726 }
wolfSSL 0:d92f9d21154c 7727
wolfSSL 0:d92f9d21154c 7728 switch (error) {
wolfSSL 0:d92f9d21154c 7729
wolfSSL 0:d92f9d21154c 7730 case UNSUPPORTED_SUITE :
wolfSSL 0:d92f9d21154c 7731 return "unsupported cipher suite";
wolfSSL 0:d92f9d21154c 7732
wolfSSL 0:d92f9d21154c 7733 case INPUT_CASE_ERROR :
wolfSSL 0:d92f9d21154c 7734 return "input state error";
wolfSSL 0:d92f9d21154c 7735
wolfSSL 0:d92f9d21154c 7736 case PREFIX_ERROR :
wolfSSL 0:d92f9d21154c 7737 return "bad index to key rounds";
wolfSSL 0:d92f9d21154c 7738
wolfSSL 0:d92f9d21154c 7739 case MEMORY_ERROR :
wolfSSL 0:d92f9d21154c 7740 return "out of memory";
wolfSSL 0:d92f9d21154c 7741
wolfSSL 0:d92f9d21154c 7742 case VERIFY_FINISHED_ERROR :
wolfSSL 0:d92f9d21154c 7743 return "verify problem on finished";
wolfSSL 0:d92f9d21154c 7744
wolfSSL 0:d92f9d21154c 7745 case VERIFY_MAC_ERROR :
wolfSSL 0:d92f9d21154c 7746 return "verify mac problem";
wolfSSL 0:d92f9d21154c 7747
wolfSSL 0:d92f9d21154c 7748 case PARSE_ERROR :
wolfSSL 0:d92f9d21154c 7749 return "parse error on header";
wolfSSL 0:d92f9d21154c 7750
wolfSSL 0:d92f9d21154c 7751 case SIDE_ERROR :
wolfSSL 0:d92f9d21154c 7752 return "wrong client/server type";
wolfSSL 0:d92f9d21154c 7753
wolfSSL 0:d92f9d21154c 7754 case NO_PEER_CERT :
wolfSSL 0:d92f9d21154c 7755 return "peer didn't send cert";
wolfSSL 0:d92f9d21154c 7756
wolfSSL 0:d92f9d21154c 7757 case UNKNOWN_HANDSHAKE_TYPE :
wolfSSL 0:d92f9d21154c 7758 return "weird handshake type";
wolfSSL 0:d92f9d21154c 7759
wolfSSL 0:d92f9d21154c 7760 case SOCKET_ERROR_E :
wolfSSL 0:d92f9d21154c 7761 return "error state on socket";
wolfSSL 0:d92f9d21154c 7762
wolfSSL 0:d92f9d21154c 7763 case SOCKET_NODATA :
wolfSSL 0:d92f9d21154c 7764 return "expected data, not there";
wolfSSL 0:d92f9d21154c 7765
wolfSSL 0:d92f9d21154c 7766 case INCOMPLETE_DATA :
wolfSSL 0:d92f9d21154c 7767 return "don't have enough data to complete task";
wolfSSL 0:d92f9d21154c 7768
wolfSSL 0:d92f9d21154c 7769 case UNKNOWN_RECORD_TYPE :
wolfSSL 0:d92f9d21154c 7770 return "unknown type in record hdr";
wolfSSL 0:d92f9d21154c 7771
wolfSSL 0:d92f9d21154c 7772 case DECRYPT_ERROR :
wolfSSL 0:d92f9d21154c 7773 return "error during decryption";
wolfSSL 0:d92f9d21154c 7774
wolfSSL 0:d92f9d21154c 7775 case FATAL_ERROR :
wolfSSL 0:d92f9d21154c 7776 return "revcd alert fatal error";
wolfSSL 0:d92f9d21154c 7777
wolfSSL 0:d92f9d21154c 7778 case ENCRYPT_ERROR :
wolfSSL 0:d92f9d21154c 7779 return "error during encryption";
wolfSSL 0:d92f9d21154c 7780
wolfSSL 0:d92f9d21154c 7781 case FREAD_ERROR :
wolfSSL 0:d92f9d21154c 7782 return "fread problem";
wolfSSL 0:d92f9d21154c 7783
wolfSSL 0:d92f9d21154c 7784 case NO_PEER_KEY :
wolfSSL 0:d92f9d21154c 7785 return "need peer's key";
wolfSSL 0:d92f9d21154c 7786
wolfSSL 0:d92f9d21154c 7787 case NO_PRIVATE_KEY :
wolfSSL 0:d92f9d21154c 7788 return "need the private key";
wolfSSL 0:d92f9d21154c 7789
wolfSSL 0:d92f9d21154c 7790 case NO_DH_PARAMS :
wolfSSL 0:d92f9d21154c 7791 return "server missing DH params";
wolfSSL 0:d92f9d21154c 7792
wolfSSL 0:d92f9d21154c 7793 case RSA_PRIVATE_ERROR :
wolfSSL 0:d92f9d21154c 7794 return "error during rsa priv op";
wolfSSL 0:d92f9d21154c 7795
wolfSSL 0:d92f9d21154c 7796 case MATCH_SUITE_ERROR :
wolfSSL 0:d92f9d21154c 7797 return "can't match cipher suite";
wolfSSL 0:d92f9d21154c 7798
wolfSSL 0:d92f9d21154c 7799 case BUILD_MSG_ERROR :
wolfSSL 0:d92f9d21154c 7800 return "build message failure";
wolfSSL 0:d92f9d21154c 7801
wolfSSL 0:d92f9d21154c 7802 case BAD_HELLO :
wolfSSL 0:d92f9d21154c 7803 return "client hello malformed";
wolfSSL 0:d92f9d21154c 7804
wolfSSL 0:d92f9d21154c 7805 case DOMAIN_NAME_MISMATCH :
wolfSSL 0:d92f9d21154c 7806 return "peer subject name mismatch";
wolfSSL 0:d92f9d21154c 7807
wolfSSL 0:d92f9d21154c 7808 case WANT_READ :
wolfSSL 0:d92f9d21154c 7809 case SSL_ERROR_WANT_READ :
wolfSSL 0:d92f9d21154c 7810 return "non-blocking socket wants data to be read";
wolfSSL 0:d92f9d21154c 7811
wolfSSL 0:d92f9d21154c 7812 case NOT_READY_ERROR :
wolfSSL 0:d92f9d21154c 7813 return "handshake layer not ready yet, complete first";
wolfSSL 0:d92f9d21154c 7814
wolfSSL 0:d92f9d21154c 7815 case PMS_VERSION_ERROR :
wolfSSL 0:d92f9d21154c 7816 return "premaster secret version mismatch error";
wolfSSL 0:d92f9d21154c 7817
wolfSSL 0:d92f9d21154c 7818 case VERSION_ERROR :
wolfSSL 0:d92f9d21154c 7819 return "record layer version error";
wolfSSL 0:d92f9d21154c 7820
wolfSSL 0:d92f9d21154c 7821 case WANT_WRITE :
wolfSSL 0:d92f9d21154c 7822 case SSL_ERROR_WANT_WRITE :
wolfSSL 0:d92f9d21154c 7823 return "non-blocking socket write buffer full";
wolfSSL 0:d92f9d21154c 7824
wolfSSL 0:d92f9d21154c 7825 case BUFFER_ERROR :
wolfSSL 0:d92f9d21154c 7826 return "malformed buffer input error";
wolfSSL 0:d92f9d21154c 7827
wolfSSL 0:d92f9d21154c 7828 case VERIFY_CERT_ERROR :
wolfSSL 0:d92f9d21154c 7829 return "verify problem on certificate";
wolfSSL 0:d92f9d21154c 7830
wolfSSL 0:d92f9d21154c 7831 case VERIFY_SIGN_ERROR :
wolfSSL 0:d92f9d21154c 7832 return "verify problem based on signature";
wolfSSL 0:d92f9d21154c 7833
wolfSSL 0:d92f9d21154c 7834 case CLIENT_ID_ERROR :
wolfSSL 0:d92f9d21154c 7835 return "psk client identity error";
wolfSSL 0:d92f9d21154c 7836
wolfSSL 0:d92f9d21154c 7837 case SERVER_HINT_ERROR:
wolfSSL 0:d92f9d21154c 7838 return "psk server hint error";
wolfSSL 0:d92f9d21154c 7839
wolfSSL 0:d92f9d21154c 7840 case PSK_KEY_ERROR:
wolfSSL 0:d92f9d21154c 7841 return "psk key callback error";
wolfSSL 0:d92f9d21154c 7842
wolfSSL 0:d92f9d21154c 7843 case NTRU_KEY_ERROR:
wolfSSL 0:d92f9d21154c 7844 return "NTRU key error";
wolfSSL 0:d92f9d21154c 7845
wolfSSL 0:d92f9d21154c 7846 case NTRU_DRBG_ERROR:
wolfSSL 0:d92f9d21154c 7847 return "NTRU drbg error";
wolfSSL 0:d92f9d21154c 7848
wolfSSL 0:d92f9d21154c 7849 case NTRU_ENCRYPT_ERROR:
wolfSSL 0:d92f9d21154c 7850 return "NTRU encrypt error";
wolfSSL 0:d92f9d21154c 7851
wolfSSL 0:d92f9d21154c 7852 case NTRU_DECRYPT_ERROR:
wolfSSL 0:d92f9d21154c 7853 return "NTRU decrypt error";
wolfSSL 0:d92f9d21154c 7854
wolfSSL 0:d92f9d21154c 7855 case ZLIB_INIT_ERROR:
wolfSSL 0:d92f9d21154c 7856 return "zlib init error";
wolfSSL 0:d92f9d21154c 7857
wolfSSL 0:d92f9d21154c 7858 case ZLIB_COMPRESS_ERROR:
wolfSSL 0:d92f9d21154c 7859 return "zlib compress error";
wolfSSL 0:d92f9d21154c 7860
wolfSSL 0:d92f9d21154c 7861 case ZLIB_DECOMPRESS_ERROR:
wolfSSL 0:d92f9d21154c 7862 return "zlib decompress error";
wolfSSL 0:d92f9d21154c 7863
wolfSSL 0:d92f9d21154c 7864 case GETTIME_ERROR:
wolfSSL 0:d92f9d21154c 7865 return "gettimeofday() error";
wolfSSL 0:d92f9d21154c 7866
wolfSSL 0:d92f9d21154c 7867 case GETITIMER_ERROR:
wolfSSL 0:d92f9d21154c 7868 return "getitimer() error";
wolfSSL 0:d92f9d21154c 7869
wolfSSL 0:d92f9d21154c 7870 case SIGACT_ERROR:
wolfSSL 0:d92f9d21154c 7871 return "sigaction() error";
wolfSSL 0:d92f9d21154c 7872
wolfSSL 0:d92f9d21154c 7873 case SETITIMER_ERROR:
wolfSSL 0:d92f9d21154c 7874 return "setitimer() error";
wolfSSL 0:d92f9d21154c 7875
wolfSSL 0:d92f9d21154c 7876 case LENGTH_ERROR:
wolfSSL 0:d92f9d21154c 7877 return "record layer length error";
wolfSSL 0:d92f9d21154c 7878
wolfSSL 0:d92f9d21154c 7879 case PEER_KEY_ERROR:
wolfSSL 0:d92f9d21154c 7880 return "cant decode peer key";
wolfSSL 0:d92f9d21154c 7881
wolfSSL 0:d92f9d21154c 7882 case ZERO_RETURN:
wolfSSL 0:d92f9d21154c 7883 case SSL_ERROR_ZERO_RETURN:
wolfSSL 0:d92f9d21154c 7884 return "peer sent close notify alert";
wolfSSL 0:d92f9d21154c 7885
wolfSSL 0:d92f9d21154c 7886 case ECC_CURVETYPE_ERROR:
wolfSSL 0:d92f9d21154c 7887 return "Bad ECC Curve Type or unsupported";
wolfSSL 0:d92f9d21154c 7888
wolfSSL 0:d92f9d21154c 7889 case ECC_CURVE_ERROR:
wolfSSL 0:d92f9d21154c 7890 return "Bad ECC Curve or unsupported";
wolfSSL 0:d92f9d21154c 7891
wolfSSL 0:d92f9d21154c 7892 case ECC_PEERKEY_ERROR:
wolfSSL 0:d92f9d21154c 7893 return "Bad ECC Peer Key";
wolfSSL 0:d92f9d21154c 7894
wolfSSL 0:d92f9d21154c 7895 case ECC_MAKEKEY_ERROR:
wolfSSL 0:d92f9d21154c 7896 return "ECC Make Key failure";
wolfSSL 0:d92f9d21154c 7897
wolfSSL 0:d92f9d21154c 7898 case ECC_EXPORT_ERROR:
wolfSSL 0:d92f9d21154c 7899 return "ECC Export Key failure";
wolfSSL 0:d92f9d21154c 7900
wolfSSL 0:d92f9d21154c 7901 case ECC_SHARED_ERROR:
wolfSSL 0:d92f9d21154c 7902 return "ECC DHE shared failure";
wolfSSL 0:d92f9d21154c 7903
wolfSSL 0:d92f9d21154c 7904 case NOT_CA_ERROR:
wolfSSL 0:d92f9d21154c 7905 return "Not a CA by basic constraint error";
wolfSSL 0:d92f9d21154c 7906
wolfSSL 0:d92f9d21154c 7907 case BAD_PATH_ERROR:
wolfSSL 0:d92f9d21154c 7908 return "Bad path for opendir error";
wolfSSL 0:d92f9d21154c 7909
wolfSSL 0:d92f9d21154c 7910 case BAD_CERT_MANAGER_ERROR:
wolfSSL 0:d92f9d21154c 7911 return "Bad Cert Manager error";
wolfSSL 0:d92f9d21154c 7912
wolfSSL 0:d92f9d21154c 7913 case OCSP_CERT_REVOKED:
wolfSSL 0:d92f9d21154c 7914 return "OCSP Cert revoked";
wolfSSL 0:d92f9d21154c 7915
wolfSSL 0:d92f9d21154c 7916 case CRL_CERT_REVOKED:
wolfSSL 0:d92f9d21154c 7917 return "CRL Cert revoked";
wolfSSL 0:d92f9d21154c 7918
wolfSSL 0:d92f9d21154c 7919 case CRL_MISSING:
wolfSSL 0:d92f9d21154c 7920 return "CRL missing, not loaded";
wolfSSL 0:d92f9d21154c 7921
wolfSSL 0:d92f9d21154c 7922 case MONITOR_RUNNING_E:
wolfSSL 0:d92f9d21154c 7923 return "CRL monitor already running";
wolfSSL 0:d92f9d21154c 7924
wolfSSL 0:d92f9d21154c 7925 case THREAD_CREATE_E:
wolfSSL 0:d92f9d21154c 7926 return "Thread creation problem";
wolfSSL 0:d92f9d21154c 7927
wolfSSL 0:d92f9d21154c 7928 case OCSP_NEED_URL:
wolfSSL 0:d92f9d21154c 7929 return "OCSP need URL";
wolfSSL 0:d92f9d21154c 7930
wolfSSL 0:d92f9d21154c 7931 case OCSP_CERT_UNKNOWN:
wolfSSL 0:d92f9d21154c 7932 return "OCSP Cert unknown";
wolfSSL 0:d92f9d21154c 7933
wolfSSL 0:d92f9d21154c 7934 case OCSP_LOOKUP_FAIL:
wolfSSL 0:d92f9d21154c 7935 return "OCSP Responder lookup fail";
wolfSSL 0:d92f9d21154c 7936
wolfSSL 0:d92f9d21154c 7937 case MAX_CHAIN_ERROR:
wolfSSL 0:d92f9d21154c 7938 return "Maximum Chain Depth Exceeded";
wolfSSL 0:d92f9d21154c 7939
wolfSSL 0:d92f9d21154c 7940 case COOKIE_ERROR:
wolfSSL 0:d92f9d21154c 7941 return "DTLS Cookie Error";
wolfSSL 0:d92f9d21154c 7942
wolfSSL 0:d92f9d21154c 7943 case SEQUENCE_ERROR:
wolfSSL 0:d92f9d21154c 7944 return "DTLS Sequence Error";
wolfSSL 0:d92f9d21154c 7945
wolfSSL 0:d92f9d21154c 7946 case SUITES_ERROR:
wolfSSL 0:d92f9d21154c 7947 return "Suites Pointer Error";
wolfSSL 0:d92f9d21154c 7948
wolfSSL 0:d92f9d21154c 7949 case SSL_NO_PEM_HEADER:
wolfSSL 0:d92f9d21154c 7950 return "No PEM Header Error";
wolfSSL 0:d92f9d21154c 7951
wolfSSL 0:d92f9d21154c 7952 case OUT_OF_ORDER_E:
wolfSSL 0:d92f9d21154c 7953 return "Out of order message, fatal";
wolfSSL 0:d92f9d21154c 7954
wolfSSL 0:d92f9d21154c 7955 case BAD_KEA_TYPE_E:
wolfSSL 0:d92f9d21154c 7956 return "Bad KEA type found";
wolfSSL 0:d92f9d21154c 7957
wolfSSL 0:d92f9d21154c 7958 case SANITY_CIPHER_E:
wolfSSL 0:d92f9d21154c 7959 return "Sanity check on ciphertext failed";
wolfSSL 0:d92f9d21154c 7960
wolfSSL 0:d92f9d21154c 7961 case RECV_OVERFLOW_E:
wolfSSL 0:d92f9d21154c 7962 return "Receive callback returned more than requested";
wolfSSL 0:d92f9d21154c 7963
wolfSSL 0:d92f9d21154c 7964 case GEN_COOKIE_E:
wolfSSL 0:d92f9d21154c 7965 return "Generate Cookie Error";
wolfSSL 0:d92f9d21154c 7966
wolfSSL 0:d92f9d21154c 7967 case NO_PEER_VERIFY:
wolfSSL 0:d92f9d21154c 7968 return "Need peer certificate verify Error";
wolfSSL 0:d92f9d21154c 7969
wolfSSL 0:d92f9d21154c 7970 case FWRITE_ERROR:
wolfSSL 0:d92f9d21154c 7971 return "fwrite Error";
wolfSSL 0:d92f9d21154c 7972
wolfSSL 0:d92f9d21154c 7973 case CACHE_MATCH_ERROR:
wolfSSL 0:d92f9d21154c 7974 return "Cache restore header match Error";
wolfSSL 0:d92f9d21154c 7975
wolfSSL 0:d92f9d21154c 7976 case UNKNOWN_SNI_HOST_NAME_E:
wolfSSL 0:d92f9d21154c 7977 return "Unrecognized host name Error";
wolfSSL 0:d92f9d21154c 7978
wolfSSL 0:d92f9d21154c 7979 case KEYUSE_SIGNATURE_E:
wolfSSL 0:d92f9d21154c 7980 return "Key Use digitalSignature not set Error";
wolfSSL 0:d92f9d21154c 7981
wolfSSL 0:d92f9d21154c 7982 case KEYUSE_ENCIPHER_E:
wolfSSL 0:d92f9d21154c 7983 return "Key Use keyEncipherment not set Error";
wolfSSL 0:d92f9d21154c 7984
wolfSSL 0:d92f9d21154c 7985 case EXTKEYUSE_AUTH_E:
wolfSSL 0:d92f9d21154c 7986 return "Ext Key Use server/client auth not set Error";
wolfSSL 0:d92f9d21154c 7987
wolfSSL 0:d92f9d21154c 7988 case SEND_OOB_READ_E:
wolfSSL 0:d92f9d21154c 7989 return "Send Callback Out of Bounds Read Error";
wolfSSL 0:d92f9d21154c 7990
wolfSSL 0:d92f9d21154c 7991 case SECURE_RENEGOTIATION_E:
wolfSSL 0:d92f9d21154c 7992 return "Invalid Renegotiation Error";
wolfSSL 0:d92f9d21154c 7993
wolfSSL 0:d92f9d21154c 7994 case SESSION_TICKET_LEN_E:
wolfSSL 0:d92f9d21154c 7995 return "Session Ticket Too Long Error";
wolfSSL 0:d92f9d21154c 7996
wolfSSL 0:d92f9d21154c 7997 case SESSION_TICKET_EXPECT_E:
wolfSSL 0:d92f9d21154c 7998 return "Session Ticket Error";
wolfSSL 0:d92f9d21154c 7999
wolfSSL 0:d92f9d21154c 8000 case SCR_DIFFERENT_CERT_E:
wolfSSL 0:d92f9d21154c 8001 return "Peer sent different cert during SCR";
wolfSSL 0:d92f9d21154c 8002
wolfSSL 0:d92f9d21154c 8003 case SESSION_SECRET_CB_E:
wolfSSL 0:d92f9d21154c 8004 return "Session Secret Callback Error";
wolfSSL 0:d92f9d21154c 8005
wolfSSL 0:d92f9d21154c 8006 case NO_CHANGE_CIPHER_E:
wolfSSL 0:d92f9d21154c 8007 return "Finished received from peer before Change Cipher Error";
wolfSSL 0:d92f9d21154c 8008
wolfSSL 0:d92f9d21154c 8009 case SANITY_MSG_E:
wolfSSL 0:d92f9d21154c 8010 return "Sanity Check on message order Error";
wolfSSL 0:d92f9d21154c 8011
wolfSSL 0:d92f9d21154c 8012 case DUPLICATE_MSG_E:
wolfSSL 0:d92f9d21154c 8013 return "Duplicate HandShake message Error";
wolfSSL 0:d92f9d21154c 8014
wolfSSL 0:d92f9d21154c 8015 case SNI_UNSUPPORTED:
wolfSSL 0:d92f9d21154c 8016 return "Protocol version does not support SNI Error";
wolfSSL 0:d92f9d21154c 8017
wolfSSL 0:d92f9d21154c 8018 case SOCKET_PEER_CLOSED_E:
wolfSSL 0:d92f9d21154c 8019 return "Peer closed underlying transport Error";
wolfSSL 0:d92f9d21154c 8020
wolfSSL 0:d92f9d21154c 8021 case BAD_TICKET_KEY_CB_SZ:
wolfSSL 0:d92f9d21154c 8022 return "Bad user session ticket key callback Size Error";
wolfSSL 0:d92f9d21154c 8023
wolfSSL 0:d92f9d21154c 8024 case BAD_TICKET_MSG_SZ:
wolfSSL 0:d92f9d21154c 8025 return "Bad session ticket message Size Error";
wolfSSL 0:d92f9d21154c 8026
wolfSSL 0:d92f9d21154c 8027 case BAD_TICKET_ENCRYPT:
wolfSSL 0:d92f9d21154c 8028 return "Bad user ticket callback encrypt Error";
wolfSSL 0:d92f9d21154c 8029
wolfSSL 0:d92f9d21154c 8030 case DH_KEY_SIZE_E:
wolfSSL 0:d92f9d21154c 8031 return "DH key too small Error";
wolfSSL 0:d92f9d21154c 8032
wolfSSL 0:d92f9d21154c 8033 default :
wolfSSL 0:d92f9d21154c 8034 return "unknown error number";
wolfSSL 0:d92f9d21154c 8035 }
wolfSSL 0:d92f9d21154c 8036
wolfSSL 0:d92f9d21154c 8037 #endif /* NO_ERROR_STRINGS */
wolfSSL 0:d92f9d21154c 8038 }
wolfSSL 0:d92f9d21154c 8039
wolfSSL 0:d92f9d21154c 8040 void SetErrorString(int error, char* str)
wolfSSL 0:d92f9d21154c 8041 {
wolfSSL 0:d92f9d21154c 8042 XSTRNCPY(str, wolfSSL_ERR_reason_error_string(error), WOLFSSL_MAX_ERROR_SZ);
wolfSSL 0:d92f9d21154c 8043 }
wolfSSL 0:d92f9d21154c 8044
wolfSSL 0:d92f9d21154c 8045
wolfSSL 0:d92f9d21154c 8046 /* be sure to add to cipher_name_idx too !!!! */
wolfSSL 0:d92f9d21154c 8047 static const char* const cipher_names[] =
wolfSSL 0:d92f9d21154c 8048 {
wolfSSL 0:d92f9d21154c 8049 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 8050 "RC4-SHA",
wolfSSL 0:d92f9d21154c 8051 #endif
wolfSSL 0:d92f9d21154c 8052
wolfSSL 0:d92f9d21154c 8053 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
wolfSSL 0:d92f9d21154c 8054 "RC4-MD5",
wolfSSL 0:d92f9d21154c 8055 #endif
wolfSSL 0:d92f9d21154c 8056
wolfSSL 0:d92f9d21154c 8057 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 8058 "DES-CBC3-SHA",
wolfSSL 0:d92f9d21154c 8059 #endif
wolfSSL 0:d92f9d21154c 8060
wolfSSL 0:d92f9d21154c 8061 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8062 "AES128-SHA",
wolfSSL 0:d92f9d21154c 8063 #endif
wolfSSL 0:d92f9d21154c 8064
wolfSSL 0:d92f9d21154c 8065 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8066 "AES256-SHA",
wolfSSL 0:d92f9d21154c 8067 #endif
wolfSSL 0:d92f9d21154c 8068
wolfSSL 0:d92f9d21154c 8069 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
wolfSSL 0:d92f9d21154c 8070 "NULL-SHA",
wolfSSL 0:d92f9d21154c 8071 #endif
wolfSSL 0:d92f9d21154c 8072
wolfSSL 0:d92f9d21154c 8073 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
wolfSSL 0:d92f9d21154c 8074 "NULL-SHA256",
wolfSSL 0:d92f9d21154c 8075 #endif
wolfSSL 0:d92f9d21154c 8076
wolfSSL 0:d92f9d21154c 8077 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8078 "DHE-RSA-AES128-SHA",
wolfSSL 0:d92f9d21154c 8079 #endif
wolfSSL 0:d92f9d21154c 8080
wolfSSL 0:d92f9d21154c 8081 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8082 "DHE-RSA-AES256-SHA",
wolfSSL 0:d92f9d21154c 8083 #endif
wolfSSL 0:d92f9d21154c 8084
wolfSSL 0:d92f9d21154c 8085 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8086 "DHE-PSK-AES256-GCM-SHA384",
wolfSSL 0:d92f9d21154c 8087 #endif
wolfSSL 0:d92f9d21154c 8088
wolfSSL 0:d92f9d21154c 8089 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8090 "DHE-PSK-AES128-GCM-SHA256",
wolfSSL 0:d92f9d21154c 8091 #endif
wolfSSL 0:d92f9d21154c 8092
wolfSSL 0:d92f9d21154c 8093 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8094 "PSK-AES256-GCM-SHA384",
wolfSSL 0:d92f9d21154c 8095 #endif
wolfSSL 0:d92f9d21154c 8096
wolfSSL 0:d92f9d21154c 8097 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8098 "PSK-AES128-GCM-SHA256",
wolfSSL 0:d92f9d21154c 8099 #endif
wolfSSL 0:d92f9d21154c 8100
wolfSSL 0:d92f9d21154c 8101 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 8102 "DHE-PSK-AES256-CBC-SHA384",
wolfSSL 0:d92f9d21154c 8103 #endif
wolfSSL 0:d92f9d21154c 8104
wolfSSL 0:d92f9d21154c 8105 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8106 "DHE-PSK-AES128-CBC-SHA256",
wolfSSL 0:d92f9d21154c 8107 #endif
wolfSSL 0:d92f9d21154c 8108
wolfSSL 0:d92f9d21154c 8109 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 8110 "PSK-AES256-CBC-SHA384",
wolfSSL 0:d92f9d21154c 8111 #endif
wolfSSL 0:d92f9d21154c 8112
wolfSSL 0:d92f9d21154c 8113 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8114 "PSK-AES128-CBC-SHA256",
wolfSSL 0:d92f9d21154c 8115 #endif
wolfSSL 0:d92f9d21154c 8116
wolfSSL 0:d92f9d21154c 8117 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8118 "PSK-AES128-CBC-SHA",
wolfSSL 0:d92f9d21154c 8119 #endif
wolfSSL 0:d92f9d21154c 8120
wolfSSL 0:d92f9d21154c 8121 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8122 "PSK-AES256-CBC-SHA",
wolfSSL 0:d92f9d21154c 8123 #endif
wolfSSL 0:d92f9d21154c 8124
wolfSSL 0:d92f9d21154c 8125 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
wolfSSL 0:d92f9d21154c 8126 "DHE-PSK-AES128-CCM",
wolfSSL 0:d92f9d21154c 8127 #endif
wolfSSL 0:d92f9d21154c 8128
wolfSSL 0:d92f9d21154c 8129 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
wolfSSL 0:d92f9d21154c 8130 "DHE-PSK-AES256-CCM",
wolfSSL 0:d92f9d21154c 8131 #endif
wolfSSL 0:d92f9d21154c 8132
wolfSSL 0:d92f9d21154c 8133 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
wolfSSL 0:d92f9d21154c 8134 "PSK-AES128-CCM",
wolfSSL 0:d92f9d21154c 8135 #endif
wolfSSL 0:d92f9d21154c 8136
wolfSSL 0:d92f9d21154c 8137 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
wolfSSL 0:d92f9d21154c 8138 "PSK-AES256-CCM",
wolfSSL 0:d92f9d21154c 8139 #endif
wolfSSL 0:d92f9d21154c 8140
wolfSSL 0:d92f9d21154c 8141 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
wolfSSL 0:d92f9d21154c 8142 "PSK-AES128-CCM-8",
wolfSSL 0:d92f9d21154c 8143 #endif
wolfSSL 0:d92f9d21154c 8144
wolfSSL 0:d92f9d21154c 8145 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
wolfSSL 0:d92f9d21154c 8146 "PSK-AES256-CCM-8",
wolfSSL 0:d92f9d21154c 8147 #endif
wolfSSL 0:d92f9d21154c 8148
wolfSSL 0:d92f9d21154c 8149 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
wolfSSL 0:d92f9d21154c 8150 "DHE-PSK-NULL-SHA384",
wolfSSL 0:d92f9d21154c 8151 #endif
wolfSSL 0:d92f9d21154c 8152
wolfSSL 0:d92f9d21154c 8153 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
wolfSSL 0:d92f9d21154c 8154 "DHE-PSK-NULL-SHA256",
wolfSSL 0:d92f9d21154c 8155 #endif
wolfSSL 0:d92f9d21154c 8156
wolfSSL 0:d92f9d21154c 8157 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
wolfSSL 0:d92f9d21154c 8158 "PSK-NULL-SHA384",
wolfSSL 0:d92f9d21154c 8159 #endif
wolfSSL 0:d92f9d21154c 8160
wolfSSL 0:d92f9d21154c 8161 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
wolfSSL 0:d92f9d21154c 8162 "PSK-NULL-SHA256",
wolfSSL 0:d92f9d21154c 8163 #endif
wolfSSL 0:d92f9d21154c 8164
wolfSSL 0:d92f9d21154c 8165 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
wolfSSL 0:d92f9d21154c 8166 "PSK-NULL-SHA",
wolfSSL 0:d92f9d21154c 8167 #endif
wolfSSL 0:d92f9d21154c 8168
wolfSSL 0:d92f9d21154c 8169 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
wolfSSL 0:d92f9d21154c 8170 "HC128-MD5",
wolfSSL 0:d92f9d21154c 8171 #endif
wolfSSL 0:d92f9d21154c 8172
wolfSSL 0:d92f9d21154c 8173 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
wolfSSL 0:d92f9d21154c 8174 "HC128-SHA",
wolfSSL 0:d92f9d21154c 8175 #endif
wolfSSL 0:d92f9d21154c 8176
wolfSSL 0:d92f9d21154c 8177 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
wolfSSL 0:d92f9d21154c 8178 "HC128-B2B256",
wolfSSL 0:d92f9d21154c 8179 #endif
wolfSSL 0:d92f9d21154c 8180
wolfSSL 0:d92f9d21154c 8181 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
wolfSSL 0:d92f9d21154c 8182 "AES128-B2B256",
wolfSSL 0:d92f9d21154c 8183 #endif
wolfSSL 0:d92f9d21154c 8184
wolfSSL 0:d92f9d21154c 8185 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
wolfSSL 0:d92f9d21154c 8186 "AES256-B2B256",
wolfSSL 0:d92f9d21154c 8187 #endif
wolfSSL 0:d92f9d21154c 8188
wolfSSL 0:d92f9d21154c 8189 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
wolfSSL 0:d92f9d21154c 8190 "RABBIT-SHA",
wolfSSL 0:d92f9d21154c 8191 #endif
wolfSSL 0:d92f9d21154c 8192
wolfSSL 0:d92f9d21154c 8193 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 8194 "NTRU-RC4-SHA",
wolfSSL 0:d92f9d21154c 8195 #endif
wolfSSL 0:d92f9d21154c 8196
wolfSSL 0:d92f9d21154c 8197 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 8198 "NTRU-DES-CBC3-SHA",
wolfSSL 0:d92f9d21154c 8199 #endif
wolfSSL 0:d92f9d21154c 8200
wolfSSL 0:d92f9d21154c 8201 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8202 "NTRU-AES128-SHA",
wolfSSL 0:d92f9d21154c 8203 #endif
wolfSSL 0:d92f9d21154c 8204
wolfSSL 0:d92f9d21154c 8205 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8206 "NTRU-AES256-SHA",
wolfSSL 0:d92f9d21154c 8207 #endif
wolfSSL 0:d92f9d21154c 8208
wolfSSL 0:d92f9d21154c 8209 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
wolfSSL 0:d92f9d21154c 8210 "AES128-CCM-8",
wolfSSL 0:d92f9d21154c 8211 #endif
wolfSSL 0:d92f9d21154c 8212
wolfSSL 0:d92f9d21154c 8213 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
wolfSSL 0:d92f9d21154c 8214 "AES256-CCM-8",
wolfSSL 0:d92f9d21154c 8215 #endif
wolfSSL 0:d92f9d21154c 8216
wolfSSL 0:d92f9d21154c 8217 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
wolfSSL 0:d92f9d21154c 8218 "ECDHE-ECDSA-AES128-CCM-8",
wolfSSL 0:d92f9d21154c 8219 #endif
wolfSSL 0:d92f9d21154c 8220
wolfSSL 0:d92f9d21154c 8221 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
wolfSSL 0:d92f9d21154c 8222 "ECDHE-ECDSA-AES256-CCM-8",
wolfSSL 0:d92f9d21154c 8223 #endif
wolfSSL 0:d92f9d21154c 8224
wolfSSL 0:d92f9d21154c 8225 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8226 "ECDHE-RSA-AES128-SHA",
wolfSSL 0:d92f9d21154c 8227 #endif
wolfSSL 0:d92f9d21154c 8228
wolfSSL 0:d92f9d21154c 8229 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8230 "ECDHE-RSA-AES256-SHA",
wolfSSL 0:d92f9d21154c 8231 #endif
wolfSSL 0:d92f9d21154c 8232
wolfSSL 0:d92f9d21154c 8233 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8234 "ECDHE-ECDSA-AES128-SHA",
wolfSSL 0:d92f9d21154c 8235 #endif
wolfSSL 0:d92f9d21154c 8236
wolfSSL 0:d92f9d21154c 8237 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8238 "ECDHE-ECDSA-AES256-SHA",
wolfSSL 0:d92f9d21154c 8239 #endif
wolfSSL 0:d92f9d21154c 8240
wolfSSL 0:d92f9d21154c 8241 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 8242 "ECDHE-RSA-RC4-SHA",
wolfSSL 0:d92f9d21154c 8243 #endif
wolfSSL 0:d92f9d21154c 8244
wolfSSL 0:d92f9d21154c 8245 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 8246 "ECDHE-RSA-DES-CBC3-SHA",
wolfSSL 0:d92f9d21154c 8247 #endif
wolfSSL 0:d92f9d21154c 8248
wolfSSL 0:d92f9d21154c 8249 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 8250 "ECDHE-ECDSA-RC4-SHA",
wolfSSL 0:d92f9d21154c 8251 #endif
wolfSSL 0:d92f9d21154c 8252
wolfSSL 0:d92f9d21154c 8253 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 8254 "ECDHE-ECDSA-DES-CBC3-SHA",
wolfSSL 0:d92f9d21154c 8255 #endif
wolfSSL 0:d92f9d21154c 8256
wolfSSL 0:d92f9d21154c 8257 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8258 "AES128-SHA256",
wolfSSL 0:d92f9d21154c 8259 #endif
wolfSSL 0:d92f9d21154c 8260
wolfSSL 0:d92f9d21154c 8261 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
wolfSSL 0:d92f9d21154c 8262 "AES256-SHA256",
wolfSSL 0:d92f9d21154c 8263 #endif
wolfSSL 0:d92f9d21154c 8264
wolfSSL 0:d92f9d21154c 8265 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8266 "DHE-RSA-AES128-SHA256",
wolfSSL 0:d92f9d21154c 8267 #endif
wolfSSL 0:d92f9d21154c 8268
wolfSSL 0:d92f9d21154c 8269 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
wolfSSL 0:d92f9d21154c 8270 "DHE-RSA-AES256-SHA256",
wolfSSL 0:d92f9d21154c 8271 #endif
wolfSSL 0:d92f9d21154c 8272
wolfSSL 0:d92f9d21154c 8273 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8274 "ECDH-RSA-AES128-SHA",
wolfSSL 0:d92f9d21154c 8275 #endif
wolfSSL 0:d92f9d21154c 8276
wolfSSL 0:d92f9d21154c 8277 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8278 "ECDH-RSA-AES256-SHA",
wolfSSL 0:d92f9d21154c 8279 #endif
wolfSSL 0:d92f9d21154c 8280
wolfSSL 0:d92f9d21154c 8281 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8282 "ECDH-ECDSA-AES128-SHA",
wolfSSL 0:d92f9d21154c 8283 #endif
wolfSSL 0:d92f9d21154c 8284
wolfSSL 0:d92f9d21154c 8285 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8286 "ECDH-ECDSA-AES256-SHA",
wolfSSL 0:d92f9d21154c 8287 #endif
wolfSSL 0:d92f9d21154c 8288
wolfSSL 0:d92f9d21154c 8289 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 8290 "ECDH-RSA-RC4-SHA",
wolfSSL 0:d92f9d21154c 8291 #endif
wolfSSL 0:d92f9d21154c 8292
wolfSSL 0:d92f9d21154c 8293 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 8294 "ECDH-RSA-DES-CBC3-SHA",
wolfSSL 0:d92f9d21154c 8295 #endif
wolfSSL 0:d92f9d21154c 8296
wolfSSL 0:d92f9d21154c 8297 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 8298 "ECDH-ECDSA-RC4-SHA",
wolfSSL 0:d92f9d21154c 8299 #endif
wolfSSL 0:d92f9d21154c 8300
wolfSSL 0:d92f9d21154c 8301 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 8302 "ECDH-ECDSA-DES-CBC3-SHA",
wolfSSL 0:d92f9d21154c 8303 #endif
wolfSSL 0:d92f9d21154c 8304
wolfSSL 0:d92f9d21154c 8305 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8306 "AES128-GCM-SHA256",
wolfSSL 0:d92f9d21154c 8307 #endif
wolfSSL 0:d92f9d21154c 8308
wolfSSL 0:d92f9d21154c 8309 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8310 "AES256-GCM-SHA384",
wolfSSL 0:d92f9d21154c 8311 #endif
wolfSSL 0:d92f9d21154c 8312
wolfSSL 0:d92f9d21154c 8313 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8314 "DHE-RSA-AES128-GCM-SHA256",
wolfSSL 0:d92f9d21154c 8315 #endif
wolfSSL 0:d92f9d21154c 8316
wolfSSL 0:d92f9d21154c 8317 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8318 "DHE-RSA-AES256-GCM-SHA384",
wolfSSL 0:d92f9d21154c 8319 #endif
wolfSSL 0:d92f9d21154c 8320
wolfSSL 0:d92f9d21154c 8321 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8322 "ECDHE-RSA-AES128-GCM-SHA256",
wolfSSL 0:d92f9d21154c 8323 #endif
wolfSSL 0:d92f9d21154c 8324
wolfSSL 0:d92f9d21154c 8325 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8326 "ECDHE-RSA-AES256-GCM-SHA384",
wolfSSL 0:d92f9d21154c 8327 #endif
wolfSSL 0:d92f9d21154c 8328
wolfSSL 0:d92f9d21154c 8329 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8330 "ECDHE-ECDSA-AES128-GCM-SHA256",
wolfSSL 0:d92f9d21154c 8331 #endif
wolfSSL 0:d92f9d21154c 8332
wolfSSL 0:d92f9d21154c 8333 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8334 "ECDHE-ECDSA-AES256-GCM-SHA384",
wolfSSL 0:d92f9d21154c 8335 #endif
wolfSSL 0:d92f9d21154c 8336
wolfSSL 0:d92f9d21154c 8337 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8338 "ECDH-RSA-AES128-GCM-SHA256",
wolfSSL 0:d92f9d21154c 8339 #endif
wolfSSL 0:d92f9d21154c 8340
wolfSSL 0:d92f9d21154c 8341 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8342 "ECDH-RSA-AES256-GCM-SHA384",
wolfSSL 0:d92f9d21154c 8343 #endif
wolfSSL 0:d92f9d21154c 8344
wolfSSL 0:d92f9d21154c 8345 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8346 "ECDH-ECDSA-AES128-GCM-SHA256",
wolfSSL 0:d92f9d21154c 8347 #endif
wolfSSL 0:d92f9d21154c 8348
wolfSSL 0:d92f9d21154c 8349 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8350 "ECDH-ECDSA-AES256-GCM-SHA384",
wolfSSL 0:d92f9d21154c 8351 #endif
wolfSSL 0:d92f9d21154c 8352
wolfSSL 0:d92f9d21154c 8353 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8354 "CAMELLIA128-SHA",
wolfSSL 0:d92f9d21154c 8355 #endif
wolfSSL 0:d92f9d21154c 8356
wolfSSL 0:d92f9d21154c 8357 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8358 "DHE-RSA-CAMELLIA128-SHA",
wolfSSL 0:d92f9d21154c 8359 #endif
wolfSSL 0:d92f9d21154c 8360
wolfSSL 0:d92f9d21154c 8361 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8362 "CAMELLIA256-SHA",
wolfSSL 0:d92f9d21154c 8363 #endif
wolfSSL 0:d92f9d21154c 8364
wolfSSL 0:d92f9d21154c 8365 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8366 "DHE-RSA-CAMELLIA256-SHA",
wolfSSL 0:d92f9d21154c 8367 #endif
wolfSSL 0:d92f9d21154c 8368
wolfSSL 0:d92f9d21154c 8369 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8370 "CAMELLIA128-SHA256",
wolfSSL 0:d92f9d21154c 8371 #endif
wolfSSL 0:d92f9d21154c 8372
wolfSSL 0:d92f9d21154c 8373 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8374 "DHE-RSA-CAMELLIA128-SHA256",
wolfSSL 0:d92f9d21154c 8375 #endif
wolfSSL 0:d92f9d21154c 8376
wolfSSL 0:d92f9d21154c 8377 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
wolfSSL 0:d92f9d21154c 8378 "CAMELLIA256-SHA256",
wolfSSL 0:d92f9d21154c 8379 #endif
wolfSSL 0:d92f9d21154c 8380
wolfSSL 0:d92f9d21154c 8381 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
wolfSSL 0:d92f9d21154c 8382 "DHE-RSA-CAMELLIA256-SHA256",
wolfSSL 0:d92f9d21154c 8383 #endif
wolfSSL 0:d92f9d21154c 8384
wolfSSL 0:d92f9d21154c 8385 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8386 "ECDHE-RSA-AES128-SHA256",
wolfSSL 0:d92f9d21154c 8387 #endif
wolfSSL 0:d92f9d21154c 8388
wolfSSL 0:d92f9d21154c 8389 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8390 "ECDHE-ECDSA-AES128-SHA256",
wolfSSL 0:d92f9d21154c 8391 #endif
wolfSSL 0:d92f9d21154c 8392
wolfSSL 0:d92f9d21154c 8393 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8394 "ECDH-RSA-AES128-SHA256",
wolfSSL 0:d92f9d21154c 8395 #endif
wolfSSL 0:d92f9d21154c 8396
wolfSSL 0:d92f9d21154c 8397 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8398 "ECDH-ECDSA-AES128-SHA256",
wolfSSL 0:d92f9d21154c 8399 #endif
wolfSSL 0:d92f9d21154c 8400
wolfSSL 0:d92f9d21154c 8401 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 8402 "ECDHE-RSA-AES256-SHA384",
wolfSSL 0:d92f9d21154c 8403 #endif
wolfSSL 0:d92f9d21154c 8404
wolfSSL 0:d92f9d21154c 8405 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 8406 "ECDHE-ECDSA-AES256-SHA384",
wolfSSL 0:d92f9d21154c 8407 #endif
wolfSSL 0:d92f9d21154c 8408
wolfSSL 0:d92f9d21154c 8409 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 8410 "ECDH-RSA-AES256-SHA384",
wolfSSL 0:d92f9d21154c 8411 #endif
wolfSSL 0:d92f9d21154c 8412
wolfSSL 0:d92f9d21154c 8413 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 8414 "ECDH-ECDSA-AES256-SHA384",
wolfSSL 0:d92f9d21154c 8415 #endif
wolfSSL 0:d92f9d21154c 8416
wolfSSL 0:d92f9d21154c 8417 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
wolfSSL 0:d92f9d21154c 8418 "ECDHE-RSA-CHACHA20-POLY1305",
wolfSSL 0:d92f9d21154c 8419 #endif
wolfSSL 0:d92f9d21154c 8420
wolfSSL 0:d92f9d21154c 8421 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
wolfSSL 0:d92f9d21154c 8422 "ECDHE-ECDSA-CHACHA20-POLY1305",
wolfSSL 0:d92f9d21154c 8423 #endif
wolfSSL 0:d92f9d21154c 8424
wolfSSL 0:d92f9d21154c 8425 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
wolfSSL 0:d92f9d21154c 8426 "DHE-RSA-CHACHA20-POLY1305",
wolfSSL 0:d92f9d21154c 8427 #endif
wolfSSL 0:d92f9d21154c 8428
wolfSSL 0:d92f9d21154c 8429 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8430 "ADH-AES128-SHA",
wolfSSL 0:d92f9d21154c 8431 #endif
wolfSSL 0:d92f9d21154c 8432
wolfSSL 0:d92f9d21154c 8433 #ifdef HAVE_RENEGOTIATION_INDICATION
wolfSSL 0:d92f9d21154c 8434 "RENEGOTIATION-INFO",
wolfSSL 0:d92f9d21154c 8435 #endif
wolfSSL 0:d92f9d21154c 8436 };
wolfSSL 0:d92f9d21154c 8437
wolfSSL 0:d92f9d21154c 8438
wolfSSL 0:d92f9d21154c 8439 /* cipher suite number that matches above name table */
wolfSSL 0:d92f9d21154c 8440 static int cipher_name_idx[] =
wolfSSL 0:d92f9d21154c 8441 {
wolfSSL 0:d92f9d21154c 8442
wolfSSL 0:d92f9d21154c 8443 #ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 8444 SSL_RSA_WITH_RC4_128_SHA,
wolfSSL 0:d92f9d21154c 8445 #endif
wolfSSL 0:d92f9d21154c 8446
wolfSSL 0:d92f9d21154c 8447 #ifdef BUILD_SSL_RSA_WITH_RC4_128_MD5
wolfSSL 0:d92f9d21154c 8448 SSL_RSA_WITH_RC4_128_MD5,
wolfSSL 0:d92f9d21154c 8449 #endif
wolfSSL 0:d92f9d21154c 8450
wolfSSL 0:d92f9d21154c 8451 #ifdef BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 8452 SSL_RSA_WITH_3DES_EDE_CBC_SHA,
wolfSSL 0:d92f9d21154c 8453 #endif
wolfSSL 0:d92f9d21154c 8454
wolfSSL 0:d92f9d21154c 8455 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8456 TLS_RSA_WITH_AES_128_CBC_SHA,
wolfSSL 0:d92f9d21154c 8457 #endif
wolfSSL 0:d92f9d21154c 8458
wolfSSL 0:d92f9d21154c 8459 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8460 TLS_RSA_WITH_AES_256_CBC_SHA,
wolfSSL 0:d92f9d21154c 8461 #endif
wolfSSL 0:d92f9d21154c 8462
wolfSSL 0:d92f9d21154c 8463 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA
wolfSSL 0:d92f9d21154c 8464 TLS_RSA_WITH_NULL_SHA,
wolfSSL 0:d92f9d21154c 8465 #endif
wolfSSL 0:d92f9d21154c 8466
wolfSSL 0:d92f9d21154c 8467 #ifdef BUILD_TLS_RSA_WITH_NULL_SHA256
wolfSSL 0:d92f9d21154c 8468 TLS_RSA_WITH_NULL_SHA256,
wolfSSL 0:d92f9d21154c 8469 #endif
wolfSSL 0:d92f9d21154c 8470
wolfSSL 0:d92f9d21154c 8471 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8472 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
wolfSSL 0:d92f9d21154c 8473 #endif
wolfSSL 0:d92f9d21154c 8474
wolfSSL 0:d92f9d21154c 8475 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8476 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
wolfSSL 0:d92f9d21154c 8477 #endif
wolfSSL 0:d92f9d21154c 8478
wolfSSL 0:d92f9d21154c 8479 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8480 TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
wolfSSL 0:d92f9d21154c 8481 #endif
wolfSSL 0:d92f9d21154c 8482
wolfSSL 0:d92f9d21154c 8483 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8484 TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
wolfSSL 0:d92f9d21154c 8485 #endif
wolfSSL 0:d92f9d21154c 8486
wolfSSL 0:d92f9d21154c 8487 #ifdef BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8488 TLS_PSK_WITH_AES_256_GCM_SHA384,
wolfSSL 0:d92f9d21154c 8489 #endif
wolfSSL 0:d92f9d21154c 8490
wolfSSL 0:d92f9d21154c 8491 #ifdef BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8492 TLS_PSK_WITH_AES_128_GCM_SHA256,
wolfSSL 0:d92f9d21154c 8493 #endif
wolfSSL 0:d92f9d21154c 8494
wolfSSL 0:d92f9d21154c 8495 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 8496 TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
wolfSSL 0:d92f9d21154c 8497 #endif
wolfSSL 0:d92f9d21154c 8498
wolfSSL 0:d92f9d21154c 8499 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8500 TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
wolfSSL 0:d92f9d21154c 8501 #endif
wolfSSL 0:d92f9d21154c 8502
wolfSSL 0:d92f9d21154c 8503 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 8504 TLS_PSK_WITH_AES_256_CBC_SHA384,
wolfSSL 0:d92f9d21154c 8505 #endif
wolfSSL 0:d92f9d21154c 8506
wolfSSL 0:d92f9d21154c 8507 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8508 TLS_PSK_WITH_AES_128_CBC_SHA256,
wolfSSL 0:d92f9d21154c 8509 #endif
wolfSSL 0:d92f9d21154c 8510
wolfSSL 0:d92f9d21154c 8511 #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8512 TLS_PSK_WITH_AES_128_CBC_SHA,
wolfSSL 0:d92f9d21154c 8513 #endif
wolfSSL 0:d92f9d21154c 8514
wolfSSL 0:d92f9d21154c 8515 #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8516 TLS_PSK_WITH_AES_256_CBC_SHA,
wolfSSL 0:d92f9d21154c 8517 #endif
wolfSSL 0:d92f9d21154c 8518
wolfSSL 0:d92f9d21154c 8519 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CCM
wolfSSL 0:d92f9d21154c 8520 TLS_DHE_PSK_WITH_AES_128_CCM,
wolfSSL 0:d92f9d21154c 8521 #endif
wolfSSL 0:d92f9d21154c 8522
wolfSSL 0:d92f9d21154c 8523 #ifdef BUILD_TLS_DHE_PSK_WITH_AES_256_CCM
wolfSSL 0:d92f9d21154c 8524 TLS_DHE_PSK_WITH_AES_256_CCM,
wolfSSL 0:d92f9d21154c 8525 #endif
wolfSSL 0:d92f9d21154c 8526
wolfSSL 0:d92f9d21154c 8527 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM
wolfSSL 0:d92f9d21154c 8528 TLS_PSK_WITH_AES_128_CCM,
wolfSSL 0:d92f9d21154c 8529 #endif
wolfSSL 0:d92f9d21154c 8530
wolfSSL 0:d92f9d21154c 8531 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM
wolfSSL 0:d92f9d21154c 8532 TLS_PSK_WITH_AES_256_CCM,
wolfSSL 0:d92f9d21154c 8533 #endif
wolfSSL 0:d92f9d21154c 8534
wolfSSL 0:d92f9d21154c 8535 #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM_8
wolfSSL 0:d92f9d21154c 8536 TLS_PSK_WITH_AES_128_CCM_8,
wolfSSL 0:d92f9d21154c 8537 #endif
wolfSSL 0:d92f9d21154c 8538
wolfSSL 0:d92f9d21154c 8539 #ifdef BUILD_TLS_PSK_WITH_AES_256_CCM_8
wolfSSL 0:d92f9d21154c 8540 TLS_PSK_WITH_AES_256_CCM_8,
wolfSSL 0:d92f9d21154c 8541 #endif
wolfSSL 0:d92f9d21154c 8542
wolfSSL 0:d92f9d21154c 8543 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA384
wolfSSL 0:d92f9d21154c 8544 TLS_DHE_PSK_WITH_NULL_SHA384,
wolfSSL 0:d92f9d21154c 8545 #endif
wolfSSL 0:d92f9d21154c 8546
wolfSSL 0:d92f9d21154c 8547 #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256
wolfSSL 0:d92f9d21154c 8548 TLS_DHE_PSK_WITH_NULL_SHA256,
wolfSSL 0:d92f9d21154c 8549 #endif
wolfSSL 0:d92f9d21154c 8550
wolfSSL 0:d92f9d21154c 8551 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384
wolfSSL 0:d92f9d21154c 8552 TLS_PSK_WITH_NULL_SHA384,
wolfSSL 0:d92f9d21154c 8553 #endif
wolfSSL 0:d92f9d21154c 8554
wolfSSL 0:d92f9d21154c 8555 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256
wolfSSL 0:d92f9d21154c 8556 TLS_PSK_WITH_NULL_SHA256,
wolfSSL 0:d92f9d21154c 8557 #endif
wolfSSL 0:d92f9d21154c 8558
wolfSSL 0:d92f9d21154c 8559 #ifdef BUILD_TLS_PSK_WITH_NULL_SHA
wolfSSL 0:d92f9d21154c 8560 TLS_PSK_WITH_NULL_SHA,
wolfSSL 0:d92f9d21154c 8561 #endif
wolfSSL 0:d92f9d21154c 8562
wolfSSL 0:d92f9d21154c 8563 #ifdef BUILD_TLS_RSA_WITH_HC_128_MD5
wolfSSL 0:d92f9d21154c 8564 TLS_RSA_WITH_HC_128_MD5,
wolfSSL 0:d92f9d21154c 8565 #endif
wolfSSL 0:d92f9d21154c 8566
wolfSSL 0:d92f9d21154c 8567 #ifdef BUILD_TLS_RSA_WITH_HC_128_SHA
wolfSSL 0:d92f9d21154c 8568 TLS_RSA_WITH_HC_128_SHA,
wolfSSL 0:d92f9d21154c 8569 #endif
wolfSSL 0:d92f9d21154c 8570
wolfSSL 0:d92f9d21154c 8571 #ifdef BUILD_TLS_RSA_WITH_HC_128_B2B256
wolfSSL 0:d92f9d21154c 8572 TLS_RSA_WITH_HC_128_B2B256,
wolfSSL 0:d92f9d21154c 8573 #endif
wolfSSL 0:d92f9d21154c 8574
wolfSSL 0:d92f9d21154c 8575 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_B2B256
wolfSSL 0:d92f9d21154c 8576 TLS_RSA_WITH_AES_128_CBC_B2B256,
wolfSSL 0:d92f9d21154c 8577 #endif
wolfSSL 0:d92f9d21154c 8578
wolfSSL 0:d92f9d21154c 8579 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_B2B256
wolfSSL 0:d92f9d21154c 8580 TLS_RSA_WITH_AES_256_CBC_B2B256,
wolfSSL 0:d92f9d21154c 8581 #endif
wolfSSL 0:d92f9d21154c 8582
wolfSSL 0:d92f9d21154c 8583 #ifdef BUILD_TLS_RSA_WITH_RABBIT_SHA
wolfSSL 0:d92f9d21154c 8584 TLS_RSA_WITH_RABBIT_SHA,
wolfSSL 0:d92f9d21154c 8585 #endif
wolfSSL 0:d92f9d21154c 8586
wolfSSL 0:d92f9d21154c 8587 #ifdef BUILD_TLS_NTRU_RSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 8588 TLS_NTRU_RSA_WITH_RC4_128_SHA,
wolfSSL 0:d92f9d21154c 8589 #endif
wolfSSL 0:d92f9d21154c 8590
wolfSSL 0:d92f9d21154c 8591 #ifdef BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 8592 TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA,
wolfSSL 0:d92f9d21154c 8593 #endif
wolfSSL 0:d92f9d21154c 8594
wolfSSL 0:d92f9d21154c 8595 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8596 TLS_NTRU_RSA_WITH_AES_128_CBC_SHA,
wolfSSL 0:d92f9d21154c 8597 #endif
wolfSSL 0:d92f9d21154c 8598
wolfSSL 0:d92f9d21154c 8599 #ifdef BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8600 TLS_NTRU_RSA_WITH_AES_256_CBC_SHA,
wolfSSL 0:d92f9d21154c 8601 #endif
wolfSSL 0:d92f9d21154c 8602
wolfSSL 0:d92f9d21154c 8603 #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8
wolfSSL 0:d92f9d21154c 8604 TLS_RSA_WITH_AES_128_CCM_8,
wolfSSL 0:d92f9d21154c 8605 #endif
wolfSSL 0:d92f9d21154c 8606
wolfSSL 0:d92f9d21154c 8607 #ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8
wolfSSL 0:d92f9d21154c 8608 TLS_RSA_WITH_AES_256_CCM_8,
wolfSSL 0:d92f9d21154c 8609 #endif
wolfSSL 0:d92f9d21154c 8610
wolfSSL 0:d92f9d21154c 8611 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
wolfSSL 0:d92f9d21154c 8612 TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
wolfSSL 0:d92f9d21154c 8613 #endif
wolfSSL 0:d92f9d21154c 8614
wolfSSL 0:d92f9d21154c 8615 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
wolfSSL 0:d92f9d21154c 8616 TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
wolfSSL 0:d92f9d21154c 8617 #endif
wolfSSL 0:d92f9d21154c 8618
wolfSSL 0:d92f9d21154c 8619 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8620 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
wolfSSL 0:d92f9d21154c 8621 #endif
wolfSSL 0:d92f9d21154c 8622
wolfSSL 0:d92f9d21154c 8623 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8624 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
wolfSSL 0:d92f9d21154c 8625 #endif
wolfSSL 0:d92f9d21154c 8626
wolfSSL 0:d92f9d21154c 8627 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8628 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
wolfSSL 0:d92f9d21154c 8629 #endif
wolfSSL 0:d92f9d21154c 8630
wolfSSL 0:d92f9d21154c 8631 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8632 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
wolfSSL 0:d92f9d21154c 8633 #endif
wolfSSL 0:d92f9d21154c 8634
wolfSSL 0:d92f9d21154c 8635 #ifdef BUILD_TLS_ECDHE_RSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 8636 TLS_ECDHE_RSA_WITH_RC4_128_SHA,
wolfSSL 0:d92f9d21154c 8637 #endif
wolfSSL 0:d92f9d21154c 8638
wolfSSL 0:d92f9d21154c 8639 #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 8640 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
wolfSSL 0:d92f9d21154c 8641 #endif
wolfSSL 0:d92f9d21154c 8642
wolfSSL 0:d92f9d21154c 8643 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 8644 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
wolfSSL 0:d92f9d21154c 8645 #endif
wolfSSL 0:d92f9d21154c 8646
wolfSSL 0:d92f9d21154c 8647 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 8648 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
wolfSSL 0:d92f9d21154c 8649 #endif
wolfSSL 0:d92f9d21154c 8650
wolfSSL 0:d92f9d21154c 8651 #ifdef BUILD_TLS_RSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8652 TLS_RSA_WITH_AES_128_CBC_SHA256,
wolfSSL 0:d92f9d21154c 8653 #endif
wolfSSL 0:d92f9d21154c 8654
wolfSSL 0:d92f9d21154c 8655 #ifdef BUILD_TLS_RSA_WITH_AES_256_CBC_SHA256
wolfSSL 0:d92f9d21154c 8656 TLS_RSA_WITH_AES_256_CBC_SHA256,
wolfSSL 0:d92f9d21154c 8657 #endif
wolfSSL 0:d92f9d21154c 8658
wolfSSL 0:d92f9d21154c 8659 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8660 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
wolfSSL 0:d92f9d21154c 8661 #endif
wolfSSL 0:d92f9d21154c 8662
wolfSSL 0:d92f9d21154c 8663 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
wolfSSL 0:d92f9d21154c 8664 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
wolfSSL 0:d92f9d21154c 8665 #endif
wolfSSL 0:d92f9d21154c 8666
wolfSSL 0:d92f9d21154c 8667 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8668 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
wolfSSL 0:d92f9d21154c 8669 #endif
wolfSSL 0:d92f9d21154c 8670
wolfSSL 0:d92f9d21154c 8671 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8672 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
wolfSSL 0:d92f9d21154c 8673 #endif
wolfSSL 0:d92f9d21154c 8674
wolfSSL 0:d92f9d21154c 8675 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8676 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
wolfSSL 0:d92f9d21154c 8677 #endif
wolfSSL 0:d92f9d21154c 8678
wolfSSL 0:d92f9d21154c 8679 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8680 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
wolfSSL 0:d92f9d21154c 8681 #endif
wolfSSL 0:d92f9d21154c 8682
wolfSSL 0:d92f9d21154c 8683 #ifdef BUILD_TLS_ECDH_RSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 8684 TLS_ECDH_RSA_WITH_RC4_128_SHA,
wolfSSL 0:d92f9d21154c 8685 #endif
wolfSSL 0:d92f9d21154c 8686
wolfSSL 0:d92f9d21154c 8687 #ifdef BUILD_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 8688 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
wolfSSL 0:d92f9d21154c 8689 #endif
wolfSSL 0:d92f9d21154c 8690
wolfSSL 0:d92f9d21154c 8691 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
wolfSSL 0:d92f9d21154c 8692 TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
wolfSSL 0:d92f9d21154c 8693 #endif
wolfSSL 0:d92f9d21154c 8694
wolfSSL 0:d92f9d21154c 8695 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
wolfSSL 0:d92f9d21154c 8696 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
wolfSSL 0:d92f9d21154c 8697 #endif
wolfSSL 0:d92f9d21154c 8698
wolfSSL 0:d92f9d21154c 8699 #ifdef BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8700 TLS_RSA_WITH_AES_128_GCM_SHA256,
wolfSSL 0:d92f9d21154c 8701 #endif
wolfSSL 0:d92f9d21154c 8702
wolfSSL 0:d92f9d21154c 8703 #ifdef BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8704 TLS_RSA_WITH_AES_256_GCM_SHA384,
wolfSSL 0:d92f9d21154c 8705 #endif
wolfSSL 0:d92f9d21154c 8706
wolfSSL 0:d92f9d21154c 8707 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8708 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
wolfSSL 0:d92f9d21154c 8709 #endif
wolfSSL 0:d92f9d21154c 8710
wolfSSL 0:d92f9d21154c 8711 #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8712 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
wolfSSL 0:d92f9d21154c 8713 #endif
wolfSSL 0:d92f9d21154c 8714
wolfSSL 0:d92f9d21154c 8715 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8716 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
wolfSSL 0:d92f9d21154c 8717 #endif
wolfSSL 0:d92f9d21154c 8718
wolfSSL 0:d92f9d21154c 8719 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8720 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
wolfSSL 0:d92f9d21154c 8721 #endif
wolfSSL 0:d92f9d21154c 8722
wolfSSL 0:d92f9d21154c 8723 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8724 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
wolfSSL 0:d92f9d21154c 8725 #endif
wolfSSL 0:d92f9d21154c 8726
wolfSSL 0:d92f9d21154c 8727 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8728 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
wolfSSL 0:d92f9d21154c 8729 #endif
wolfSSL 0:d92f9d21154c 8730
wolfSSL 0:d92f9d21154c 8731 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8732 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
wolfSSL 0:d92f9d21154c 8733 #endif
wolfSSL 0:d92f9d21154c 8734
wolfSSL 0:d92f9d21154c 8735 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8736 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
wolfSSL 0:d92f9d21154c 8737 #endif
wolfSSL 0:d92f9d21154c 8738
wolfSSL 0:d92f9d21154c 8739 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
wolfSSL 0:d92f9d21154c 8740 TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
wolfSSL 0:d92f9d21154c 8741 #endif
wolfSSL 0:d92f9d21154c 8742
wolfSSL 0:d92f9d21154c 8743 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
wolfSSL 0:d92f9d21154c 8744 TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
wolfSSL 0:d92f9d21154c 8745 #endif
wolfSSL 0:d92f9d21154c 8746
wolfSSL 0:d92f9d21154c 8747 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8748 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
wolfSSL 0:d92f9d21154c 8749 #endif
wolfSSL 0:d92f9d21154c 8750
wolfSSL 0:d92f9d21154c 8751 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8752 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
wolfSSL 0:d92f9d21154c 8753 #endif
wolfSSL 0:d92f9d21154c 8754
wolfSSL 0:d92f9d21154c 8755 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8756 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
wolfSSL 0:d92f9d21154c 8757 #endif
wolfSSL 0:d92f9d21154c 8758
wolfSSL 0:d92f9d21154c 8759 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
wolfSSL 0:d92f9d21154c 8760 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
wolfSSL 0:d92f9d21154c 8761 #endif
wolfSSL 0:d92f9d21154c 8762
wolfSSL 0:d92f9d21154c 8763 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8764 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
wolfSSL 0:d92f9d21154c 8765 #endif
wolfSSL 0:d92f9d21154c 8766
wolfSSL 0:d92f9d21154c 8767 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8768 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
wolfSSL 0:d92f9d21154c 8769 #endif
wolfSSL 0:d92f9d21154c 8770
wolfSSL 0:d92f9d21154c 8771 #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
wolfSSL 0:d92f9d21154c 8772 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
wolfSSL 0:d92f9d21154c 8773 #endif
wolfSSL 0:d92f9d21154c 8774
wolfSSL 0:d92f9d21154c 8775 #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
wolfSSL 0:d92f9d21154c 8776 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
wolfSSL 0:d92f9d21154c 8777 #endif
wolfSSL 0:d92f9d21154c 8778
wolfSSL 0:d92f9d21154c 8779 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8780 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
wolfSSL 0:d92f9d21154c 8781 #endif
wolfSSL 0:d92f9d21154c 8782
wolfSSL 0:d92f9d21154c 8783 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8784 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
wolfSSL 0:d92f9d21154c 8785 #endif
wolfSSL 0:d92f9d21154c 8786
wolfSSL 0:d92f9d21154c 8787 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8788 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
wolfSSL 0:d92f9d21154c 8789 #endif
wolfSSL 0:d92f9d21154c 8790
wolfSSL 0:d92f9d21154c 8791 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
wolfSSL 0:d92f9d21154c 8792 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
wolfSSL 0:d92f9d21154c 8793 #endif
wolfSSL 0:d92f9d21154c 8794
wolfSSL 0:d92f9d21154c 8795 #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 8796 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
wolfSSL 0:d92f9d21154c 8797 #endif
wolfSSL 0:d92f9d21154c 8798
wolfSSL 0:d92f9d21154c 8799 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 8800 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
wolfSSL 0:d92f9d21154c 8801 #endif
wolfSSL 0:d92f9d21154c 8802
wolfSSL 0:d92f9d21154c 8803 #ifdef BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 8804 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
wolfSSL 0:d92f9d21154c 8805 #endif
wolfSSL 0:d92f9d21154c 8806
wolfSSL 0:d92f9d21154c 8807 #ifdef BUILD_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
wolfSSL 0:d92f9d21154c 8808 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
wolfSSL 0:d92f9d21154c 8809 #endif
wolfSSL 0:d92f9d21154c 8810
wolfSSL 0:d92f9d21154c 8811 #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
wolfSSL 0:d92f9d21154c 8812 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
wolfSSL 0:d92f9d21154c 8813 #endif
wolfSSL 0:d92f9d21154c 8814
wolfSSL 0:d92f9d21154c 8815 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
wolfSSL 0:d92f9d21154c 8816 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
wolfSSL 0:d92f9d21154c 8817 #endif
wolfSSL 0:d92f9d21154c 8818
wolfSSL 0:d92f9d21154c 8819 #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
wolfSSL 0:d92f9d21154c 8820 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
wolfSSL 0:d92f9d21154c 8821 #endif
wolfSSL 0:d92f9d21154c 8822
wolfSSL 0:d92f9d21154c 8823 #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA
wolfSSL 0:d92f9d21154c 8824 TLS_DH_anon_WITH_AES_128_CBC_SHA,
wolfSSL 0:d92f9d21154c 8825 #endif
wolfSSL 0:d92f9d21154c 8826
wolfSSL 0:d92f9d21154c 8827 #ifdef HAVE_RENEGOTIATION_INDICATION
wolfSSL 0:d92f9d21154c 8828 TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
wolfSSL 0:d92f9d21154c 8829 #endif
wolfSSL 0:d92f9d21154c 8830 };
wolfSSL 0:d92f9d21154c 8831
wolfSSL 0:d92f9d21154c 8832
wolfSSL 0:d92f9d21154c 8833 /* returns the cipher_names array */
wolfSSL 0:d92f9d21154c 8834 const char* const* GetCipherNames(void)
wolfSSL 0:d92f9d21154c 8835 {
wolfSSL 0:d92f9d21154c 8836 return cipher_names;
wolfSSL 0:d92f9d21154c 8837 }
wolfSSL 0:d92f9d21154c 8838
wolfSSL 0:d92f9d21154c 8839
wolfSSL 0:d92f9d21154c 8840 /* returns the size of the cipher_names array */
wolfSSL 0:d92f9d21154c 8841 int GetCipherNamesSize(void)
wolfSSL 0:d92f9d21154c 8842 {
wolfSSL 0:d92f9d21154c 8843 return (int)(sizeof(cipher_names) / sizeof(char*));
wolfSSL 0:d92f9d21154c 8844 }
wolfSSL 0:d92f9d21154c 8845
wolfSSL 0:d92f9d21154c 8846
wolfSSL 0:d92f9d21154c 8847 /**
wolfSSL 0:d92f9d21154c 8848 Set the enabled cipher suites.
wolfSSL 0:d92f9d21154c 8849
wolfSSL 0:d92f9d21154c 8850 @param [out] suites Suites structure.
wolfSSL 0:d92f9d21154c 8851 @param [in] list List of cipher suites, only supports full name from
wolfSSL 0:d92f9d21154c 8852 cipher_name[] delimited by ':'.
wolfSSL 0:d92f9d21154c 8853
wolfSSL 0:d92f9d21154c 8854 @return true on success, else false.
wolfSSL 0:d92f9d21154c 8855 */
wolfSSL 0:d92f9d21154c 8856 int SetCipherList(Suites* suites, const char* list)
wolfSSL 0:d92f9d21154c 8857 {
wolfSSL 0:d92f9d21154c 8858 int ret = 0;
wolfSSL 0:d92f9d21154c 8859 int idx = 0;
wolfSSL 0:d92f9d21154c 8860 int haveRSAsig = 0;
wolfSSL 0:d92f9d21154c 8861 int haveECDSAsig = 0;
wolfSSL 0:d92f9d21154c 8862 int haveAnon = 0;
wolfSSL 0:d92f9d21154c 8863 const int suiteSz = GetCipherNamesSize();
wolfSSL 0:d92f9d21154c 8864 char* next = (char*)list;
wolfSSL 0:d92f9d21154c 8865
wolfSSL 0:d92f9d21154c 8866 if (suites == NULL || list == NULL) {
wolfSSL 0:d92f9d21154c 8867 WOLFSSL_MSG("SetCipherList parameter error");
wolfSSL 0:d92f9d21154c 8868 return 0;
wolfSSL 0:d92f9d21154c 8869 }
wolfSSL 0:d92f9d21154c 8870
wolfSSL 0:d92f9d21154c 8871 if (next[0] == 0 || XSTRNCMP(next, "ALL", 3) == 0)
wolfSSL 0:d92f9d21154c 8872 return 1; /* wolfSSL defualt */
wolfSSL 0:d92f9d21154c 8873
wolfSSL 0:d92f9d21154c 8874 do {
wolfSSL 0:d92f9d21154c 8875 char* current = next;
wolfSSL 0:d92f9d21154c 8876 char name[MAX_SUITE_NAME + 1];
wolfSSL 0:d92f9d21154c 8877 int i;
wolfSSL 0:d92f9d21154c 8878 word32 length;
wolfSSL 0:d92f9d21154c 8879
wolfSSL 0:d92f9d21154c 8880 next = XSTRSTR(next, ":");
wolfSSL 0:d92f9d21154c 8881 length = min(sizeof(name), !next ? (word32)XSTRLEN(current) /* last */
wolfSSL 0:d92f9d21154c 8882 : (word32)(next - current));
wolfSSL 0:d92f9d21154c 8883
wolfSSL 0:d92f9d21154c 8884 XSTRNCPY(name, current, length);
wolfSSL 0:d92f9d21154c 8885 name[(length == sizeof(name)) ? length - 1 : length] = 0;
wolfSSL 0:d92f9d21154c 8886
wolfSSL 0:d92f9d21154c 8887 for (i = 0; i < suiteSz; i++) {
wolfSSL 0:d92f9d21154c 8888 if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) {
wolfSSL 0:d92f9d21154c 8889 suites->suites[idx++] = (XSTRSTR(name, "CHACHA")) ? CHACHA_BYTE
wolfSSL 0:d92f9d21154c 8890 : (XSTRSTR(name, "EC")) ? ECC_BYTE
wolfSSL 0:d92f9d21154c 8891 : (XSTRSTR(name, "CCM")) ? ECC_BYTE
wolfSSL 0:d92f9d21154c 8892 : 0x00; /* normal */
wolfSSL 0:d92f9d21154c 8893
wolfSSL 0:d92f9d21154c 8894 suites->suites[idx++] = (byte)cipher_name_idx[i];
wolfSSL 0:d92f9d21154c 8895
wolfSSL 0:d92f9d21154c 8896 /* The suites are either ECDSA, RSA, PSK, or Anon. The RSA
wolfSSL 0:d92f9d21154c 8897 * suites don't necessarily have RSA in the name. */
wolfSSL 0:d92f9d21154c 8898 if ((haveECDSAsig == 0) && XSTRSTR(name, "ECDSA"))
wolfSSL 0:d92f9d21154c 8899 haveECDSAsig = 1;
wolfSSL 0:d92f9d21154c 8900 else if (XSTRSTR(name, "ADH"))
wolfSSL 0:d92f9d21154c 8901 haveAnon = 1;
wolfSSL 0:d92f9d21154c 8902 else if ((haveRSAsig == 0) && (XSTRSTR(name, "PSK") == NULL))
wolfSSL 0:d92f9d21154c 8903 haveRSAsig = 1;
wolfSSL 0:d92f9d21154c 8904
wolfSSL 0:d92f9d21154c 8905 ret = 1; /* found at least one */
wolfSSL 0:d92f9d21154c 8906 break;
wolfSSL 0:d92f9d21154c 8907 }
wolfSSL 0:d92f9d21154c 8908 }
wolfSSL 0:d92f9d21154c 8909 }
wolfSSL 0:d92f9d21154c 8910 while (next++); /* ++ needed to skip ':' */
wolfSSL 0:d92f9d21154c 8911
wolfSSL 0:d92f9d21154c 8912 if (ret) {
wolfSSL 0:d92f9d21154c 8913 suites->setSuites = 1;
wolfSSL 0:d92f9d21154c 8914 suites->suiteSz = (word16)idx;
wolfSSL 0:d92f9d21154c 8915 InitSuitesHashSigAlgo(suites, haveECDSAsig, haveRSAsig, haveAnon);
wolfSSL 0:d92f9d21154c 8916 }
wolfSSL 0:d92f9d21154c 8917
wolfSSL 0:d92f9d21154c 8918 return ret;
wolfSSL 0:d92f9d21154c 8919 }
wolfSSL 0:d92f9d21154c 8920
wolfSSL 0:d92f9d21154c 8921
wolfSSL 0:d92f9d21154c 8922 static void PickHashSigAlgo(WOLFSSL* ssl,
wolfSSL 0:d92f9d21154c 8923 const byte* hashSigAlgo, word32 hashSigAlgoSz)
wolfSSL 0:d92f9d21154c 8924 {
wolfSSL 0:d92f9d21154c 8925 word32 i;
wolfSSL 0:d92f9d21154c 8926
wolfSSL 0:d92f9d21154c 8927 ssl->suites->sigAlgo = ssl->specs.sig_algo;
wolfSSL 0:d92f9d21154c 8928 ssl->suites->hashAlgo = sha_mac;
wolfSSL 0:d92f9d21154c 8929
wolfSSL 0:d92f9d21154c 8930 /* i+1 since peek a byte ahead for type */
wolfSSL 0:d92f9d21154c 8931 for (i = 0; (i+1) < hashSigAlgoSz; i += 2) {
wolfSSL 0:d92f9d21154c 8932 if (hashSigAlgo[i+1] == ssl->specs.sig_algo) {
wolfSSL 0:d92f9d21154c 8933 if (hashSigAlgo[i] == sha_mac) {
wolfSSL 0:d92f9d21154c 8934 break;
wolfSSL 0:d92f9d21154c 8935 }
wolfSSL 0:d92f9d21154c 8936 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 8937 else if (hashSigAlgo[i] == sha256_mac) {
wolfSSL 0:d92f9d21154c 8938 ssl->suites->hashAlgo = sha256_mac;
wolfSSL 0:d92f9d21154c 8939 break;
wolfSSL 0:d92f9d21154c 8940 }
wolfSSL 0:d92f9d21154c 8941 #endif
wolfSSL 0:d92f9d21154c 8942 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 8943 else if (hashSigAlgo[i] == sha384_mac) {
wolfSSL 0:d92f9d21154c 8944 ssl->suites->hashAlgo = sha384_mac;
wolfSSL 0:d92f9d21154c 8945 break;
wolfSSL 0:d92f9d21154c 8946 }
wolfSSL 0:d92f9d21154c 8947 #endif
wolfSSL 0:d92f9d21154c 8948 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 8949 else if (hashSigAlgo[i] == sha512_mac) {
wolfSSL 0:d92f9d21154c 8950 ssl->suites->hashAlgo = sha512_mac;
wolfSSL 0:d92f9d21154c 8951 break;
wolfSSL 0:d92f9d21154c 8952 }
wolfSSL 0:d92f9d21154c 8953 #endif
wolfSSL 0:d92f9d21154c 8954 }
wolfSSL 0:d92f9d21154c 8955 }
wolfSSL 0:d92f9d21154c 8956 }
wolfSSL 0:d92f9d21154c 8957
wolfSSL 0:d92f9d21154c 8958
wolfSSL 0:d92f9d21154c 8959 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 8960
wolfSSL 0:d92f9d21154c 8961 /* Initialisze HandShakeInfo */
wolfSSL 0:d92f9d21154c 8962 void InitHandShakeInfo(HandShakeInfo* info)
wolfSSL 0:d92f9d21154c 8963 {
wolfSSL 0:d92f9d21154c 8964 int i;
wolfSSL 0:d92f9d21154c 8965
wolfSSL 0:d92f9d21154c 8966 info->cipherName[0] = 0;
wolfSSL 0:d92f9d21154c 8967 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
wolfSSL 0:d92f9d21154c 8968 info->packetNames[i][0] = 0;
wolfSSL 0:d92f9d21154c 8969 info->numberPackets = 0;
wolfSSL 0:d92f9d21154c 8970 info->negotiationError = 0;
wolfSSL 0:d92f9d21154c 8971 }
wolfSSL 0:d92f9d21154c 8972
wolfSSL 0:d92f9d21154c 8973 /* Set Final HandShakeInfo parameters */
wolfSSL 0:d92f9d21154c 8974 void FinishHandShakeInfo(HandShakeInfo* info, const WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 8975 {
wolfSSL 0:d92f9d21154c 8976 int i;
wolfSSL 0:d92f9d21154c 8977 int sz = sizeof(cipher_name_idx)/sizeof(int);
wolfSSL 0:d92f9d21154c 8978
wolfSSL 0:d92f9d21154c 8979 for (i = 0; i < sz; i++)
wolfSSL 0:d92f9d21154c 8980 if (ssl->options.cipherSuite == (byte)cipher_name_idx[i]) {
wolfSSL 0:d92f9d21154c 8981 if (ssl->options.cipherSuite0 == ECC_BYTE)
wolfSSL 0:d92f9d21154c 8982 continue; /* ECC suites at end */
wolfSSL 0:d92f9d21154c 8983 XSTRNCPY(info->cipherName, cipher_names[i], MAX_CIPHERNAME_SZ);
wolfSSL 0:d92f9d21154c 8984 break;
wolfSSL 0:d92f9d21154c 8985 }
wolfSSL 0:d92f9d21154c 8986
wolfSSL 0:d92f9d21154c 8987 /* error max and min are negative numbers */
wolfSSL 0:d92f9d21154c 8988 if (ssl->error <= MIN_PARAM_ERR && ssl->error >= MAX_PARAM_ERR)
wolfSSL 0:d92f9d21154c 8989 info->negotiationError = ssl->error;
wolfSSL 0:d92f9d21154c 8990 }
wolfSSL 0:d92f9d21154c 8991
wolfSSL 0:d92f9d21154c 8992
wolfSSL 0:d92f9d21154c 8993 /* Add name to info packet names, increase packet name count */
wolfSSL 0:d92f9d21154c 8994 void AddPacketName(const char* name, HandShakeInfo* info)
wolfSSL 0:d92f9d21154c 8995 {
wolfSSL 0:d92f9d21154c 8996 if (info->numberPackets < MAX_PACKETS_HANDSHAKE) {
wolfSSL 0:d92f9d21154c 8997 XSTRNCPY(info->packetNames[info->numberPackets++], name,
wolfSSL 0:d92f9d21154c 8998 MAX_PACKETNAME_SZ);
wolfSSL 0:d92f9d21154c 8999 }
wolfSSL 0:d92f9d21154c 9000 }
wolfSSL 0:d92f9d21154c 9001
wolfSSL 0:d92f9d21154c 9002
wolfSSL 0:d92f9d21154c 9003 /* Initialisze TimeoutInfo */
wolfSSL 0:d92f9d21154c 9004 void InitTimeoutInfo(TimeoutInfo* info)
wolfSSL 0:d92f9d21154c 9005 {
wolfSSL 0:d92f9d21154c 9006 int i;
wolfSSL 0:d92f9d21154c 9007
wolfSSL 0:d92f9d21154c 9008 info->timeoutName[0] = 0;
wolfSSL 0:d92f9d21154c 9009 info->flags = 0;
wolfSSL 0:d92f9d21154c 9010
wolfSSL 0:d92f9d21154c 9011 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++) {
wolfSSL 0:d92f9d21154c 9012 info->packets[i].packetName[0] = 0;
wolfSSL 0:d92f9d21154c 9013 info->packets[i].timestamp.tv_sec = 0;
wolfSSL 0:d92f9d21154c 9014 info->packets[i].timestamp.tv_usec = 0;
wolfSSL 0:d92f9d21154c 9015 info->packets[i].bufferValue = 0;
wolfSSL 0:d92f9d21154c 9016 info->packets[i].valueSz = 0;
wolfSSL 0:d92f9d21154c 9017 }
wolfSSL 0:d92f9d21154c 9018 info->numberPackets = 0;
wolfSSL 0:d92f9d21154c 9019 info->timeoutValue.tv_sec = 0;
wolfSSL 0:d92f9d21154c 9020 info->timeoutValue.tv_usec = 0;
wolfSSL 0:d92f9d21154c 9021 }
wolfSSL 0:d92f9d21154c 9022
wolfSSL 0:d92f9d21154c 9023
wolfSSL 0:d92f9d21154c 9024 /* Free TimeoutInfo */
wolfSSL 0:d92f9d21154c 9025 void FreeTimeoutInfo(TimeoutInfo* info, void* heap)
wolfSSL 0:d92f9d21154c 9026 {
wolfSSL 0:d92f9d21154c 9027 int i;
wolfSSL 0:d92f9d21154c 9028 (void)heap;
wolfSSL 0:d92f9d21154c 9029 for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++)
wolfSSL 0:d92f9d21154c 9030 if (info->packets[i].bufferValue) {
wolfSSL 0:d92f9d21154c 9031 XFREE(info->packets[i].bufferValue, heap, DYNAMIC_TYPE_INFO);
wolfSSL 0:d92f9d21154c 9032 info->packets[i].bufferValue = 0;
wolfSSL 0:d92f9d21154c 9033 }
wolfSSL 0:d92f9d21154c 9034
wolfSSL 0:d92f9d21154c 9035 }
wolfSSL 0:d92f9d21154c 9036
wolfSSL 0:d92f9d21154c 9037
wolfSSL 0:d92f9d21154c 9038 /* Add PacketInfo to TimeoutInfo */
wolfSSL 0:d92f9d21154c 9039 void AddPacketInfo(const char* name, TimeoutInfo* info, const byte* data,
wolfSSL 0:d92f9d21154c 9040 int sz, void* heap)
wolfSSL 0:d92f9d21154c 9041 {
wolfSSL 0:d92f9d21154c 9042 if (info->numberPackets < (MAX_PACKETS_HANDSHAKE - 1)) {
wolfSSL 0:d92f9d21154c 9043 Timeval currTime;
wolfSSL 0:d92f9d21154c 9044
wolfSSL 0:d92f9d21154c 9045 /* may add name after */
wolfSSL 0:d92f9d21154c 9046 if (name)
wolfSSL 0:d92f9d21154c 9047 XSTRNCPY(info->packets[info->numberPackets].packetName, name,
wolfSSL 0:d92f9d21154c 9048 MAX_PACKETNAME_SZ);
wolfSSL 0:d92f9d21154c 9049
wolfSSL 0:d92f9d21154c 9050 /* add data, put in buffer if bigger than static buffer */
wolfSSL 0:d92f9d21154c 9051 info->packets[info->numberPackets].valueSz = sz;
wolfSSL 0:d92f9d21154c 9052 if (sz < MAX_VALUE_SZ)
wolfSSL 0:d92f9d21154c 9053 XMEMCPY(info->packets[info->numberPackets].value, data, sz);
wolfSSL 0:d92f9d21154c 9054 else {
wolfSSL 0:d92f9d21154c 9055 info->packets[info->numberPackets].bufferValue =
wolfSSL 0:d92f9d21154c 9056 XMALLOC(sz, heap, DYNAMIC_TYPE_INFO);
wolfSSL 0:d92f9d21154c 9057 if (!info->packets[info->numberPackets].bufferValue)
wolfSSL 0:d92f9d21154c 9058 /* let next alloc catch, just don't fill, not fatal here */
wolfSSL 0:d92f9d21154c 9059 info->packets[info->numberPackets].valueSz = 0;
wolfSSL 0:d92f9d21154c 9060 else
wolfSSL 0:d92f9d21154c 9061 XMEMCPY(info->packets[info->numberPackets].bufferValue,
wolfSSL 0:d92f9d21154c 9062 data, sz);
wolfSSL 0:d92f9d21154c 9063 }
wolfSSL 0:d92f9d21154c 9064 gettimeofday(&currTime, 0);
wolfSSL 0:d92f9d21154c 9065 info->packets[info->numberPackets].timestamp.tv_sec =
wolfSSL 0:d92f9d21154c 9066 currTime.tv_sec;
wolfSSL 0:d92f9d21154c 9067 info->packets[info->numberPackets].timestamp.tv_usec =
wolfSSL 0:d92f9d21154c 9068 currTime.tv_usec;
wolfSSL 0:d92f9d21154c 9069 info->numberPackets++;
wolfSSL 0:d92f9d21154c 9070 }
wolfSSL 0:d92f9d21154c 9071 }
wolfSSL 0:d92f9d21154c 9072
wolfSSL 0:d92f9d21154c 9073
wolfSSL 0:d92f9d21154c 9074 /* Add packet name to previsouly added packet info */
wolfSSL 0:d92f9d21154c 9075 void AddLateName(const char* name, TimeoutInfo* info)
wolfSSL 0:d92f9d21154c 9076 {
wolfSSL 0:d92f9d21154c 9077 /* make sure we have a valid previous one */
wolfSSL 0:d92f9d21154c 9078 if (info->numberPackets > 0 && info->numberPackets <
wolfSSL 0:d92f9d21154c 9079 MAX_PACKETS_HANDSHAKE) {
wolfSSL 0:d92f9d21154c 9080 XSTRNCPY(info->packets[info->numberPackets - 1].packetName, name,
wolfSSL 0:d92f9d21154c 9081 MAX_PACKETNAME_SZ);
wolfSSL 0:d92f9d21154c 9082 }
wolfSSL 0:d92f9d21154c 9083 }
wolfSSL 0:d92f9d21154c 9084
wolfSSL 0:d92f9d21154c 9085 /* Add record header to previsouly added packet info */
wolfSSL 0:d92f9d21154c 9086 void AddLateRecordHeader(const RecordLayerHeader* rl, TimeoutInfo* info)
wolfSSL 0:d92f9d21154c 9087 {
wolfSSL 0:d92f9d21154c 9088 /* make sure we have a valid previous one */
wolfSSL 0:d92f9d21154c 9089 if (info->numberPackets > 0 && info->numberPackets <
wolfSSL 0:d92f9d21154c 9090 MAX_PACKETS_HANDSHAKE) {
wolfSSL 0:d92f9d21154c 9091 if (info->packets[info->numberPackets - 1].bufferValue)
wolfSSL 0:d92f9d21154c 9092 XMEMCPY(info->packets[info->numberPackets - 1].bufferValue, rl,
wolfSSL 0:d92f9d21154c 9093 RECORD_HEADER_SZ);
wolfSSL 0:d92f9d21154c 9094 else
wolfSSL 0:d92f9d21154c 9095 XMEMCPY(info->packets[info->numberPackets - 1].value, rl,
wolfSSL 0:d92f9d21154c 9096 RECORD_HEADER_SZ);
wolfSSL 0:d92f9d21154c 9097 }
wolfSSL 0:d92f9d21154c 9098 }
wolfSSL 0:d92f9d21154c 9099
wolfSSL 0:d92f9d21154c 9100 #endif /* WOLFSSL_CALLBACKS */
wolfSSL 0:d92f9d21154c 9101
wolfSSL 0:d92f9d21154c 9102
wolfSSL 0:d92f9d21154c 9103
wolfSSL 0:d92f9d21154c 9104 /* client only parts */
wolfSSL 0:d92f9d21154c 9105 #ifndef NO_WOLFSSL_CLIENT
wolfSSL 0:d92f9d21154c 9106
wolfSSL 0:d92f9d21154c 9107 int SendClientHello(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 9108 {
wolfSSL 0:d92f9d21154c 9109 byte *output;
wolfSSL 0:d92f9d21154c 9110 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 9111 int sendSz;
wolfSSL 0:d92f9d21154c 9112 int idSz = ssl->options.resuming
wolfSSL 0:d92f9d21154c 9113 ? ssl->session.sessionIDSz
wolfSSL 0:d92f9d21154c 9114 : 0;
wolfSSL 0:d92f9d21154c 9115 int ret;
wolfSSL 0:d92f9d21154c 9116
wolfSSL 0:d92f9d21154c 9117 if (ssl->suites == NULL) {
wolfSSL 0:d92f9d21154c 9118 WOLFSSL_MSG("Bad suites pointer in SendClientHello");
wolfSSL 0:d92f9d21154c 9119 return SUITES_ERROR;
wolfSSL 0:d92f9d21154c 9120 }
wolfSSL 0:d92f9d21154c 9121
wolfSSL 0:d92f9d21154c 9122 #ifdef HAVE_SESSION_TICKET
wolfSSL 0:d92f9d21154c 9123 if (ssl->options.resuming && ssl->session.ticketLen > 0) {
wolfSSL 0:d92f9d21154c 9124 SessionTicket* ticket;
wolfSSL 0:d92f9d21154c 9125
wolfSSL 0:d92f9d21154c 9126 ticket = TLSX_SessionTicket_Create(0,
wolfSSL 0:d92f9d21154c 9127 ssl->session.ticket, ssl->session.ticketLen);
wolfSSL 0:d92f9d21154c 9128 if (ticket == NULL) return MEMORY_E;
wolfSSL 0:d92f9d21154c 9129
wolfSSL 0:d92f9d21154c 9130 ret = TLSX_UseSessionTicket(&ssl->extensions, ticket);
wolfSSL 0:d92f9d21154c 9131 if (ret != SSL_SUCCESS) return ret;
wolfSSL 0:d92f9d21154c 9132
wolfSSL 0:d92f9d21154c 9133 idSz = 0;
wolfSSL 0:d92f9d21154c 9134 }
wolfSSL 0:d92f9d21154c 9135 #endif
wolfSSL 0:d92f9d21154c 9136
wolfSSL 0:d92f9d21154c 9137 length = VERSION_SZ + RAN_LEN
wolfSSL 0:d92f9d21154c 9138 + idSz + ENUM_LEN
wolfSSL 0:d92f9d21154c 9139 + ssl->suites->suiteSz + SUITE_LEN
wolfSSL 0:d92f9d21154c 9140 + COMP_LEN + ENUM_LEN;
wolfSSL 0:d92f9d21154c 9141
wolfSSL 0:d92f9d21154c 9142 #ifdef HAVE_TLS_EXTENSIONS
wolfSSL 0:d92f9d21154c 9143 length += TLSX_GetRequestSize(ssl);
wolfSSL 0:d92f9d21154c 9144 #else
wolfSSL 0:d92f9d21154c 9145 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz) {
wolfSSL 0:d92f9d21154c 9146 length += ssl->suites->hashSigAlgoSz + HELLO_EXT_SZ;
wolfSSL 0:d92f9d21154c 9147 }
wolfSSL 0:d92f9d21154c 9148 #endif
wolfSSL 0:d92f9d21154c 9149 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 9150
wolfSSL 0:d92f9d21154c 9151 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 9152 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 9153 length += ENUM_LEN; /* cookie */
wolfSSL 0:d92f9d21154c 9154 if (ssl->arrays->cookieSz != 0) length += ssl->arrays->cookieSz;
wolfSSL 0:d92f9d21154c 9155 sendSz = length + DTLS_HANDSHAKE_HEADER_SZ + DTLS_RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 9156 idx += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 9157 }
wolfSSL 0:d92f9d21154c 9158 #endif
wolfSSL 0:d92f9d21154c 9159
wolfSSL 0:d92f9d21154c 9160 if (ssl->keys.encryptionOn)
wolfSSL 0:d92f9d21154c 9161 sendSz += MAX_MSG_EXTRA;
wolfSSL 0:d92f9d21154c 9162
wolfSSL 0:d92f9d21154c 9163 /* check for available size */
wolfSSL 0:d92f9d21154c 9164 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 9165 return ret;
wolfSSL 0:d92f9d21154c 9166
wolfSSL 0:d92f9d21154c 9167 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 9168 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 9169 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 9170
wolfSSL 0:d92f9d21154c 9171 AddHeaders(output, length, client_hello, ssl);
wolfSSL 0:d92f9d21154c 9172
wolfSSL 0:d92f9d21154c 9173 /* client hello, first version */
wolfSSL 0:d92f9d21154c 9174 output[idx++] = ssl->version.major;
wolfSSL 0:d92f9d21154c 9175 output[idx++] = ssl->version.minor;
wolfSSL 0:d92f9d21154c 9176 ssl->chVersion = ssl->version; /* store in case changed */
wolfSSL 0:d92f9d21154c 9177
wolfSSL 0:d92f9d21154c 9178 /* then random */
wolfSSL 0:d92f9d21154c 9179 if (ssl->options.connectState == CONNECT_BEGIN) {
wolfSSL 0:d92f9d21154c 9180 ret = wc_RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN);
wolfSSL 0:d92f9d21154c 9181 if (ret != 0)
wolfSSL 0:d92f9d21154c 9182 return ret;
wolfSSL 0:d92f9d21154c 9183
wolfSSL 0:d92f9d21154c 9184 /* store random */
wolfSSL 0:d92f9d21154c 9185 XMEMCPY(ssl->arrays->clientRandom, output + idx, RAN_LEN);
wolfSSL 0:d92f9d21154c 9186 } else {
wolfSSL 0:d92f9d21154c 9187 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 9188 /* send same random on hello again */
wolfSSL 0:d92f9d21154c 9189 XMEMCPY(output + idx, ssl->arrays->clientRandom, RAN_LEN);
wolfSSL 0:d92f9d21154c 9190 #endif
wolfSSL 0:d92f9d21154c 9191 }
wolfSSL 0:d92f9d21154c 9192 idx += RAN_LEN;
wolfSSL 0:d92f9d21154c 9193
wolfSSL 0:d92f9d21154c 9194 /* then session id */
wolfSSL 0:d92f9d21154c 9195 output[idx++] = (byte)idSz;
wolfSSL 0:d92f9d21154c 9196 if (idSz) {
wolfSSL 0:d92f9d21154c 9197 XMEMCPY(output + idx, ssl->session.sessionID,
wolfSSL 0:d92f9d21154c 9198 ssl->session.sessionIDSz);
wolfSSL 0:d92f9d21154c 9199 idx += ssl->session.sessionIDSz;
wolfSSL 0:d92f9d21154c 9200 }
wolfSSL 0:d92f9d21154c 9201
wolfSSL 0:d92f9d21154c 9202 /* then DTLS cookie */
wolfSSL 0:d92f9d21154c 9203 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 9204 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 9205 byte cookieSz = ssl->arrays->cookieSz;
wolfSSL 0:d92f9d21154c 9206
wolfSSL 0:d92f9d21154c 9207 output[idx++] = cookieSz;
wolfSSL 0:d92f9d21154c 9208 if (cookieSz) {
wolfSSL 0:d92f9d21154c 9209 XMEMCPY(&output[idx], ssl->arrays->cookie, cookieSz);
wolfSSL 0:d92f9d21154c 9210 idx += cookieSz;
wolfSSL 0:d92f9d21154c 9211 }
wolfSSL 0:d92f9d21154c 9212 }
wolfSSL 0:d92f9d21154c 9213 #endif
wolfSSL 0:d92f9d21154c 9214 /* then cipher suites */
wolfSSL 0:d92f9d21154c 9215 c16toa(ssl->suites->suiteSz, output + idx);
wolfSSL 0:d92f9d21154c 9216 idx += 2;
wolfSSL 0:d92f9d21154c 9217 XMEMCPY(output + idx, &ssl->suites->suites, ssl->suites->suiteSz);
wolfSSL 0:d92f9d21154c 9218 idx += ssl->suites->suiteSz;
wolfSSL 0:d92f9d21154c 9219
wolfSSL 0:d92f9d21154c 9220 /* last, compression */
wolfSSL 0:d92f9d21154c 9221 output[idx++] = COMP_LEN;
wolfSSL 0:d92f9d21154c 9222 if (ssl->options.usingCompression)
wolfSSL 0:d92f9d21154c 9223 output[idx++] = ZLIB_COMPRESSION;
wolfSSL 0:d92f9d21154c 9224 else
wolfSSL 0:d92f9d21154c 9225 output[idx++] = NO_COMPRESSION;
wolfSSL 0:d92f9d21154c 9226
wolfSSL 0:d92f9d21154c 9227 #ifdef HAVE_TLS_EXTENSIONS
wolfSSL 0:d92f9d21154c 9228 idx += TLSX_WriteRequest(ssl, output + idx);
wolfSSL 0:d92f9d21154c 9229
wolfSSL 0:d92f9d21154c 9230 (void)idx; /* suppress analyzer warning, keep idx current */
wolfSSL 0:d92f9d21154c 9231 #else
wolfSSL 0:d92f9d21154c 9232 if (IsAtLeastTLSv1_2(ssl) && ssl->suites->hashSigAlgoSz)
wolfSSL 0:d92f9d21154c 9233 {
wolfSSL 0:d92f9d21154c 9234 int i;
wolfSSL 0:d92f9d21154c 9235 /* add in the extensions length */
wolfSSL 0:d92f9d21154c 9236 c16toa(HELLO_EXT_LEN + ssl->suites->hashSigAlgoSz, output + idx);
wolfSSL 0:d92f9d21154c 9237 idx += 2;
wolfSSL 0:d92f9d21154c 9238
wolfSSL 0:d92f9d21154c 9239 c16toa(HELLO_EXT_SIG_ALGO, output + idx);
wolfSSL 0:d92f9d21154c 9240 idx += 2;
wolfSSL 0:d92f9d21154c 9241 c16toa(HELLO_EXT_SIGALGO_SZ+ssl->suites->hashSigAlgoSz, output+idx);
wolfSSL 0:d92f9d21154c 9242 idx += 2;
wolfSSL 0:d92f9d21154c 9243 c16toa(ssl->suites->hashSigAlgoSz, output + idx);
wolfSSL 0:d92f9d21154c 9244 idx += 2;
wolfSSL 0:d92f9d21154c 9245 for (i = 0; i < ssl->suites->hashSigAlgoSz; i++, idx++) {
wolfSSL 0:d92f9d21154c 9246 output[idx] = ssl->suites->hashSigAlgo[i];
wolfSSL 0:d92f9d21154c 9247 }
wolfSSL 0:d92f9d21154c 9248 }
wolfSSL 0:d92f9d21154c 9249 #endif
wolfSSL 0:d92f9d21154c 9250
wolfSSL 0:d92f9d21154c 9251 if (ssl->keys.encryptionOn) {
wolfSSL 0:d92f9d21154c 9252 byte* input;
wolfSSL 0:d92f9d21154c 9253 int inputSz = idx - RECORD_HEADER_SZ; /* build msg adds rec hdr */
wolfSSL 0:d92f9d21154c 9254
wolfSSL 0:d92f9d21154c 9255 input = (byte*)XMALLOC(inputSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 9256 if (input == NULL)
wolfSSL 0:d92f9d21154c 9257 return MEMORY_E;
wolfSSL 0:d92f9d21154c 9258
wolfSSL 0:d92f9d21154c 9259 XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
wolfSSL 0:d92f9d21154c 9260 sendSz = BuildMessage(ssl, output, sendSz, input,inputSz,handshake);
wolfSSL 0:d92f9d21154c 9261 XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 9262
wolfSSL 0:d92f9d21154c 9263 if (sendSz < 0)
wolfSSL 0:d92f9d21154c 9264 return sendSz;
wolfSSL 0:d92f9d21154c 9265 } else {
wolfSSL 0:d92f9d21154c 9266 ret = HashOutput(ssl, output, sendSz, 0);
wolfSSL 0:d92f9d21154c 9267 if (ret != 0)
wolfSSL 0:d92f9d21154c 9268 return ret;
wolfSSL 0:d92f9d21154c 9269 }
wolfSSL 0:d92f9d21154c 9270
wolfSSL 0:d92f9d21154c 9271 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 9272 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 9273 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 9274 return ret;
wolfSSL 0:d92f9d21154c 9275 }
wolfSSL 0:d92f9d21154c 9276 #endif
wolfSSL 0:d92f9d21154c 9277
wolfSSL 0:d92f9d21154c 9278 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
wolfSSL 0:d92f9d21154c 9279
wolfSSL 0:d92f9d21154c 9280 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 9281 if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 9282 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 9283 AddPacketInfo("ClientHello", &ssl->timeoutInfo, output, sendSz,
wolfSSL 0:d92f9d21154c 9284 ssl->heap);
wolfSSL 0:d92f9d21154c 9285 #endif
wolfSSL 0:d92f9d21154c 9286
wolfSSL 0:d92f9d21154c 9287 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 9288
wolfSSL 0:d92f9d21154c 9289 return SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 9290 }
wolfSSL 0:d92f9d21154c 9291
wolfSSL 0:d92f9d21154c 9292
wolfSSL 0:d92f9d21154c 9293 static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input,
wolfSSL 0:d92f9d21154c 9294 word32* inOutIdx, word32 size)
wolfSSL 0:d92f9d21154c 9295 {
wolfSSL 0:d92f9d21154c 9296 ProtocolVersion pv;
wolfSSL 0:d92f9d21154c 9297 byte cookieSz;
wolfSSL 0:d92f9d21154c 9298 word32 begin = *inOutIdx;
wolfSSL 0:d92f9d21154c 9299
wolfSSL 0:d92f9d21154c 9300 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 9301 if (ssl->hsInfoOn) AddPacketName("HelloVerifyRequest",
wolfSSL 0:d92f9d21154c 9302 &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 9303 if (ssl->toInfoOn) AddLateName("HelloVerifyRequest", &ssl->timeoutInfo);
wolfSSL 0:d92f9d21154c 9304 #endif
wolfSSL 0:d92f9d21154c 9305
wolfSSL 0:d92f9d21154c 9306 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 9307 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 9308 DtlsPoolReset(ssl);
wolfSSL 0:d92f9d21154c 9309 }
wolfSSL 0:d92f9d21154c 9310 #endif
wolfSSL 0:d92f9d21154c 9311
wolfSSL 0:d92f9d21154c 9312 if ((*inOutIdx - begin) + OPAQUE16_LEN + OPAQUE8_LEN > size)
wolfSSL 0:d92f9d21154c 9313 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9314
wolfSSL 0:d92f9d21154c 9315 XMEMCPY(&pv, input + *inOutIdx, OPAQUE16_LEN);
wolfSSL 0:d92f9d21154c 9316 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 9317
wolfSSL 0:d92f9d21154c 9318 cookieSz = input[(*inOutIdx)++];
wolfSSL 0:d92f9d21154c 9319
wolfSSL 0:d92f9d21154c 9320 if (cookieSz) {
wolfSSL 0:d92f9d21154c 9321 if ((*inOutIdx - begin) + cookieSz > size)
wolfSSL 0:d92f9d21154c 9322 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9323
wolfSSL 0:d92f9d21154c 9324 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 9325 if (cookieSz <= MAX_COOKIE_LEN) {
wolfSSL 0:d92f9d21154c 9326 XMEMCPY(ssl->arrays->cookie, input + *inOutIdx, cookieSz);
wolfSSL 0:d92f9d21154c 9327 ssl->arrays->cookieSz = cookieSz;
wolfSSL 0:d92f9d21154c 9328 }
wolfSSL 0:d92f9d21154c 9329 #endif
wolfSSL 0:d92f9d21154c 9330 *inOutIdx += cookieSz;
wolfSSL 0:d92f9d21154c 9331 }
wolfSSL 0:d92f9d21154c 9332
wolfSSL 0:d92f9d21154c 9333 ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
wolfSSL 0:d92f9d21154c 9334 return 0;
wolfSSL 0:d92f9d21154c 9335 }
wolfSSL 0:d92f9d21154c 9336
wolfSSL 0:d92f9d21154c 9337
wolfSSL 0:d92f9d21154c 9338 static INLINE int DSH_CheckSessionId(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 9339 {
wolfSSL 0:d92f9d21154c 9340 int ret = 0;
wolfSSL 0:d92f9d21154c 9341
wolfSSL 0:d92f9d21154c 9342 #ifdef HAVE_SECRET_CALLBACK
wolfSSL 0:d92f9d21154c 9343 /* If a session secret callback exists, we are using that
wolfSSL 0:d92f9d21154c 9344 * key instead of the saved session key. */
wolfSSL 0:d92f9d21154c 9345 ret = ret || (ssl->sessionSecretCb != NULL);
wolfSSL 0:d92f9d21154c 9346 #endif
wolfSSL 0:d92f9d21154c 9347
wolfSSL 0:d92f9d21154c 9348 #ifdef HAVE_SESSION_TICKET
wolfSSL 0:d92f9d21154c 9349 /* server may send blank ticket which may not be expected to indicate
wolfSSL 0:d92f9d21154c 9350 * exisiting one ok but will also be sending a new one */
wolfSSL 0:d92f9d21154c 9351 ret = ret || (ssl->session.ticketLen > 0);
wolfSSL 0:d92f9d21154c 9352 #endif
wolfSSL 0:d92f9d21154c 9353
wolfSSL 0:d92f9d21154c 9354 ret = ret ||
wolfSSL 0:d92f9d21154c 9355 (ssl->options.haveSessionId && XMEMCMP(ssl->arrays->sessionID,
wolfSSL 0:d92f9d21154c 9356 ssl->session.sessionID, ID_LEN) == 0);
wolfSSL 0:d92f9d21154c 9357
wolfSSL 0:d92f9d21154c 9358 return ret;
wolfSSL 0:d92f9d21154c 9359 }
wolfSSL 0:d92f9d21154c 9360
wolfSSL 0:d92f9d21154c 9361 static int DoServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
wolfSSL 0:d92f9d21154c 9362 word32 helloSz)
wolfSSL 0:d92f9d21154c 9363 {
wolfSSL 0:d92f9d21154c 9364 byte cs0; /* cipher suite bytes 0, 1 */
wolfSSL 0:d92f9d21154c 9365 byte cs1;
wolfSSL 0:d92f9d21154c 9366 ProtocolVersion pv;
wolfSSL 0:d92f9d21154c 9367 byte compression;
wolfSSL 0:d92f9d21154c 9368 word32 i = *inOutIdx;
wolfSSL 0:d92f9d21154c 9369 word32 begin = i;
wolfSSL 0:d92f9d21154c 9370
wolfSSL 0:d92f9d21154c 9371 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 9372 if (ssl->hsInfoOn) AddPacketName("ServerHello", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 9373 if (ssl->toInfoOn) AddLateName("ServerHello", &ssl->timeoutInfo);
wolfSSL 0:d92f9d21154c 9374 #endif
wolfSSL 0:d92f9d21154c 9375
wolfSSL 0:d92f9d21154c 9376 /* protocol version, random and session id length check */
wolfSSL 0:d92f9d21154c 9377 if (OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
wolfSSL 0:d92f9d21154c 9378 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9379
wolfSSL 0:d92f9d21154c 9380 /* protocol version */
wolfSSL 0:d92f9d21154c 9381 XMEMCPY(&pv, input + i, OPAQUE16_LEN);
wolfSSL 0:d92f9d21154c 9382 i += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 9383
wolfSSL 0:d92f9d21154c 9384 if (pv.minor > ssl->version.minor) {
wolfSSL 0:d92f9d21154c 9385 WOLFSSL_MSG("Server using higher version, fatal error");
wolfSSL 0:d92f9d21154c 9386 return VERSION_ERROR;
wolfSSL 0:d92f9d21154c 9387 }
wolfSSL 0:d92f9d21154c 9388 else if (pv.minor < ssl->version.minor) {
wolfSSL 0:d92f9d21154c 9389 WOLFSSL_MSG("server using lower version");
wolfSSL 0:d92f9d21154c 9390
wolfSSL 0:d92f9d21154c 9391 if (!ssl->options.downgrade) {
wolfSSL 0:d92f9d21154c 9392 WOLFSSL_MSG(" no downgrade allowed, fatal error");
wolfSSL 0:d92f9d21154c 9393 return VERSION_ERROR;
wolfSSL 0:d92f9d21154c 9394 }
wolfSSL 0:d92f9d21154c 9395 if (pv.minor < ssl->options.minDowngrade) {
wolfSSL 0:d92f9d21154c 9396 WOLFSSL_MSG(" version below minimum allowed, fatal error");
wolfSSL 0:d92f9d21154c 9397 return VERSION_ERROR;
wolfSSL 0:d92f9d21154c 9398 }
wolfSSL 0:d92f9d21154c 9399
wolfSSL 0:d92f9d21154c 9400 #ifdef HAVE_SECURE_RENEGOTIATION
wolfSSL 0:d92f9d21154c 9401 if (ssl->secure_renegotiation &&
wolfSSL 0:d92f9d21154c 9402 ssl->secure_renegotiation->enabled &&
wolfSSL 0:d92f9d21154c 9403 ssl->options.handShakeDone) {
wolfSSL 0:d92f9d21154c 9404 WOLFSSL_MSG("Server changed version during scr");
wolfSSL 0:d92f9d21154c 9405 return VERSION_ERROR;
wolfSSL 0:d92f9d21154c 9406 }
wolfSSL 0:d92f9d21154c 9407 #endif
wolfSSL 0:d92f9d21154c 9408
wolfSSL 0:d92f9d21154c 9409 if (pv.minor == SSLv3_MINOR) {
wolfSSL 0:d92f9d21154c 9410 /* turn off tls */
wolfSSL 0:d92f9d21154c 9411 WOLFSSL_MSG(" downgrading to SSLv3");
wolfSSL 0:d92f9d21154c 9412 ssl->options.tls = 0;
wolfSSL 0:d92f9d21154c 9413 ssl->options.tls1_1 = 0;
wolfSSL 0:d92f9d21154c 9414 ssl->version.minor = SSLv3_MINOR;
wolfSSL 0:d92f9d21154c 9415 }
wolfSSL 0:d92f9d21154c 9416 else if (pv.minor == TLSv1_MINOR) {
wolfSSL 0:d92f9d21154c 9417 /* turn off tls 1.1+ */
wolfSSL 0:d92f9d21154c 9418 WOLFSSL_MSG(" downgrading to TLSv1");
wolfSSL 0:d92f9d21154c 9419 ssl->options.tls1_1 = 0;
wolfSSL 0:d92f9d21154c 9420 ssl->version.minor = TLSv1_MINOR;
wolfSSL 0:d92f9d21154c 9421 }
wolfSSL 0:d92f9d21154c 9422 else if (pv.minor == TLSv1_1_MINOR) {
wolfSSL 0:d92f9d21154c 9423 WOLFSSL_MSG(" downgrading to TLSv1.1");
wolfSSL 0:d92f9d21154c 9424 ssl->version.minor = TLSv1_1_MINOR;
wolfSSL 0:d92f9d21154c 9425 }
wolfSSL 0:d92f9d21154c 9426 }
wolfSSL 0:d92f9d21154c 9427
wolfSSL 0:d92f9d21154c 9428 /* random */
wolfSSL 0:d92f9d21154c 9429 XMEMCPY(ssl->arrays->serverRandom, input + i, RAN_LEN);
wolfSSL 0:d92f9d21154c 9430 i += RAN_LEN;
wolfSSL 0:d92f9d21154c 9431
wolfSSL 0:d92f9d21154c 9432 /* session id */
wolfSSL 0:d92f9d21154c 9433 ssl->arrays->sessionIDSz = input[i++];
wolfSSL 0:d92f9d21154c 9434
wolfSSL 0:d92f9d21154c 9435 if (ssl->arrays->sessionIDSz > ID_LEN) {
wolfSSL 0:d92f9d21154c 9436 WOLFSSL_MSG("Invalid session ID size");
wolfSSL 0:d92f9d21154c 9437 ssl->arrays->sessionIDSz = 0;
wolfSSL 0:d92f9d21154c 9438 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9439 }
wolfSSL 0:d92f9d21154c 9440 else if (ssl->arrays->sessionIDSz) {
wolfSSL 0:d92f9d21154c 9441 if ((i - begin) + ssl->arrays->sessionIDSz > helloSz)
wolfSSL 0:d92f9d21154c 9442 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9443
wolfSSL 0:d92f9d21154c 9444 XMEMCPY(ssl->arrays->sessionID, input + i,
wolfSSL 0:d92f9d21154c 9445 ssl->arrays->sessionIDSz);
wolfSSL 0:d92f9d21154c 9446 i += ssl->arrays->sessionIDSz;
wolfSSL 0:d92f9d21154c 9447 ssl->options.haveSessionId = 1;
wolfSSL 0:d92f9d21154c 9448 }
wolfSSL 0:d92f9d21154c 9449
wolfSSL 0:d92f9d21154c 9450
wolfSSL 0:d92f9d21154c 9451 /* suite and compression */
wolfSSL 0:d92f9d21154c 9452 if ((i - begin) + OPAQUE16_LEN + OPAQUE8_LEN > helloSz)
wolfSSL 0:d92f9d21154c 9453 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9454
wolfSSL 0:d92f9d21154c 9455 cs0 = input[i++];
wolfSSL 0:d92f9d21154c 9456 cs1 = input[i++];
wolfSSL 0:d92f9d21154c 9457
wolfSSL 0:d92f9d21154c 9458 #ifdef HAVE_SECURE_RENEGOTIATION
wolfSSL 0:d92f9d21154c 9459 if (ssl->secure_renegotiation && ssl->secure_renegotiation->enabled &&
wolfSSL 0:d92f9d21154c 9460 ssl->options.handShakeDone) {
wolfSSL 0:d92f9d21154c 9461 if (ssl->options.cipherSuite0 != cs0 ||
wolfSSL 0:d92f9d21154c 9462 ssl->options.cipherSuite != cs1) {
wolfSSL 0:d92f9d21154c 9463 WOLFSSL_MSG("Server changed cipher suite during scr");
wolfSSL 0:d92f9d21154c 9464 return MATCH_SUITE_ERROR;
wolfSSL 0:d92f9d21154c 9465 }
wolfSSL 0:d92f9d21154c 9466 }
wolfSSL 0:d92f9d21154c 9467 #endif
wolfSSL 0:d92f9d21154c 9468
wolfSSL 0:d92f9d21154c 9469 ssl->options.cipherSuite0 = cs0;
wolfSSL 0:d92f9d21154c 9470 ssl->options.cipherSuite = cs1;
wolfSSL 0:d92f9d21154c 9471 compression = input[i++];
wolfSSL 0:d92f9d21154c 9472
wolfSSL 0:d92f9d21154c 9473 if (compression != ZLIB_COMPRESSION && ssl->options.usingCompression) {
wolfSSL 0:d92f9d21154c 9474 WOLFSSL_MSG("Server refused compression, turning off");
wolfSSL 0:d92f9d21154c 9475 ssl->options.usingCompression = 0; /* turn off if server refused */
wolfSSL 0:d92f9d21154c 9476 }
wolfSSL 0:d92f9d21154c 9477
wolfSSL 0:d92f9d21154c 9478 *inOutIdx = i;
wolfSSL 0:d92f9d21154c 9479
wolfSSL 0:d92f9d21154c 9480 /* tls extensions */
wolfSSL 0:d92f9d21154c 9481 if ( (i - begin) < helloSz) {
wolfSSL 0:d92f9d21154c 9482 #ifdef HAVE_TLS_EXTENSIONS
wolfSSL 0:d92f9d21154c 9483 if (TLSX_SupportExtensions(ssl)) {
wolfSSL 0:d92f9d21154c 9484 int ret = 0;
wolfSSL 0:d92f9d21154c 9485 word16 totalExtSz;
wolfSSL 0:d92f9d21154c 9486
wolfSSL 0:d92f9d21154c 9487 if ((i - begin) + OPAQUE16_LEN > helloSz)
wolfSSL 0:d92f9d21154c 9488 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9489
wolfSSL 0:d92f9d21154c 9490 ato16(&input[i], &totalExtSz);
wolfSSL 0:d92f9d21154c 9491 i += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 9492
wolfSSL 0:d92f9d21154c 9493 if ((i - begin) + totalExtSz > helloSz)
wolfSSL 0:d92f9d21154c 9494 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9495
wolfSSL 0:d92f9d21154c 9496 if ((ret = TLSX_Parse(ssl, (byte *) input + i,
wolfSSL 0:d92f9d21154c 9497 totalExtSz, 0, NULL)))
wolfSSL 0:d92f9d21154c 9498 return ret;
wolfSSL 0:d92f9d21154c 9499
wolfSSL 0:d92f9d21154c 9500 i += totalExtSz;
wolfSSL 0:d92f9d21154c 9501 *inOutIdx = i;
wolfSSL 0:d92f9d21154c 9502 }
wolfSSL 0:d92f9d21154c 9503 else
wolfSSL 0:d92f9d21154c 9504 #endif
wolfSSL 0:d92f9d21154c 9505 *inOutIdx = begin + helloSz; /* skip extensions */
wolfSSL 0:d92f9d21154c 9506 }
wolfSSL 0:d92f9d21154c 9507
wolfSSL 0:d92f9d21154c 9508 ssl->options.serverState = SERVER_HELLO_COMPLETE;
wolfSSL 0:d92f9d21154c 9509
wolfSSL 0:d92f9d21154c 9510 if (ssl->keys.encryptionOn) {
wolfSSL 0:d92f9d21154c 9511 *inOutIdx += ssl->keys.padSz;
wolfSSL 0:d92f9d21154c 9512 }
wolfSSL 0:d92f9d21154c 9513
wolfSSL 0:d92f9d21154c 9514 #ifdef HAVE_SECRET_CALLBACK
wolfSSL 0:d92f9d21154c 9515 if (ssl->sessionSecretCb != NULL) {
wolfSSL 0:d92f9d21154c 9516 int secretSz = SECRET_LEN, ret;
wolfSSL 0:d92f9d21154c 9517 ret = ssl->sessionSecretCb(ssl, ssl->session.masterSecret,
wolfSSL 0:d92f9d21154c 9518 &secretSz, ssl->sessionSecretCtx);
wolfSSL 0:d92f9d21154c 9519 if (ret != 0 || secretSz != SECRET_LEN)
wolfSSL 0:d92f9d21154c 9520 return SESSION_SECRET_CB_E;
wolfSSL 0:d92f9d21154c 9521 }
wolfSSL 0:d92f9d21154c 9522 #endif /* HAVE_SECRET_CALLBACK */
wolfSSL 0:d92f9d21154c 9523
wolfSSL 0:d92f9d21154c 9524 if (ssl->options.resuming) {
wolfSSL 0:d92f9d21154c 9525 if (DSH_CheckSessionId(ssl)) {
wolfSSL 0:d92f9d21154c 9526 if (SetCipherSpecs(ssl) == 0) {
wolfSSL 0:d92f9d21154c 9527 int ret = -1;
wolfSSL 0:d92f9d21154c 9528
wolfSSL 0:d92f9d21154c 9529 XMEMCPY(ssl->arrays->masterSecret,
wolfSSL 0:d92f9d21154c 9530 ssl->session.masterSecret, SECRET_LEN);
wolfSSL 0:d92f9d21154c 9531 #ifdef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 9532 ret = DeriveTlsKeys(ssl);
wolfSSL 0:d92f9d21154c 9533 #else
wolfSSL 0:d92f9d21154c 9534 #ifndef NO_TLS
wolfSSL 0:d92f9d21154c 9535 if (ssl->options.tls)
wolfSSL 0:d92f9d21154c 9536 ret = DeriveTlsKeys(ssl);
wolfSSL 0:d92f9d21154c 9537 #endif
wolfSSL 0:d92f9d21154c 9538 if (!ssl->options.tls)
wolfSSL 0:d92f9d21154c 9539 ret = DeriveKeys(ssl);
wolfSSL 0:d92f9d21154c 9540 #endif
wolfSSL 0:d92f9d21154c 9541 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
wolfSSL 0:d92f9d21154c 9542
wolfSSL 0:d92f9d21154c 9543 return ret;
wolfSSL 0:d92f9d21154c 9544 }
wolfSSL 0:d92f9d21154c 9545 else {
wolfSSL 0:d92f9d21154c 9546 WOLFSSL_MSG("Unsupported cipher suite, DoServerHello");
wolfSSL 0:d92f9d21154c 9547 return UNSUPPORTED_SUITE;
wolfSSL 0:d92f9d21154c 9548 }
wolfSSL 0:d92f9d21154c 9549 }
wolfSSL 0:d92f9d21154c 9550 else {
wolfSSL 0:d92f9d21154c 9551 WOLFSSL_MSG("Server denied resumption attempt");
wolfSSL 0:d92f9d21154c 9552 ssl->options.resuming = 0; /* server denied resumption try */
wolfSSL 0:d92f9d21154c 9553 }
wolfSSL 0:d92f9d21154c 9554 }
wolfSSL 0:d92f9d21154c 9555 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 9556 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 9557 DtlsPoolReset(ssl);
wolfSSL 0:d92f9d21154c 9558 }
wolfSSL 0:d92f9d21154c 9559 #endif
wolfSSL 0:d92f9d21154c 9560
wolfSSL 0:d92f9d21154c 9561 return SetCipherSpecs(ssl);
wolfSSL 0:d92f9d21154c 9562 }
wolfSSL 0:d92f9d21154c 9563
wolfSSL 0:d92f9d21154c 9564
wolfSSL 0:d92f9d21154c 9565 /* Make sure client setup is valid for this suite, true on success */
wolfSSL 0:d92f9d21154c 9566 int VerifyClientSuite(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 9567 {
wolfSSL 0:d92f9d21154c 9568 int havePSK = 0;
wolfSSL 0:d92f9d21154c 9569 byte first = ssl->options.cipherSuite0;
wolfSSL 0:d92f9d21154c 9570 byte second = ssl->options.cipherSuite;
wolfSSL 0:d92f9d21154c 9571
wolfSSL 0:d92f9d21154c 9572 WOLFSSL_ENTER("VerifyClientSuite");
wolfSSL 0:d92f9d21154c 9573
wolfSSL 0:d92f9d21154c 9574 #ifndef NO_PSK
wolfSSL 0:d92f9d21154c 9575 havePSK = ssl->options.havePSK;
wolfSSL 0:d92f9d21154c 9576 #endif
wolfSSL 0:d92f9d21154c 9577
wolfSSL 0:d92f9d21154c 9578 if (CipherRequires(first, second, REQUIRES_PSK)) {
wolfSSL 0:d92f9d21154c 9579 WOLFSSL_MSG("Requires PSK");
wolfSSL 0:d92f9d21154c 9580 if (havePSK == 0) {
wolfSSL 0:d92f9d21154c 9581 WOLFSSL_MSG("Don't have PSK");
wolfSSL 0:d92f9d21154c 9582 return 0;
wolfSSL 0:d92f9d21154c 9583 }
wolfSSL 0:d92f9d21154c 9584 }
wolfSSL 0:d92f9d21154c 9585
wolfSSL 0:d92f9d21154c 9586 return 1; /* success */
wolfSSL 0:d92f9d21154c 9587 }
wolfSSL 0:d92f9d21154c 9588
wolfSSL 0:d92f9d21154c 9589
wolfSSL 0:d92f9d21154c 9590 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 9591 /* just read in and ignore for now TODO: */
wolfSSL 0:d92f9d21154c 9592 static int DoCertificateRequest(WOLFSSL* ssl, const byte* input, word32*
wolfSSL 0:d92f9d21154c 9593 inOutIdx, word32 size)
wolfSSL 0:d92f9d21154c 9594 {
wolfSSL 0:d92f9d21154c 9595 word16 len;
wolfSSL 0:d92f9d21154c 9596 word32 begin = *inOutIdx;
wolfSSL 0:d92f9d21154c 9597
wolfSSL 0:d92f9d21154c 9598 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 9599 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 9600 AddPacketName("CertificateRequest", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 9601 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 9602 AddLateName("CertificateRequest", &ssl->timeoutInfo);
wolfSSL 0:d92f9d21154c 9603 #endif
wolfSSL 0:d92f9d21154c 9604
wolfSSL 0:d92f9d21154c 9605 if ((*inOutIdx - begin) + OPAQUE8_LEN > size)
wolfSSL 0:d92f9d21154c 9606 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9607
wolfSSL 0:d92f9d21154c 9608 len = input[(*inOutIdx)++];
wolfSSL 0:d92f9d21154c 9609
wolfSSL 0:d92f9d21154c 9610 if ((*inOutIdx - begin) + len > size)
wolfSSL 0:d92f9d21154c 9611 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9612
wolfSSL 0:d92f9d21154c 9613 /* types, read in here */
wolfSSL 0:d92f9d21154c 9614 *inOutIdx += len;
wolfSSL 0:d92f9d21154c 9615
wolfSSL 0:d92f9d21154c 9616 /* signature and hash signature algorithm */
wolfSSL 0:d92f9d21154c 9617 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 9618 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 9619 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9620
wolfSSL 0:d92f9d21154c 9621 ato16(input + *inOutIdx, &len);
wolfSSL 0:d92f9d21154c 9622 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 9623
wolfSSL 0:d92f9d21154c 9624 if ((*inOutIdx - begin) + len > size)
wolfSSL 0:d92f9d21154c 9625 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9626
wolfSSL 0:d92f9d21154c 9627 PickHashSigAlgo(ssl, input + *inOutIdx, len);
wolfSSL 0:d92f9d21154c 9628 *inOutIdx += len;
wolfSSL 0:d92f9d21154c 9629 }
wolfSSL 0:d92f9d21154c 9630
wolfSSL 0:d92f9d21154c 9631 /* authorities */
wolfSSL 0:d92f9d21154c 9632 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 9633 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9634
wolfSSL 0:d92f9d21154c 9635 ato16(input + *inOutIdx, &len);
wolfSSL 0:d92f9d21154c 9636 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 9637
wolfSSL 0:d92f9d21154c 9638 if ((*inOutIdx - begin) + len > size)
wolfSSL 0:d92f9d21154c 9639 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9640
wolfSSL 0:d92f9d21154c 9641 while (len) {
wolfSSL 0:d92f9d21154c 9642 word16 dnSz;
wolfSSL 0:d92f9d21154c 9643
wolfSSL 0:d92f9d21154c 9644 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 9645 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9646
wolfSSL 0:d92f9d21154c 9647 ato16(input + *inOutIdx, &dnSz);
wolfSSL 0:d92f9d21154c 9648 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 9649
wolfSSL 0:d92f9d21154c 9650 if ((*inOutIdx - begin) + dnSz > size)
wolfSSL 0:d92f9d21154c 9651 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9652
wolfSSL 0:d92f9d21154c 9653 *inOutIdx += dnSz;
wolfSSL 0:d92f9d21154c 9654 len -= OPAQUE16_LEN + dnSz;
wolfSSL 0:d92f9d21154c 9655 }
wolfSSL 0:d92f9d21154c 9656
wolfSSL 0:d92f9d21154c 9657 /* don't send client cert or cert verify if user hasn't provided
wolfSSL 0:d92f9d21154c 9658 cert and private key */
wolfSSL 0:d92f9d21154c 9659 if (ssl->buffers.certificate.buffer && ssl->buffers.key.buffer)
wolfSSL 0:d92f9d21154c 9660 ssl->options.sendVerify = SEND_CERT;
wolfSSL 0:d92f9d21154c 9661 else if (IsTLS(ssl))
wolfSSL 0:d92f9d21154c 9662 ssl->options.sendVerify = SEND_BLANK_CERT;
wolfSSL 0:d92f9d21154c 9663
wolfSSL 0:d92f9d21154c 9664 if (ssl->keys.encryptionOn)
wolfSSL 0:d92f9d21154c 9665 *inOutIdx += ssl->keys.padSz;
wolfSSL 0:d92f9d21154c 9666
wolfSSL 0:d92f9d21154c 9667 return 0;
wolfSSL 0:d92f9d21154c 9668 }
wolfSSL 0:d92f9d21154c 9669 #endif /* !NO_CERTS */
wolfSSL 0:d92f9d21154c 9670
wolfSSL 0:d92f9d21154c 9671
wolfSSL 0:d92f9d21154c 9672 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 9673
wolfSSL 0:d92f9d21154c 9674 static int CheckCurveId(int oid)
wolfSSL 0:d92f9d21154c 9675 {
wolfSSL 0:d92f9d21154c 9676 int ret = 0;
wolfSSL 0:d92f9d21154c 9677
wolfSSL 0:d92f9d21154c 9678 switch (oid) {
wolfSSL 0:d92f9d21154c 9679 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
wolfSSL 0:d92f9d21154c 9680 case WOLFSSL_ECC_SECP160R1:
wolfSSL 0:d92f9d21154c 9681 #endif
wolfSSL 0:d92f9d21154c 9682 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
wolfSSL 0:d92f9d21154c 9683 case WOLFSSL_ECC_SECP192R1:
wolfSSL 0:d92f9d21154c 9684 #endif
wolfSSL 0:d92f9d21154c 9685 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
wolfSSL 0:d92f9d21154c 9686 case WOLFSSL_ECC_SECP224R1:
wolfSSL 0:d92f9d21154c 9687 #endif
wolfSSL 0:d92f9d21154c 9688 #if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
wolfSSL 0:d92f9d21154c 9689 case WOLFSSL_ECC_SECP256R1:
wolfSSL 0:d92f9d21154c 9690 #endif
wolfSSL 0:d92f9d21154c 9691 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
wolfSSL 0:d92f9d21154c 9692 case WOLFSSL_ECC_SECP384R1:
wolfSSL 0:d92f9d21154c 9693 #endif
wolfSSL 0:d92f9d21154c 9694 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
wolfSSL 0:d92f9d21154c 9695 case WOLFSSL_ECC_SECP521R1:
wolfSSL 0:d92f9d21154c 9696 #endif
wolfSSL 0:d92f9d21154c 9697 break;
wolfSSL 0:d92f9d21154c 9698
wolfSSL 0:d92f9d21154c 9699 default:
wolfSSL 0:d92f9d21154c 9700 ret = -1;
wolfSSL 0:d92f9d21154c 9701 }
wolfSSL 0:d92f9d21154c 9702
wolfSSL 0:d92f9d21154c 9703 return ret;
wolfSSL 0:d92f9d21154c 9704 }
wolfSSL 0:d92f9d21154c 9705
wolfSSL 0:d92f9d21154c 9706 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 9707
wolfSSL 0:d92f9d21154c 9708 static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input,
wolfSSL 0:d92f9d21154c 9709 word32* inOutIdx, word32 size)
wolfSSL 0:d92f9d21154c 9710 {
wolfSSL 0:d92f9d21154c 9711 word16 length = 0;
wolfSSL 0:d92f9d21154c 9712 word32 begin = *inOutIdx;
wolfSSL 0:d92f9d21154c 9713 int ret = 0;
wolfSSL 0:d92f9d21154c 9714 #define ERROR_OUT(err, eLabel) do { ret = err; goto eLabel; } while(0)
wolfSSL 0:d92f9d21154c 9715
wolfSSL 0:d92f9d21154c 9716 (void)length; /* shut up compiler warnings */
wolfSSL 0:d92f9d21154c 9717 (void)begin;
wolfSSL 0:d92f9d21154c 9718 (void)ssl;
wolfSSL 0:d92f9d21154c 9719 (void)input;
wolfSSL 0:d92f9d21154c 9720 (void)size;
wolfSSL 0:d92f9d21154c 9721 (void)ret;
wolfSSL 0:d92f9d21154c 9722
wolfSSL 0:d92f9d21154c 9723 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 9724 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 9725 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 9726 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 9727 AddLateName("ServerKeyExchange", &ssl->timeoutInfo);
wolfSSL 0:d92f9d21154c 9728 #endif
wolfSSL 0:d92f9d21154c 9729
wolfSSL 0:d92f9d21154c 9730 #ifndef NO_PSK
wolfSSL 0:d92f9d21154c 9731 if (ssl->specs.kea == psk_kea) {
wolfSSL 0:d92f9d21154c 9732
wolfSSL 0:d92f9d21154c 9733 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 9734 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9735
wolfSSL 0:d92f9d21154c 9736 ato16(input + *inOutIdx, &length);
wolfSSL 0:d92f9d21154c 9737 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 9738
wolfSSL 0:d92f9d21154c 9739 if ((*inOutIdx - begin) + length > size)
wolfSSL 0:d92f9d21154c 9740 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9741
wolfSSL 0:d92f9d21154c 9742 XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx,
wolfSSL 0:d92f9d21154c 9743 min(length, MAX_PSK_ID_LEN));
wolfSSL 0:d92f9d21154c 9744
wolfSSL 0:d92f9d21154c 9745 ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0;
wolfSSL 0:d92f9d21154c 9746 *inOutIdx += length;
wolfSSL 0:d92f9d21154c 9747
wolfSSL 0:d92f9d21154c 9748 return 0;
wolfSSL 0:d92f9d21154c 9749 }
wolfSSL 0:d92f9d21154c 9750 #endif
wolfSSL 0:d92f9d21154c 9751 #ifndef NO_DH
wolfSSL 0:d92f9d21154c 9752 if (ssl->specs.kea == diffie_hellman_kea)
wolfSSL 0:d92f9d21154c 9753 {
wolfSSL 0:d92f9d21154c 9754 /* p */
wolfSSL 0:d92f9d21154c 9755 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 9756 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9757
wolfSSL 0:d92f9d21154c 9758 ato16(input + *inOutIdx, &length);
wolfSSL 0:d92f9d21154c 9759 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 9760
wolfSSL 0:d92f9d21154c 9761 if ((*inOutIdx - begin) + length > size)
wolfSSL 0:d92f9d21154c 9762 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9763
wolfSSL 0:d92f9d21154c 9764 if (length < ssl->options.minDhKeySz) {
wolfSSL 0:d92f9d21154c 9765 WOLFSSL_MSG("Server using a DH key that is too small");
wolfSSL 0:d92f9d21154c 9766 SendAlert(ssl, alert_fatal, handshake_failure);
wolfSSL 0:d92f9d21154c 9767 return DH_KEY_SIZE_E;
wolfSSL 0:d92f9d21154c 9768 }
wolfSSL 0:d92f9d21154c 9769
wolfSSL 0:d92f9d21154c 9770 ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
wolfSSL 0:d92f9d21154c 9771 DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 9772
wolfSSL 0:d92f9d21154c 9773 if (ssl->buffers.serverDH_P.buffer)
wolfSSL 0:d92f9d21154c 9774 ssl->buffers.serverDH_P.length = length;
wolfSSL 0:d92f9d21154c 9775 else
wolfSSL 0:d92f9d21154c 9776 return MEMORY_ERROR;
wolfSSL 0:d92f9d21154c 9777
wolfSSL 0:d92f9d21154c 9778 XMEMCPY(ssl->buffers.serverDH_P.buffer, input + *inOutIdx, length);
wolfSSL 0:d92f9d21154c 9779 *inOutIdx += length;
wolfSSL 0:d92f9d21154c 9780
wolfSSL 0:d92f9d21154c 9781 ssl->options.dhKeySz = length;
wolfSSL 0:d92f9d21154c 9782
wolfSSL 0:d92f9d21154c 9783 /* g */
wolfSSL 0:d92f9d21154c 9784 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 9785 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9786
wolfSSL 0:d92f9d21154c 9787 ato16(input + *inOutIdx, &length);
wolfSSL 0:d92f9d21154c 9788 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 9789
wolfSSL 0:d92f9d21154c 9790 if ((*inOutIdx - begin) + length > size)
wolfSSL 0:d92f9d21154c 9791 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9792
wolfSSL 0:d92f9d21154c 9793 ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
wolfSSL 0:d92f9d21154c 9794 DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 9795
wolfSSL 0:d92f9d21154c 9796 if (ssl->buffers.serverDH_G.buffer)
wolfSSL 0:d92f9d21154c 9797 ssl->buffers.serverDH_G.length = length;
wolfSSL 0:d92f9d21154c 9798 else
wolfSSL 0:d92f9d21154c 9799 return MEMORY_ERROR;
wolfSSL 0:d92f9d21154c 9800
wolfSSL 0:d92f9d21154c 9801 XMEMCPY(ssl->buffers.serverDH_G.buffer, input + *inOutIdx, length);
wolfSSL 0:d92f9d21154c 9802 *inOutIdx += length;
wolfSSL 0:d92f9d21154c 9803
wolfSSL 0:d92f9d21154c 9804 /* pub */
wolfSSL 0:d92f9d21154c 9805 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 9806 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9807
wolfSSL 0:d92f9d21154c 9808 ato16(input + *inOutIdx, &length);
wolfSSL 0:d92f9d21154c 9809 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 9810
wolfSSL 0:d92f9d21154c 9811 if ((*inOutIdx - begin) + length > size)
wolfSSL 0:d92f9d21154c 9812 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9813
wolfSSL 0:d92f9d21154c 9814 ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
wolfSSL 0:d92f9d21154c 9815 DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 9816
wolfSSL 0:d92f9d21154c 9817 if (ssl->buffers.serverDH_Pub.buffer)
wolfSSL 0:d92f9d21154c 9818 ssl->buffers.serverDH_Pub.length = length;
wolfSSL 0:d92f9d21154c 9819 else
wolfSSL 0:d92f9d21154c 9820 return MEMORY_ERROR;
wolfSSL 0:d92f9d21154c 9821
wolfSSL 0:d92f9d21154c 9822 XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + *inOutIdx, length);
wolfSSL 0:d92f9d21154c 9823 *inOutIdx += length;
wolfSSL 0:d92f9d21154c 9824 } /* dh_kea */
wolfSSL 0:d92f9d21154c 9825 #endif /* NO_DH */
wolfSSL 0:d92f9d21154c 9826
wolfSSL 0:d92f9d21154c 9827 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 9828 if (ssl->specs.kea == ecc_diffie_hellman_kea)
wolfSSL 0:d92f9d21154c 9829 {
wolfSSL 0:d92f9d21154c 9830 byte b;
wolfSSL 0:d92f9d21154c 9831
wolfSSL 0:d92f9d21154c 9832 if ((*inOutIdx - begin) + ENUM_LEN + OPAQUE16_LEN + OPAQUE8_LEN > size)
wolfSSL 0:d92f9d21154c 9833 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9834
wolfSSL 0:d92f9d21154c 9835 b = input[(*inOutIdx)++];
wolfSSL 0:d92f9d21154c 9836
wolfSSL 0:d92f9d21154c 9837 if (b != named_curve)
wolfSSL 0:d92f9d21154c 9838 return ECC_CURVETYPE_ERROR;
wolfSSL 0:d92f9d21154c 9839
wolfSSL 0:d92f9d21154c 9840 *inOutIdx += 1; /* curve type, eat leading 0 */
wolfSSL 0:d92f9d21154c 9841 b = input[(*inOutIdx)++];
wolfSSL 0:d92f9d21154c 9842
wolfSSL 0:d92f9d21154c 9843 if (CheckCurveId(b) != 0) {
wolfSSL 0:d92f9d21154c 9844 return ECC_CURVE_ERROR;
wolfSSL 0:d92f9d21154c 9845 }
wolfSSL 0:d92f9d21154c 9846
wolfSSL 0:d92f9d21154c 9847 length = input[(*inOutIdx)++];
wolfSSL 0:d92f9d21154c 9848
wolfSSL 0:d92f9d21154c 9849 if ((*inOutIdx - begin) + length > size)
wolfSSL 0:d92f9d21154c 9850 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9851
wolfSSL 0:d92f9d21154c 9852 if (ssl->peerEccKey == NULL) {
wolfSSL 0:d92f9d21154c 9853 /* alloc/init on demand */
wolfSSL 0:d92f9d21154c 9854 ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
wolfSSL 0:d92f9d21154c 9855 ssl->ctx->heap, DYNAMIC_TYPE_ECC);
wolfSSL 0:d92f9d21154c 9856 if (ssl->peerEccKey == NULL) {
wolfSSL 0:d92f9d21154c 9857 WOLFSSL_MSG("PeerEccKey Memory error");
wolfSSL 0:d92f9d21154c 9858 return MEMORY_E;
wolfSSL 0:d92f9d21154c 9859 }
wolfSSL 0:d92f9d21154c 9860 wc_ecc_init(ssl->peerEccKey);
wolfSSL 0:d92f9d21154c 9861 } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */
wolfSSL 0:d92f9d21154c 9862 wc_ecc_free(ssl->peerEccKey);
wolfSSL 0:d92f9d21154c 9863 ssl->peerEccKeyPresent = 0;
wolfSSL 0:d92f9d21154c 9864 wc_ecc_init(ssl->peerEccKey);
wolfSSL 0:d92f9d21154c 9865 }
wolfSSL 0:d92f9d21154c 9866
wolfSSL 0:d92f9d21154c 9867 if (wc_ecc_import_x963(input + *inOutIdx, length, ssl->peerEccKey) != 0)
wolfSSL 0:d92f9d21154c 9868 return ECC_PEERKEY_ERROR;
wolfSSL 0:d92f9d21154c 9869
wolfSSL 0:d92f9d21154c 9870 *inOutIdx += length;
wolfSSL 0:d92f9d21154c 9871 ssl->peerEccKeyPresent = 1;
wolfSSL 0:d92f9d21154c 9872 }
wolfSSL 0:d92f9d21154c 9873 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 9874
wolfSSL 0:d92f9d21154c 9875 #if !defined(NO_DH) && !defined(NO_PSK)
wolfSSL 0:d92f9d21154c 9876 if (ssl->specs.kea == dhe_psk_kea) {
wolfSSL 0:d92f9d21154c 9877 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 9878 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9879
wolfSSL 0:d92f9d21154c 9880 ato16(input + *inOutIdx, &length);
wolfSSL 0:d92f9d21154c 9881 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 9882
wolfSSL 0:d92f9d21154c 9883 if ((*inOutIdx - begin) + length > size)
wolfSSL 0:d92f9d21154c 9884 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9885
wolfSSL 0:d92f9d21154c 9886 XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx,
wolfSSL 0:d92f9d21154c 9887 min(length, MAX_PSK_ID_LEN));
wolfSSL 0:d92f9d21154c 9888
wolfSSL 0:d92f9d21154c 9889 ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0;
wolfSSL 0:d92f9d21154c 9890 *inOutIdx += length;
wolfSSL 0:d92f9d21154c 9891
wolfSSL 0:d92f9d21154c 9892 /* p */
wolfSSL 0:d92f9d21154c 9893 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 9894 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9895
wolfSSL 0:d92f9d21154c 9896 ato16(input + *inOutIdx, &length);
wolfSSL 0:d92f9d21154c 9897 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 9898
wolfSSL 0:d92f9d21154c 9899 if ((*inOutIdx - begin) + length > size)
wolfSSL 0:d92f9d21154c 9900 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9901
wolfSSL 0:d92f9d21154c 9902 if (length < ssl->options.minDhKeySz) {
wolfSSL 0:d92f9d21154c 9903 WOLFSSL_MSG("Server using a DH key that is too small");
wolfSSL 0:d92f9d21154c 9904 SendAlert(ssl, alert_fatal, handshake_failure);
wolfSSL 0:d92f9d21154c 9905 return DH_KEY_SIZE_E;
wolfSSL 0:d92f9d21154c 9906 }
wolfSSL 0:d92f9d21154c 9907
wolfSSL 0:d92f9d21154c 9908 ssl->buffers.serverDH_P.buffer = (byte*) XMALLOC(length, ssl->heap,
wolfSSL 0:d92f9d21154c 9909 DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 9910
wolfSSL 0:d92f9d21154c 9911 if (ssl->buffers.serverDH_P.buffer)
wolfSSL 0:d92f9d21154c 9912 ssl->buffers.serverDH_P.length = length;
wolfSSL 0:d92f9d21154c 9913 else
wolfSSL 0:d92f9d21154c 9914 return MEMORY_ERROR;
wolfSSL 0:d92f9d21154c 9915
wolfSSL 0:d92f9d21154c 9916 XMEMCPY(ssl->buffers.serverDH_P.buffer, input + *inOutIdx, length);
wolfSSL 0:d92f9d21154c 9917 *inOutIdx += length;
wolfSSL 0:d92f9d21154c 9918
wolfSSL 0:d92f9d21154c 9919 ssl->options.dhKeySz = length;
wolfSSL 0:d92f9d21154c 9920
wolfSSL 0:d92f9d21154c 9921 /* g */
wolfSSL 0:d92f9d21154c 9922 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 9923 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9924
wolfSSL 0:d92f9d21154c 9925 ato16(input + *inOutIdx, &length);
wolfSSL 0:d92f9d21154c 9926 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 9927
wolfSSL 0:d92f9d21154c 9928 if ((*inOutIdx - begin) + length > size)
wolfSSL 0:d92f9d21154c 9929 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9930
wolfSSL 0:d92f9d21154c 9931 ssl->buffers.serverDH_G.buffer = (byte*) XMALLOC(length, ssl->heap,
wolfSSL 0:d92f9d21154c 9932 DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 9933
wolfSSL 0:d92f9d21154c 9934 if (ssl->buffers.serverDH_G.buffer)
wolfSSL 0:d92f9d21154c 9935 ssl->buffers.serverDH_G.length = length;
wolfSSL 0:d92f9d21154c 9936 else
wolfSSL 0:d92f9d21154c 9937 return MEMORY_ERROR;
wolfSSL 0:d92f9d21154c 9938
wolfSSL 0:d92f9d21154c 9939 XMEMCPY(ssl->buffers.serverDH_G.buffer, input + *inOutIdx, length);
wolfSSL 0:d92f9d21154c 9940 *inOutIdx += length;
wolfSSL 0:d92f9d21154c 9941
wolfSSL 0:d92f9d21154c 9942 /* pub */
wolfSSL 0:d92f9d21154c 9943 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 9944 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9945
wolfSSL 0:d92f9d21154c 9946 ato16(input + *inOutIdx, &length);
wolfSSL 0:d92f9d21154c 9947 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 9948
wolfSSL 0:d92f9d21154c 9949 if ((*inOutIdx - begin) + length > size)
wolfSSL 0:d92f9d21154c 9950 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 9951
wolfSSL 0:d92f9d21154c 9952 ssl->buffers.serverDH_Pub.buffer = (byte*) XMALLOC(length, ssl->heap,
wolfSSL 0:d92f9d21154c 9953 DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 9954
wolfSSL 0:d92f9d21154c 9955 if (ssl->buffers.serverDH_Pub.buffer)
wolfSSL 0:d92f9d21154c 9956 ssl->buffers.serverDH_Pub.length = length;
wolfSSL 0:d92f9d21154c 9957 else
wolfSSL 0:d92f9d21154c 9958 return MEMORY_ERROR;
wolfSSL 0:d92f9d21154c 9959
wolfSSL 0:d92f9d21154c 9960 XMEMCPY(ssl->buffers.serverDH_Pub.buffer, input + *inOutIdx, length);
wolfSSL 0:d92f9d21154c 9961 *inOutIdx += length;
wolfSSL 0:d92f9d21154c 9962 }
wolfSSL 0:d92f9d21154c 9963 #endif /* !NO_DH || !NO_PSK */
wolfSSL 0:d92f9d21154c 9964
wolfSSL 0:d92f9d21154c 9965 #if !defined(NO_DH) || defined(HAVE_ECC)
wolfSSL 0:d92f9d21154c 9966 if (!ssl->options.usingAnon_cipher &&
wolfSSL 0:d92f9d21154c 9967 (ssl->specs.kea == ecc_diffie_hellman_kea ||
wolfSSL 0:d92f9d21154c 9968 ssl->specs.kea == diffie_hellman_kea))
wolfSSL 0:d92f9d21154c 9969 {
wolfSSL 0:d92f9d21154c 9970 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 9971 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 9972 Md5* md5 = NULL;
wolfSSL 0:d92f9d21154c 9973 Sha* sha = NULL;
wolfSSL 0:d92f9d21154c 9974 #else
wolfSSL 0:d92f9d21154c 9975 Md5 md5[1];
wolfSSL 0:d92f9d21154c 9976 Sha sha[1];
wolfSSL 0:d92f9d21154c 9977 #endif
wolfSSL 0:d92f9d21154c 9978 #endif
wolfSSL 0:d92f9d21154c 9979 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 9980 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 9981 Sha256* sha256 = NULL;
wolfSSL 0:d92f9d21154c 9982 byte* hash256 = NULL;
wolfSSL 0:d92f9d21154c 9983 #else
wolfSSL 0:d92f9d21154c 9984 Sha256 sha256[1];
wolfSSL 0:d92f9d21154c 9985 byte hash256[SHA256_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 9986 #endif
wolfSSL 0:d92f9d21154c 9987 #endif
wolfSSL 0:d92f9d21154c 9988 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 9989 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 9990 Sha384* sha384 = NULL;
wolfSSL 0:d92f9d21154c 9991 byte* hash384 = NULL;
wolfSSL 0:d92f9d21154c 9992 #else
wolfSSL 0:d92f9d21154c 9993 Sha384 sha384[1];
wolfSSL 0:d92f9d21154c 9994 byte hash384[SHA384_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 9995 #endif
wolfSSL 0:d92f9d21154c 9996 #endif
wolfSSL 0:d92f9d21154c 9997 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 9998 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 9999 Sha512* sha512 = NULL;
wolfSSL 0:d92f9d21154c 10000 byte* hash512 = NULL;
wolfSSL 0:d92f9d21154c 10001 #else
wolfSSL 0:d92f9d21154c 10002 Sha512 sha512[1];
wolfSSL 0:d92f9d21154c 10003 byte hash512[SHA512_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 10004 #endif
wolfSSL 0:d92f9d21154c 10005 #endif
wolfSSL 0:d92f9d21154c 10006 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10007 byte* hash = NULL;
wolfSSL 0:d92f9d21154c 10008 byte* messageVerify = NULL;
wolfSSL 0:d92f9d21154c 10009 #else
wolfSSL 0:d92f9d21154c 10010 byte hash[FINISHED_SZ];
wolfSSL 0:d92f9d21154c 10011 byte messageVerify[MAX_DH_SZ];
wolfSSL 0:d92f9d21154c 10012 #endif
wolfSSL 0:d92f9d21154c 10013 byte hashAlgo = sha_mac;
wolfSSL 0:d92f9d21154c 10014 byte sigAlgo = ssl->specs.sig_algo;
wolfSSL 0:d92f9d21154c 10015 word16 verifySz = (word16) (*inOutIdx - begin);
wolfSSL 0:d92f9d21154c 10016
wolfSSL 0:d92f9d21154c 10017 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 10018 byte doMd5 = 0;
wolfSSL 0:d92f9d21154c 10019 byte doSha = 0;
wolfSSL 0:d92f9d21154c 10020 #endif
wolfSSL 0:d92f9d21154c 10021 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 10022 byte doSha256 = 0;
wolfSSL 0:d92f9d21154c 10023 #endif
wolfSSL 0:d92f9d21154c 10024 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 10025 byte doSha384 = 0;
wolfSSL 0:d92f9d21154c 10026 #endif
wolfSSL 0:d92f9d21154c 10027 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 10028 byte doSha512 = 0;
wolfSSL 0:d92f9d21154c 10029 #endif
wolfSSL 0:d92f9d21154c 10030
wolfSSL 0:d92f9d21154c 10031 (void)hash;
wolfSSL 0:d92f9d21154c 10032 (void)sigAlgo;
wolfSSL 0:d92f9d21154c 10033 (void)hashAlgo;
wolfSSL 0:d92f9d21154c 10034
wolfSSL 0:d92f9d21154c 10035 /* save message for hash verify */
wolfSSL 0:d92f9d21154c 10036 if (verifySz > MAX_DH_SZ)
wolfSSL 0:d92f9d21154c 10037 ERROR_OUT(BUFFER_ERROR, done);
wolfSSL 0:d92f9d21154c 10038
wolfSSL 0:d92f9d21154c 10039 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10040 messageVerify = (byte*)XMALLOC(MAX_DH_SZ, NULL,
wolfSSL 0:d92f9d21154c 10041 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10042 if (messageVerify == NULL)
wolfSSL 0:d92f9d21154c 10043 ERROR_OUT(MEMORY_E, done);
wolfSSL 0:d92f9d21154c 10044 #endif
wolfSSL 0:d92f9d21154c 10045
wolfSSL 0:d92f9d21154c 10046 XMEMCPY(messageVerify, input + begin, verifySz);
wolfSSL 0:d92f9d21154c 10047
wolfSSL 0:d92f9d21154c 10048 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 10049 byte setHash = 0;
wolfSSL 0:d92f9d21154c 10050 if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size)
wolfSSL 0:d92f9d21154c 10051 ERROR_OUT(BUFFER_ERROR, done);
wolfSSL 0:d92f9d21154c 10052
wolfSSL 0:d92f9d21154c 10053 hashAlgo = input[(*inOutIdx)++];
wolfSSL 0:d92f9d21154c 10054 sigAlgo = input[(*inOutIdx)++];
wolfSSL 0:d92f9d21154c 10055
wolfSSL 0:d92f9d21154c 10056 switch (hashAlgo) {
wolfSSL 0:d92f9d21154c 10057 case sha512_mac:
wolfSSL 0:d92f9d21154c 10058 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 10059 doSha512 = 1;
wolfSSL 0:d92f9d21154c 10060 setHash = 1;
wolfSSL 0:d92f9d21154c 10061 #endif
wolfSSL 0:d92f9d21154c 10062 break;
wolfSSL 0:d92f9d21154c 10063
wolfSSL 0:d92f9d21154c 10064 case sha384_mac:
wolfSSL 0:d92f9d21154c 10065 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 10066 doSha384 = 1;
wolfSSL 0:d92f9d21154c 10067 setHash = 1;
wolfSSL 0:d92f9d21154c 10068 #endif
wolfSSL 0:d92f9d21154c 10069 break;
wolfSSL 0:d92f9d21154c 10070
wolfSSL 0:d92f9d21154c 10071 case sha256_mac:
wolfSSL 0:d92f9d21154c 10072 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 10073 doSha256 = 1;
wolfSSL 0:d92f9d21154c 10074 setHash = 1;
wolfSSL 0:d92f9d21154c 10075 #endif
wolfSSL 0:d92f9d21154c 10076 break;
wolfSSL 0:d92f9d21154c 10077
wolfSSL 0:d92f9d21154c 10078 case sha_mac:
wolfSSL 0:d92f9d21154c 10079 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 10080 doSha = 1;
wolfSSL 0:d92f9d21154c 10081 setHash = 1;
wolfSSL 0:d92f9d21154c 10082 #endif
wolfSSL 0:d92f9d21154c 10083 break;
wolfSSL 0:d92f9d21154c 10084
wolfSSL 0:d92f9d21154c 10085 default:
wolfSSL 0:d92f9d21154c 10086 ERROR_OUT(ALGO_ID_E, done);
wolfSSL 0:d92f9d21154c 10087 }
wolfSSL 0:d92f9d21154c 10088
wolfSSL 0:d92f9d21154c 10089 if (setHash == 0) {
wolfSSL 0:d92f9d21154c 10090 ERROR_OUT(ALGO_ID_E, done);
wolfSSL 0:d92f9d21154c 10091 }
wolfSSL 0:d92f9d21154c 10092
wolfSSL 0:d92f9d21154c 10093 } else {
wolfSSL 0:d92f9d21154c 10094 /* only using sha and md5 for rsa */
wolfSSL 0:d92f9d21154c 10095 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 10096 doSha = 1;
wolfSSL 0:d92f9d21154c 10097 if (sigAlgo == rsa_sa_algo) {
wolfSSL 0:d92f9d21154c 10098 doMd5 = 1;
wolfSSL 0:d92f9d21154c 10099 }
wolfSSL 0:d92f9d21154c 10100 #else
wolfSSL 0:d92f9d21154c 10101 ERROR_OUT(ALGO_ID_E, done);
wolfSSL 0:d92f9d21154c 10102 #endif
wolfSSL 0:d92f9d21154c 10103 }
wolfSSL 0:d92f9d21154c 10104
wolfSSL 0:d92f9d21154c 10105 /* signature */
wolfSSL 0:d92f9d21154c 10106 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 10107 ERROR_OUT(BUFFER_ERROR, done);
wolfSSL 0:d92f9d21154c 10108
wolfSSL 0:d92f9d21154c 10109 ato16(input + *inOutIdx, &length);
wolfSSL 0:d92f9d21154c 10110 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 10111
wolfSSL 0:d92f9d21154c 10112 if ((*inOutIdx - begin) + length > size)
wolfSSL 0:d92f9d21154c 10113 ERROR_OUT(BUFFER_ERROR, done);
wolfSSL 0:d92f9d21154c 10114
wolfSSL 0:d92f9d21154c 10115 /* inOutIdx updated at the end of the function */
wolfSSL 0:d92f9d21154c 10116
wolfSSL 0:d92f9d21154c 10117 /* verify signature */
wolfSSL 0:d92f9d21154c 10118 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10119 hash = (byte*)XMALLOC(FINISHED_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10120 if (hash == NULL)
wolfSSL 0:d92f9d21154c 10121 ERROR_OUT(MEMORY_E, done);
wolfSSL 0:d92f9d21154c 10122 #endif
wolfSSL 0:d92f9d21154c 10123
wolfSSL 0:d92f9d21154c 10124 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 10125 /* md5 */
wolfSSL 0:d92f9d21154c 10126 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10127 if (doMd5) {
wolfSSL 0:d92f9d21154c 10128 md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10129 if (md5 == NULL)
wolfSSL 0:d92f9d21154c 10130 ERROR_OUT(MEMORY_E, done);
wolfSSL 0:d92f9d21154c 10131 }
wolfSSL 0:d92f9d21154c 10132 #endif
wolfSSL 0:d92f9d21154c 10133 if (doMd5) {
wolfSSL 0:d92f9d21154c 10134 wc_InitMd5(md5);
wolfSSL 0:d92f9d21154c 10135 wc_Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
wolfSSL 0:d92f9d21154c 10136 wc_Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
wolfSSL 0:d92f9d21154c 10137 wc_Md5Update(md5, messageVerify, verifySz);
wolfSSL 0:d92f9d21154c 10138 wc_Md5Final(md5, hash);
wolfSSL 0:d92f9d21154c 10139 }
wolfSSL 0:d92f9d21154c 10140 /* sha */
wolfSSL 0:d92f9d21154c 10141 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10142 if (doSha) {
wolfSSL 0:d92f9d21154c 10143 sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10144 if (sha == NULL)
wolfSSL 0:d92f9d21154c 10145 ERROR_OUT(MEMORY_E, done);
wolfSSL 0:d92f9d21154c 10146 }
wolfSSL 0:d92f9d21154c 10147 #endif
wolfSSL 0:d92f9d21154c 10148 if (doSha) {
wolfSSL 0:d92f9d21154c 10149 ret = wc_InitSha(sha);
wolfSSL 0:d92f9d21154c 10150 if (ret != 0) goto done;
wolfSSL 0:d92f9d21154c 10151 wc_ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
wolfSSL 0:d92f9d21154c 10152 wc_ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
wolfSSL 0:d92f9d21154c 10153 wc_ShaUpdate(sha, messageVerify, verifySz);
wolfSSL 0:d92f9d21154c 10154 wc_ShaFinal(sha, hash + MD5_DIGEST_SIZE);
wolfSSL 0:d92f9d21154c 10155 }
wolfSSL 0:d92f9d21154c 10156 #endif
wolfSSL 0:d92f9d21154c 10157
wolfSSL 0:d92f9d21154c 10158 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 10159 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10160 if (doSha256) {
wolfSSL 0:d92f9d21154c 10161 sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
wolfSSL 0:d92f9d21154c 10162 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10163 hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
wolfSSL 0:d92f9d21154c 10164 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10165 if (sha256 == NULL || hash256 == NULL)
wolfSSL 0:d92f9d21154c 10166 ERROR_OUT(MEMORY_E, done);
wolfSSL 0:d92f9d21154c 10167 }
wolfSSL 0:d92f9d21154c 10168 #endif
wolfSSL 0:d92f9d21154c 10169 if (doSha256) {
wolfSSL 0:d92f9d21154c 10170 if (!(ret = wc_InitSha256(sha256))
wolfSSL 0:d92f9d21154c 10171 && !(ret = wc_Sha256Update(sha256, ssl->arrays->clientRandom,
wolfSSL 0:d92f9d21154c 10172 RAN_LEN))
wolfSSL 0:d92f9d21154c 10173 && !(ret = wc_Sha256Update(sha256, ssl->arrays->serverRandom,
wolfSSL 0:d92f9d21154c 10174 RAN_LEN))
wolfSSL 0:d92f9d21154c 10175 && !(ret = wc_Sha256Update(sha256, messageVerify, verifySz)))
wolfSSL 0:d92f9d21154c 10176 ret = wc_Sha256Final(sha256, hash256);
wolfSSL 0:d92f9d21154c 10177 if (ret != 0) goto done;
wolfSSL 0:d92f9d21154c 10178 }
wolfSSL 0:d92f9d21154c 10179 #endif
wolfSSL 0:d92f9d21154c 10180
wolfSSL 0:d92f9d21154c 10181 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 10182 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10183 if (doSha384) {
wolfSSL 0:d92f9d21154c 10184 sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
wolfSSL 0:d92f9d21154c 10185 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10186 hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
wolfSSL 0:d92f9d21154c 10187 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10188 if (sha384 == NULL || hash384 == NULL)
wolfSSL 0:d92f9d21154c 10189 ERROR_OUT(MEMORY_E, done);
wolfSSL 0:d92f9d21154c 10190 }
wolfSSL 0:d92f9d21154c 10191 #endif
wolfSSL 0:d92f9d21154c 10192 if (doSha384) {
wolfSSL 0:d92f9d21154c 10193 if (!(ret = wc_InitSha384(sha384))
wolfSSL 0:d92f9d21154c 10194 && !(ret = wc_Sha384Update(sha384, ssl->arrays->clientRandom,
wolfSSL 0:d92f9d21154c 10195 RAN_LEN))
wolfSSL 0:d92f9d21154c 10196 && !(ret = wc_Sha384Update(sha384, ssl->arrays->serverRandom,
wolfSSL 0:d92f9d21154c 10197 RAN_LEN))
wolfSSL 0:d92f9d21154c 10198 && !(ret = wc_Sha384Update(sha384, messageVerify, verifySz)))
wolfSSL 0:d92f9d21154c 10199 ret = wc_Sha384Final(sha384, hash384);
wolfSSL 0:d92f9d21154c 10200 if (ret != 0) goto done;
wolfSSL 0:d92f9d21154c 10201 }
wolfSSL 0:d92f9d21154c 10202 #endif
wolfSSL 0:d92f9d21154c 10203
wolfSSL 0:d92f9d21154c 10204 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 10205 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10206 if (doSha512) {
wolfSSL 0:d92f9d21154c 10207 sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL,
wolfSSL 0:d92f9d21154c 10208 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10209 hash512 = (byte*)XMALLOC(SHA512_DIGEST_SIZE, NULL,
wolfSSL 0:d92f9d21154c 10210 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10211 if (sha512 == NULL || hash512 == NULL)
wolfSSL 0:d92f9d21154c 10212 ERROR_OUT(MEMORY_E, done);
wolfSSL 0:d92f9d21154c 10213 }
wolfSSL 0:d92f9d21154c 10214 #endif
wolfSSL 0:d92f9d21154c 10215 if (doSha512) {
wolfSSL 0:d92f9d21154c 10216 if (!(ret = wc_InitSha512(sha512))
wolfSSL 0:d92f9d21154c 10217 && !(ret = wc_Sha512Update(sha512, ssl->arrays->clientRandom,
wolfSSL 0:d92f9d21154c 10218 RAN_LEN))
wolfSSL 0:d92f9d21154c 10219 && !(ret = wc_Sha512Update(sha512, ssl->arrays->serverRandom,
wolfSSL 0:d92f9d21154c 10220 RAN_LEN))
wolfSSL 0:d92f9d21154c 10221 && !(ret = wc_Sha512Update(sha512, messageVerify, verifySz)))
wolfSSL 0:d92f9d21154c 10222 ret = wc_Sha512Final(sha512, hash512);
wolfSSL 0:d92f9d21154c 10223 if (ret != 0) goto done;
wolfSSL 0:d92f9d21154c 10224 }
wolfSSL 0:d92f9d21154c 10225 #endif
wolfSSL 0:d92f9d21154c 10226
wolfSSL 0:d92f9d21154c 10227 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 10228 /* rsa */
wolfSSL 0:d92f9d21154c 10229 if (sigAlgo == rsa_sa_algo)
wolfSSL 0:d92f9d21154c 10230 {
wolfSSL 0:d92f9d21154c 10231 byte* out = NULL;
wolfSSL 0:d92f9d21154c 10232 byte doUserRsa = 0;
wolfSSL 0:d92f9d21154c 10233 word32 verifiedSz = 0;
wolfSSL 0:d92f9d21154c 10234
wolfSSL 0:d92f9d21154c 10235 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 10236 if (ssl->ctx->RsaVerifyCb)
wolfSSL 0:d92f9d21154c 10237 doUserRsa = 1;
wolfSSL 0:d92f9d21154c 10238 #endif /*HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 10239
wolfSSL 0:d92f9d21154c 10240 if (ssl->peerRsaKey == NULL || !ssl->peerRsaKeyPresent)
wolfSSL 0:d92f9d21154c 10241 ERROR_OUT(NO_PEER_KEY, done);
wolfSSL 0:d92f9d21154c 10242
wolfSSL 0:d92f9d21154c 10243 if (doUserRsa) {
wolfSSL 0:d92f9d21154c 10244 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 10245 verifiedSz = ssl->ctx->RsaVerifyCb(ssl,
wolfSSL 0:d92f9d21154c 10246 (byte *)input + *inOutIdx,
wolfSSL 0:d92f9d21154c 10247 length, &out,
wolfSSL 0:d92f9d21154c 10248 ssl->buffers.peerRsaKey.buffer,
wolfSSL 0:d92f9d21154c 10249 ssl->buffers.peerRsaKey.length,
wolfSSL 0:d92f9d21154c 10250 ssl->RsaVerifyCtx);
wolfSSL 0:d92f9d21154c 10251 #endif /*HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 10252 }
wolfSSL 0:d92f9d21154c 10253 else
wolfSSL 0:d92f9d21154c 10254 verifiedSz = wc_RsaSSL_VerifyInline((byte *)input + *inOutIdx,
wolfSSL 0:d92f9d21154c 10255 length, &out, ssl->peerRsaKey);
wolfSSL 0:d92f9d21154c 10256
wolfSSL 0:d92f9d21154c 10257 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 10258 word32 encSigSz;
wolfSSL 0:d92f9d21154c 10259 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 10260 byte* digest = &hash[MD5_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 10261 int typeH = SHAh;
wolfSSL 0:d92f9d21154c 10262 int digestSz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 10263 #else
wolfSSL 0:d92f9d21154c 10264 byte* digest = hash256;
wolfSSL 0:d92f9d21154c 10265 int typeH = SHA256h;
wolfSSL 0:d92f9d21154c 10266 int digestSz = SHA256_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 10267 #endif
wolfSSL 0:d92f9d21154c 10268 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10269 byte* encodedSig = NULL;
wolfSSL 0:d92f9d21154c 10270 #else
wolfSSL 0:d92f9d21154c 10271 byte encodedSig[MAX_ENCODED_SIG_SZ];
wolfSSL 0:d92f9d21154c 10272 #endif
wolfSSL 0:d92f9d21154c 10273
wolfSSL 0:d92f9d21154c 10274 if (hashAlgo == sha_mac) {
wolfSSL 0:d92f9d21154c 10275 #ifndef NO_SHA
wolfSSL 0:d92f9d21154c 10276 digest = &hash[MD5_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 10277 typeH = SHAh;
wolfSSL 0:d92f9d21154c 10278 digestSz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 10279 #endif
wolfSSL 0:d92f9d21154c 10280 }
wolfSSL 0:d92f9d21154c 10281 else if (hashAlgo == sha256_mac) {
wolfSSL 0:d92f9d21154c 10282 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 10283 digest = hash256;
wolfSSL 0:d92f9d21154c 10284 typeH = SHA256h;
wolfSSL 0:d92f9d21154c 10285 digestSz = SHA256_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 10286 #endif
wolfSSL 0:d92f9d21154c 10287 }
wolfSSL 0:d92f9d21154c 10288 else if (hashAlgo == sha384_mac) {
wolfSSL 0:d92f9d21154c 10289 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 10290 digest = hash384;
wolfSSL 0:d92f9d21154c 10291 typeH = SHA384h;
wolfSSL 0:d92f9d21154c 10292 digestSz = SHA384_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 10293 #endif
wolfSSL 0:d92f9d21154c 10294 }
wolfSSL 0:d92f9d21154c 10295 else if (hashAlgo == sha512_mac) {
wolfSSL 0:d92f9d21154c 10296 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 10297 digest = hash512;
wolfSSL 0:d92f9d21154c 10298 typeH = SHA512h;
wolfSSL 0:d92f9d21154c 10299 digestSz = SHA512_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 10300 #endif
wolfSSL 0:d92f9d21154c 10301 }
wolfSSL 0:d92f9d21154c 10302
wolfSSL 0:d92f9d21154c 10303 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10304 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
wolfSSL 0:d92f9d21154c 10305 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10306 if (encodedSig == NULL)
wolfSSL 0:d92f9d21154c 10307 ERROR_OUT(MEMORY_E, done);
wolfSSL 0:d92f9d21154c 10308 #endif
wolfSSL 0:d92f9d21154c 10309
wolfSSL 0:d92f9d21154c 10310 if (digest == NULL)
wolfSSL 0:d92f9d21154c 10311 ERROR_OUT(ALGO_ID_E, done);
wolfSSL 0:d92f9d21154c 10312 encSigSz = wc_EncodeSignature(encodedSig, digest, digestSz,
wolfSSL 0:d92f9d21154c 10313 typeH);
wolfSSL 0:d92f9d21154c 10314 if (encSigSz != verifiedSz || !out || XMEMCMP(out, encodedSig,
wolfSSL 0:d92f9d21154c 10315 min(encSigSz, MAX_ENCODED_SIG_SZ)) != 0)
wolfSSL 0:d92f9d21154c 10316 ret = VERIFY_SIGN_ERROR;
wolfSSL 0:d92f9d21154c 10317
wolfSSL 0:d92f9d21154c 10318 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10319 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10320 #endif
wolfSSL 0:d92f9d21154c 10321 if (ret != 0)
wolfSSL 0:d92f9d21154c 10322 goto done;
wolfSSL 0:d92f9d21154c 10323 }
wolfSSL 0:d92f9d21154c 10324 else if (verifiedSz != FINISHED_SZ || !out || XMEMCMP(out,
wolfSSL 0:d92f9d21154c 10325 hash, FINISHED_SZ) != 0)
wolfSSL 0:d92f9d21154c 10326 ERROR_OUT(VERIFY_SIGN_ERROR, done);
wolfSSL 0:d92f9d21154c 10327 } else
wolfSSL 0:d92f9d21154c 10328 #endif
wolfSSL 0:d92f9d21154c 10329 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 10330 /* ecdsa */
wolfSSL 0:d92f9d21154c 10331 if (sigAlgo == ecc_dsa_sa_algo) {
wolfSSL 0:d92f9d21154c 10332 int verify = 0;
wolfSSL 0:d92f9d21154c 10333 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 10334 byte* digest = &hash[MD5_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 10335 word32 digestSz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 10336 #else
wolfSSL 0:d92f9d21154c 10337 byte* digest = hash256;
wolfSSL 0:d92f9d21154c 10338 word32 digestSz = SHA256_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 10339 #endif
wolfSSL 0:d92f9d21154c 10340 byte doUserEcc = 0;
wolfSSL 0:d92f9d21154c 10341
wolfSSL 0:d92f9d21154c 10342 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 10343 if (ssl->ctx->EccVerifyCb)
wolfSSL 0:d92f9d21154c 10344 doUserEcc = 1;
wolfSSL 0:d92f9d21154c 10345 #endif
wolfSSL 0:d92f9d21154c 10346
wolfSSL 0:d92f9d21154c 10347 if (!ssl->peerEccDsaKeyPresent)
wolfSSL 0:d92f9d21154c 10348 ERROR_OUT(NO_PEER_KEY, done);
wolfSSL 0:d92f9d21154c 10349
wolfSSL 0:d92f9d21154c 10350 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 10351 if (hashAlgo == sha_mac) {
wolfSSL 0:d92f9d21154c 10352 #ifndef NO_SHA
wolfSSL 0:d92f9d21154c 10353 digest = &hash[MD5_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 10354 digestSz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 10355 #endif
wolfSSL 0:d92f9d21154c 10356 }
wolfSSL 0:d92f9d21154c 10357 else if (hashAlgo == sha256_mac) {
wolfSSL 0:d92f9d21154c 10358 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 10359 digest = hash256;
wolfSSL 0:d92f9d21154c 10360 digestSz = SHA256_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 10361 #endif
wolfSSL 0:d92f9d21154c 10362 }
wolfSSL 0:d92f9d21154c 10363 else if (hashAlgo == sha384_mac) {
wolfSSL 0:d92f9d21154c 10364 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 10365 digest = hash384;
wolfSSL 0:d92f9d21154c 10366 digestSz = SHA384_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 10367 #endif
wolfSSL 0:d92f9d21154c 10368 }
wolfSSL 0:d92f9d21154c 10369 else if (hashAlgo == sha512_mac) {
wolfSSL 0:d92f9d21154c 10370 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 10371 digest = hash512;
wolfSSL 0:d92f9d21154c 10372 digestSz = SHA512_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 10373 #endif
wolfSSL 0:d92f9d21154c 10374 }
wolfSSL 0:d92f9d21154c 10375 }
wolfSSL 0:d92f9d21154c 10376 if (doUserEcc) {
wolfSSL 0:d92f9d21154c 10377 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 10378 ret = ssl->ctx->EccVerifyCb(ssl, input + *inOutIdx, length,
wolfSSL 0:d92f9d21154c 10379 digest, digestSz,
wolfSSL 0:d92f9d21154c 10380 ssl->buffers.peerEccDsaKey.buffer,
wolfSSL 0:d92f9d21154c 10381 ssl->buffers.peerEccDsaKey.length,
wolfSSL 0:d92f9d21154c 10382 &verify, ssl->EccVerifyCtx);
wolfSSL 0:d92f9d21154c 10383 #endif
wolfSSL 0:d92f9d21154c 10384 }
wolfSSL 0:d92f9d21154c 10385 else {
wolfSSL 0:d92f9d21154c 10386 ret = wc_ecc_verify_hash(input + *inOutIdx, length,
wolfSSL 0:d92f9d21154c 10387 digest, digestSz, &verify, ssl->peerEccDsaKey);
wolfSSL 0:d92f9d21154c 10388 }
wolfSSL 0:d92f9d21154c 10389 if (ret != 0 || verify == 0)
wolfSSL 0:d92f9d21154c 10390 ERROR_OUT(VERIFY_SIGN_ERROR, done);
wolfSSL 0:d92f9d21154c 10391 }
wolfSSL 0:d92f9d21154c 10392 else
wolfSSL 0:d92f9d21154c 10393 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 10394 ERROR_OUT(ALGO_ID_E, done);
wolfSSL 0:d92f9d21154c 10395
wolfSSL 0:d92f9d21154c 10396 /* signature length */
wolfSSL 0:d92f9d21154c 10397 *inOutIdx += length;
wolfSSL 0:d92f9d21154c 10398
wolfSSL 0:d92f9d21154c 10399 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
wolfSSL 0:d92f9d21154c 10400
wolfSSL 0:d92f9d21154c 10401 done:
wolfSSL 0:d92f9d21154c 10402 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10403 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 10404 XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10405 XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10406 #endif
wolfSSL 0:d92f9d21154c 10407 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 10408 XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10409 XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10410 #endif
wolfSSL 0:d92f9d21154c 10411 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 10412 XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10413 XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10414 #endif
wolfSSL 0:d92f9d21154c 10415 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 10416 XFREE(sha512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10417 XFREE(hash512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10418 #endif
wolfSSL 0:d92f9d21154c 10419 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10420 XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10421 #endif
wolfSSL 0:d92f9d21154c 10422 if (ret != 0)
wolfSSL 0:d92f9d21154c 10423 return ret;
wolfSSL 0:d92f9d21154c 10424 }
wolfSSL 0:d92f9d21154c 10425
wolfSSL 0:d92f9d21154c 10426 if (ssl->keys.encryptionOn) {
wolfSSL 0:d92f9d21154c 10427 *inOutIdx += ssl->keys.padSz;
wolfSSL 0:d92f9d21154c 10428 }
wolfSSL 0:d92f9d21154c 10429
wolfSSL 0:d92f9d21154c 10430 return 0;
wolfSSL 0:d92f9d21154c 10431 #else /* !NO_DH or HAVE_ECC */
wolfSSL 0:d92f9d21154c 10432 return NOT_COMPILED_IN; /* not supported by build */
wolfSSL 0:d92f9d21154c 10433 #endif /* !NO_DH or HAVE_ECC */
wolfSSL 0:d92f9d21154c 10434
wolfSSL 0:d92f9d21154c 10435 #undef ERROR_OUT
wolfSSL 0:d92f9d21154c 10436 }
wolfSSL 0:d92f9d21154c 10437
wolfSSL 0:d92f9d21154c 10438
wolfSSL 0:d92f9d21154c 10439 int SendClientKeyExchange(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 10440 {
wolfSSL 0:d92f9d21154c 10441 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10442 byte* encSecret = NULL;
wolfSSL 0:d92f9d21154c 10443 #else
wolfSSL 0:d92f9d21154c 10444 byte encSecret[MAX_ENCRYPT_SZ];
wolfSSL 0:d92f9d21154c 10445 #endif
wolfSSL 0:d92f9d21154c 10446 word32 encSz = 0;
wolfSSL 0:d92f9d21154c 10447 word32 idx = 0;
wolfSSL 0:d92f9d21154c 10448 int ret = 0;
wolfSSL 0:d92f9d21154c 10449 byte doUserRsa = 0;
wolfSSL 0:d92f9d21154c 10450
wolfSSL 0:d92f9d21154c 10451 (void)doUserRsa;
wolfSSL 0:d92f9d21154c 10452
wolfSSL 0:d92f9d21154c 10453 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 10454 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 10455 if (ssl->ctx->RsaEncCb)
wolfSSL 0:d92f9d21154c 10456 doUserRsa = 1;
wolfSSL 0:d92f9d21154c 10457 #endif /* NO_RSA */
wolfSSL 0:d92f9d21154c 10458 #endif /*HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 10459
wolfSSL 0:d92f9d21154c 10460 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10461 encSecret = (byte*)XMALLOC(MAX_ENCRYPT_SZ, NULL,
wolfSSL 0:d92f9d21154c 10462 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10463 if (encSecret == NULL)
wolfSSL 0:d92f9d21154c 10464 return MEMORY_E;
wolfSSL 0:d92f9d21154c 10465 #endif
wolfSSL 0:d92f9d21154c 10466
wolfSSL 0:d92f9d21154c 10467 switch (ssl->specs.kea) {
wolfSSL 0:d92f9d21154c 10468 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 10469 case rsa_kea:
wolfSSL 0:d92f9d21154c 10470 ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret,
wolfSSL 0:d92f9d21154c 10471 SECRET_LEN);
wolfSSL 0:d92f9d21154c 10472 if (ret != 0) {
wolfSSL 0:d92f9d21154c 10473 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10474 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10475 #endif
wolfSSL 0:d92f9d21154c 10476 return ret;
wolfSSL 0:d92f9d21154c 10477 }
wolfSSL 0:d92f9d21154c 10478
wolfSSL 0:d92f9d21154c 10479 ssl->arrays->preMasterSecret[0] = ssl->chVersion.major;
wolfSSL 0:d92f9d21154c 10480 ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor;
wolfSSL 0:d92f9d21154c 10481 ssl->arrays->preMasterSz = SECRET_LEN;
wolfSSL 0:d92f9d21154c 10482
wolfSSL 0:d92f9d21154c 10483 if (ssl->peerRsaKey == NULL || ssl->peerRsaKeyPresent == 0) {
wolfSSL 0:d92f9d21154c 10484 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10485 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10486 #endif
wolfSSL 0:d92f9d21154c 10487 return NO_PEER_KEY;
wolfSSL 0:d92f9d21154c 10488 }
wolfSSL 0:d92f9d21154c 10489
wolfSSL 0:d92f9d21154c 10490 if (doUserRsa) {
wolfSSL 0:d92f9d21154c 10491 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 10492 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 10493 encSz = MAX_ENCRYPT_SZ;
wolfSSL 0:d92f9d21154c 10494 ret = ssl->ctx->RsaEncCb(ssl,
wolfSSL 0:d92f9d21154c 10495 ssl->arrays->preMasterSecret,
wolfSSL 0:d92f9d21154c 10496 SECRET_LEN,
wolfSSL 0:d92f9d21154c 10497 encSecret, &encSz,
wolfSSL 0:d92f9d21154c 10498 ssl->buffers.peerRsaKey.buffer,
wolfSSL 0:d92f9d21154c 10499 ssl->buffers.peerRsaKey.length,
wolfSSL 0:d92f9d21154c 10500 ssl->RsaEncCtx);
wolfSSL 0:d92f9d21154c 10501 #endif /* NO_RSA */
wolfSSL 0:d92f9d21154c 10502 #endif /*HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 10503 }
wolfSSL 0:d92f9d21154c 10504 else {
wolfSSL 0:d92f9d21154c 10505 ret = wc_RsaPublicEncrypt(ssl->arrays->preMasterSecret,
wolfSSL 0:d92f9d21154c 10506 SECRET_LEN, encSecret, MAX_ENCRYPT_SZ,
wolfSSL 0:d92f9d21154c 10507 ssl->peerRsaKey, ssl->rng);
wolfSSL 0:d92f9d21154c 10508 if (ret > 0) {
wolfSSL 0:d92f9d21154c 10509 encSz = ret;
wolfSSL 0:d92f9d21154c 10510 ret = 0; /* set success to 0 */
wolfSSL 0:d92f9d21154c 10511 }
wolfSSL 0:d92f9d21154c 10512 }
wolfSSL 0:d92f9d21154c 10513 break;
wolfSSL 0:d92f9d21154c 10514 #endif
wolfSSL 0:d92f9d21154c 10515 #ifndef NO_DH
wolfSSL 0:d92f9d21154c 10516 case diffie_hellman_kea:
wolfSSL 0:d92f9d21154c 10517 {
wolfSSL 0:d92f9d21154c 10518 buffer serverP = ssl->buffers.serverDH_P;
wolfSSL 0:d92f9d21154c 10519 buffer serverG = ssl->buffers.serverDH_G;
wolfSSL 0:d92f9d21154c 10520 buffer serverPub = ssl->buffers.serverDH_Pub;
wolfSSL 0:d92f9d21154c 10521 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10522 byte* priv = NULL;
wolfSSL 0:d92f9d21154c 10523 #else
wolfSSL 0:d92f9d21154c 10524 byte priv[ENCRYPT_LEN];
wolfSSL 0:d92f9d21154c 10525 #endif
wolfSSL 0:d92f9d21154c 10526 word32 privSz = 0;
wolfSSL 0:d92f9d21154c 10527 DhKey key;
wolfSSL 0:d92f9d21154c 10528
wolfSSL 0:d92f9d21154c 10529 if (serverP.buffer == 0 || serverG.buffer == 0 ||
wolfSSL 0:d92f9d21154c 10530 serverPub.buffer == 0) {
wolfSSL 0:d92f9d21154c 10531 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10532 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10533 #endif
wolfSSL 0:d92f9d21154c 10534 return NO_PEER_KEY;
wolfSSL 0:d92f9d21154c 10535 }
wolfSSL 0:d92f9d21154c 10536
wolfSSL 0:d92f9d21154c 10537 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10538 priv = (byte*)XMALLOC(ENCRYPT_LEN, NULL,
wolfSSL 0:d92f9d21154c 10539 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10540 if (priv == NULL) {
wolfSSL 0:d92f9d21154c 10541 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10542 return MEMORY_E;
wolfSSL 0:d92f9d21154c 10543 }
wolfSSL 0:d92f9d21154c 10544 #endif
wolfSSL 0:d92f9d21154c 10545
wolfSSL 0:d92f9d21154c 10546 wc_InitDhKey(&key);
wolfSSL 0:d92f9d21154c 10547 ret = wc_DhSetKey(&key, serverP.buffer, serverP.length,
wolfSSL 0:d92f9d21154c 10548 serverG.buffer, serverG.length);
wolfSSL 0:d92f9d21154c 10549 if (ret == 0)
wolfSSL 0:d92f9d21154c 10550 /* for DH, encSecret is Yc, agree is pre-master */
wolfSSL 0:d92f9d21154c 10551 ret = wc_DhGenerateKeyPair(&key, ssl->rng, priv, &privSz,
wolfSSL 0:d92f9d21154c 10552 encSecret, &encSz);
wolfSSL 0:d92f9d21154c 10553 if (ret == 0)
wolfSSL 0:d92f9d21154c 10554 ret = wc_DhAgree(&key, ssl->arrays->preMasterSecret,
wolfSSL 0:d92f9d21154c 10555 &ssl->arrays->preMasterSz, priv, privSz,
wolfSSL 0:d92f9d21154c 10556 serverPub.buffer, serverPub.length);
wolfSSL 0:d92f9d21154c 10557 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10558 XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10559 #endif
wolfSSL 0:d92f9d21154c 10560 wc_FreeDhKey(&key);
wolfSSL 0:d92f9d21154c 10561 }
wolfSSL 0:d92f9d21154c 10562 break;
wolfSSL 0:d92f9d21154c 10563 #endif /* NO_DH */
wolfSSL 0:d92f9d21154c 10564 #ifndef NO_PSK
wolfSSL 0:d92f9d21154c 10565 case psk_kea:
wolfSSL 0:d92f9d21154c 10566 {
wolfSSL 0:d92f9d21154c 10567 byte* pms = ssl->arrays->preMasterSecret;
wolfSSL 0:d92f9d21154c 10568
wolfSSL 0:d92f9d21154c 10569 ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
wolfSSL 0:d92f9d21154c 10570 ssl->arrays->server_hint, ssl->arrays->client_identity,
wolfSSL 0:d92f9d21154c 10571 MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
wolfSSL 0:d92f9d21154c 10572 if (ssl->arrays->psk_keySz == 0 ||
wolfSSL 0:d92f9d21154c 10573 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
wolfSSL 0:d92f9d21154c 10574 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10575 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10576 #endif
wolfSSL 0:d92f9d21154c 10577 return PSK_KEY_ERROR;
wolfSSL 0:d92f9d21154c 10578 }
wolfSSL 0:d92f9d21154c 10579 encSz = (word32)XSTRLEN(ssl->arrays->client_identity);
wolfSSL 0:d92f9d21154c 10580 if (encSz > MAX_PSK_ID_LEN) {
wolfSSL 0:d92f9d21154c 10581 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10582 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10583 #endif
wolfSSL 0:d92f9d21154c 10584 return CLIENT_ID_ERROR;
wolfSSL 0:d92f9d21154c 10585 }
wolfSSL 0:d92f9d21154c 10586 XMEMCPY(encSecret, ssl->arrays->client_identity, encSz);
wolfSSL 0:d92f9d21154c 10587
wolfSSL 0:d92f9d21154c 10588 /* make psk pre master secret */
wolfSSL 0:d92f9d21154c 10589 /* length of key + length 0s + length of key + key */
wolfSSL 0:d92f9d21154c 10590 c16toa((word16)ssl->arrays->psk_keySz, pms);
wolfSSL 0:d92f9d21154c 10591 pms += 2;
wolfSSL 0:d92f9d21154c 10592 XMEMSET(pms, 0, ssl->arrays->psk_keySz);
wolfSSL 0:d92f9d21154c 10593 pms += ssl->arrays->psk_keySz;
wolfSSL 0:d92f9d21154c 10594 c16toa((word16)ssl->arrays->psk_keySz, pms);
wolfSSL 0:d92f9d21154c 10595 pms += 2;
wolfSSL 0:d92f9d21154c 10596 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
wolfSSL 0:d92f9d21154c 10597 ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
wolfSSL 0:d92f9d21154c 10598 ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
wolfSSL 0:d92f9d21154c 10599 ssl->arrays->psk_keySz = 0; /* No further need */
wolfSSL 0:d92f9d21154c 10600 }
wolfSSL 0:d92f9d21154c 10601 break;
wolfSSL 0:d92f9d21154c 10602 #endif /* NO_PSK */
wolfSSL 0:d92f9d21154c 10603 #if !defined(NO_DH) && !defined(NO_PSK)
wolfSSL 0:d92f9d21154c 10604 case dhe_psk_kea:
wolfSSL 0:d92f9d21154c 10605 {
wolfSSL 0:d92f9d21154c 10606 byte* pms = ssl->arrays->preMasterSecret;
wolfSSL 0:d92f9d21154c 10607 byte* es = encSecret;
wolfSSL 0:d92f9d21154c 10608 buffer serverP = ssl->buffers.serverDH_P;
wolfSSL 0:d92f9d21154c 10609 buffer serverG = ssl->buffers.serverDH_G;
wolfSSL 0:d92f9d21154c 10610 buffer serverPub = ssl->buffers.serverDH_Pub;
wolfSSL 0:d92f9d21154c 10611 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10612 byte* priv = NULL;
wolfSSL 0:d92f9d21154c 10613 #else
wolfSSL 0:d92f9d21154c 10614 byte priv[ENCRYPT_LEN];
wolfSSL 0:d92f9d21154c 10615 #endif
wolfSSL 0:d92f9d21154c 10616 word32 privSz = 0;
wolfSSL 0:d92f9d21154c 10617 word32 pubSz = 0;
wolfSSL 0:d92f9d21154c 10618 word32 esSz = 0;
wolfSSL 0:d92f9d21154c 10619 DhKey key;
wolfSSL 0:d92f9d21154c 10620
wolfSSL 0:d92f9d21154c 10621 if (serverP.buffer == 0 || serverG.buffer == 0 ||
wolfSSL 0:d92f9d21154c 10622 serverPub.buffer == 0) {
wolfSSL 0:d92f9d21154c 10623 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10624 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10625 #endif
wolfSSL 0:d92f9d21154c 10626 return NO_PEER_KEY;
wolfSSL 0:d92f9d21154c 10627 }
wolfSSL 0:d92f9d21154c 10628
wolfSSL 0:d92f9d21154c 10629 ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
wolfSSL 0:d92f9d21154c 10630 ssl->arrays->server_hint, ssl->arrays->client_identity,
wolfSSL 0:d92f9d21154c 10631 MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
wolfSSL 0:d92f9d21154c 10632 if (ssl->arrays->psk_keySz == 0 ||
wolfSSL 0:d92f9d21154c 10633 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
wolfSSL 0:d92f9d21154c 10634 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10635 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10636 #endif
wolfSSL 0:d92f9d21154c 10637 return PSK_KEY_ERROR;
wolfSSL 0:d92f9d21154c 10638 }
wolfSSL 0:d92f9d21154c 10639 esSz = (word32)XSTRLEN(ssl->arrays->client_identity);
wolfSSL 0:d92f9d21154c 10640
wolfSSL 0:d92f9d21154c 10641 if (esSz > MAX_PSK_ID_LEN) {
wolfSSL 0:d92f9d21154c 10642 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10643 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10644 #endif
wolfSSL 0:d92f9d21154c 10645 return CLIENT_ID_ERROR;
wolfSSL 0:d92f9d21154c 10646 }
wolfSSL 0:d92f9d21154c 10647
wolfSSL 0:d92f9d21154c 10648 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10649 priv = (byte*)XMALLOC(ENCRYPT_LEN, NULL,
wolfSSL 0:d92f9d21154c 10650 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10651 if (priv == NULL) {
wolfSSL 0:d92f9d21154c 10652 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10653 return MEMORY_E;
wolfSSL 0:d92f9d21154c 10654 }
wolfSSL 0:d92f9d21154c 10655 #endif
wolfSSL 0:d92f9d21154c 10656 c16toa((word16)esSz, es);
wolfSSL 0:d92f9d21154c 10657 es += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 10658 XMEMCPY(es, ssl->arrays->client_identity, esSz);
wolfSSL 0:d92f9d21154c 10659 es += esSz;
wolfSSL 0:d92f9d21154c 10660 encSz = esSz + OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 10661
wolfSSL 0:d92f9d21154c 10662 wc_InitDhKey(&key);
wolfSSL 0:d92f9d21154c 10663 ret = wc_DhSetKey(&key, serverP.buffer, serverP.length,
wolfSSL 0:d92f9d21154c 10664 serverG.buffer, serverG.length);
wolfSSL 0:d92f9d21154c 10665 if (ret == 0)
wolfSSL 0:d92f9d21154c 10666 /* for DH, encSecret is Yc, agree is pre-master */
wolfSSL 0:d92f9d21154c 10667 ret = wc_DhGenerateKeyPair(&key, ssl->rng, priv, &privSz,
wolfSSL 0:d92f9d21154c 10668 es + OPAQUE16_LEN, &pubSz);
wolfSSL 0:d92f9d21154c 10669 if (ret == 0)
wolfSSL 0:d92f9d21154c 10670 ret = wc_DhAgree(&key, pms + OPAQUE16_LEN,
wolfSSL 0:d92f9d21154c 10671 &ssl->arrays->preMasterSz, priv, privSz,
wolfSSL 0:d92f9d21154c 10672 serverPub.buffer, serverPub.length);
wolfSSL 0:d92f9d21154c 10673 wc_FreeDhKey(&key);
wolfSSL 0:d92f9d21154c 10674 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10675 XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10676 #endif
wolfSSL 0:d92f9d21154c 10677 if (ret != 0) {
wolfSSL 0:d92f9d21154c 10678 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10679 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10680 #endif
wolfSSL 0:d92f9d21154c 10681 return ret;
wolfSSL 0:d92f9d21154c 10682 }
wolfSSL 0:d92f9d21154c 10683
wolfSSL 0:d92f9d21154c 10684 c16toa((word16)pubSz, es);
wolfSSL 0:d92f9d21154c 10685 encSz += pubSz + OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 10686 c16toa((word16)ssl->arrays->preMasterSz, pms);
wolfSSL 0:d92f9d21154c 10687 ssl->arrays->preMasterSz += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 10688 pms += ssl->arrays->preMasterSz;
wolfSSL 0:d92f9d21154c 10689
wolfSSL 0:d92f9d21154c 10690 /* make psk pre master secret */
wolfSSL 0:d92f9d21154c 10691 /* length of key + length 0s + length of key + key */
wolfSSL 0:d92f9d21154c 10692 c16toa((word16)ssl->arrays->psk_keySz, pms);
wolfSSL 0:d92f9d21154c 10693 pms += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 10694 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
wolfSSL 0:d92f9d21154c 10695 ssl->arrays->preMasterSz +=
wolfSSL 0:d92f9d21154c 10696 ssl->arrays->psk_keySz + OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 10697 ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
wolfSSL 0:d92f9d21154c 10698 ssl->arrays->psk_keySz = 0; /* No further need */
wolfSSL 0:d92f9d21154c 10699 }
wolfSSL 0:d92f9d21154c 10700 break;
wolfSSL 0:d92f9d21154c 10701 #endif /* !NO_DH && !NO_PSK */
wolfSSL 0:d92f9d21154c 10702 #ifdef HAVE_NTRU
wolfSSL 0:d92f9d21154c 10703 case ntru_kea:
wolfSSL 0:d92f9d21154c 10704 {
wolfSSL 0:d92f9d21154c 10705 word32 rc;
wolfSSL 0:d92f9d21154c 10706 word16 cipherLen = MAX_ENCRYPT_SZ;
wolfSSL 0:d92f9d21154c 10707 DRBG_HANDLE drbg;
wolfSSL 0:d92f9d21154c 10708 static uint8_t const wolfsslStr[] = {
wolfSSL 0:d92f9d21154c 10709 'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U'
wolfSSL 0:d92f9d21154c 10710 };
wolfSSL 0:d92f9d21154c 10711
wolfSSL 0:d92f9d21154c 10712 ret = wc_RNG_GenerateBlock(ssl->rng,
wolfSSL 0:d92f9d21154c 10713 ssl->arrays->preMasterSecret, SECRET_LEN);
wolfSSL 0:d92f9d21154c 10714 if (ret != 0) {
wolfSSL 0:d92f9d21154c 10715 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10716 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10717 #endif
wolfSSL 0:d92f9d21154c 10718 return ret;
wolfSSL 0:d92f9d21154c 10719 }
wolfSSL 0:d92f9d21154c 10720
wolfSSL 0:d92f9d21154c 10721 ssl->arrays->preMasterSz = SECRET_LEN;
wolfSSL 0:d92f9d21154c 10722
wolfSSL 0:d92f9d21154c 10723 if (ssl->peerNtruKeyPresent == 0) {
wolfSSL 0:d92f9d21154c 10724 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10725 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10726 #endif
wolfSSL 0:d92f9d21154c 10727 return NO_PEER_KEY;
wolfSSL 0:d92f9d21154c 10728 }
wolfSSL 0:d92f9d21154c 10729
wolfSSL 0:d92f9d21154c 10730 rc = ntru_crypto_drbg_instantiate(MAX_NTRU_BITS, wolfsslStr,
wolfSSL 0:d92f9d21154c 10731 sizeof(wolfsslStr), GetEntropy,
wolfSSL 0:d92f9d21154c 10732 &drbg);
wolfSSL 0:d92f9d21154c 10733 if (rc != DRBG_OK) {
wolfSSL 0:d92f9d21154c 10734 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10735 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10736 #endif
wolfSSL 0:d92f9d21154c 10737 return NTRU_DRBG_ERROR;
wolfSSL 0:d92f9d21154c 10738 }
wolfSSL 0:d92f9d21154c 10739
wolfSSL 0:d92f9d21154c 10740 rc = ntru_crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen,
wolfSSL 0:d92f9d21154c 10741 ssl->peerNtruKey,
wolfSSL 0:d92f9d21154c 10742 ssl->arrays->preMasterSz,
wolfSSL 0:d92f9d21154c 10743 ssl->arrays->preMasterSecret,
wolfSSL 0:d92f9d21154c 10744 &cipherLen, encSecret);
wolfSSL 0:d92f9d21154c 10745 ntru_crypto_drbg_uninstantiate(drbg);
wolfSSL 0:d92f9d21154c 10746 if (rc != NTRU_OK) {
wolfSSL 0:d92f9d21154c 10747 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10748 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10749 #endif
wolfSSL 0:d92f9d21154c 10750 return NTRU_ENCRYPT_ERROR;
wolfSSL 0:d92f9d21154c 10751 }
wolfSSL 0:d92f9d21154c 10752
wolfSSL 0:d92f9d21154c 10753 encSz = cipherLen;
wolfSSL 0:d92f9d21154c 10754 ret = 0;
wolfSSL 0:d92f9d21154c 10755 }
wolfSSL 0:d92f9d21154c 10756 break;
wolfSSL 0:d92f9d21154c 10757 #endif /* HAVE_NTRU */
wolfSSL 0:d92f9d21154c 10758 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 10759 case ecc_diffie_hellman_kea:
wolfSSL 0:d92f9d21154c 10760 {
wolfSSL 0:d92f9d21154c 10761 ecc_key myKey;
wolfSSL 0:d92f9d21154c 10762 ecc_key* peerKey = NULL;
wolfSSL 0:d92f9d21154c 10763 word32 size = MAX_ENCRYPT_SZ;
wolfSSL 0:d92f9d21154c 10764
wolfSSL 0:d92f9d21154c 10765 if (ssl->specs.static_ecdh) {
wolfSSL 0:d92f9d21154c 10766 /* TODO: EccDsa is really fixed Ecc change naming */
wolfSSL 0:d92f9d21154c 10767 if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent ||
wolfSSL 0:d92f9d21154c 10768 !ssl->peerEccDsaKey->dp) {
wolfSSL 0:d92f9d21154c 10769 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10770 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10771 #endif
wolfSSL 0:d92f9d21154c 10772 return NO_PEER_KEY;
wolfSSL 0:d92f9d21154c 10773 }
wolfSSL 0:d92f9d21154c 10774 peerKey = ssl->peerEccDsaKey;
wolfSSL 0:d92f9d21154c 10775 }
wolfSSL 0:d92f9d21154c 10776 else {
wolfSSL 0:d92f9d21154c 10777 if (!ssl->peerEccKey || !ssl->peerEccKeyPresent ||
wolfSSL 0:d92f9d21154c 10778 !ssl->peerEccKey->dp) {
wolfSSL 0:d92f9d21154c 10779 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10780 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10781 #endif
wolfSSL 0:d92f9d21154c 10782 return NO_PEER_KEY;
wolfSSL 0:d92f9d21154c 10783 }
wolfSSL 0:d92f9d21154c 10784 peerKey = ssl->peerEccKey;
wolfSSL 0:d92f9d21154c 10785 }
wolfSSL 0:d92f9d21154c 10786
wolfSSL 0:d92f9d21154c 10787 if (peerKey == NULL) {
wolfSSL 0:d92f9d21154c 10788 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10789 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10790 #endif
wolfSSL 0:d92f9d21154c 10791 return NO_PEER_KEY;
wolfSSL 0:d92f9d21154c 10792 }
wolfSSL 0:d92f9d21154c 10793
wolfSSL 0:d92f9d21154c 10794 wc_ecc_init(&myKey);
wolfSSL 0:d92f9d21154c 10795 ret = wc_ecc_make_key(ssl->rng, peerKey->dp->size, &myKey);
wolfSSL 0:d92f9d21154c 10796 if (ret != 0) {
wolfSSL 0:d92f9d21154c 10797 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10798 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10799 #endif
wolfSSL 0:d92f9d21154c 10800 return ECC_MAKEKEY_ERROR;
wolfSSL 0:d92f9d21154c 10801 }
wolfSSL 0:d92f9d21154c 10802
wolfSSL 0:d92f9d21154c 10803 /* precede export with 1 byte length */
wolfSSL 0:d92f9d21154c 10804 ret = wc_ecc_export_x963(&myKey, encSecret + 1, &size);
wolfSSL 0:d92f9d21154c 10805 encSecret[0] = (byte)size;
wolfSSL 0:d92f9d21154c 10806 encSz = size + 1;
wolfSSL 0:d92f9d21154c 10807
wolfSSL 0:d92f9d21154c 10808 if (ret != 0)
wolfSSL 0:d92f9d21154c 10809 ret = ECC_EXPORT_ERROR;
wolfSSL 0:d92f9d21154c 10810 else {
wolfSSL 0:d92f9d21154c 10811 size = sizeof(ssl->arrays->preMasterSecret);
wolfSSL 0:d92f9d21154c 10812 ret = wc_ecc_shared_secret(&myKey, peerKey,
wolfSSL 0:d92f9d21154c 10813 ssl->arrays->preMasterSecret, &size);
wolfSSL 0:d92f9d21154c 10814 if (ret != 0)
wolfSSL 0:d92f9d21154c 10815 ret = ECC_SHARED_ERROR;
wolfSSL 0:d92f9d21154c 10816 }
wolfSSL 0:d92f9d21154c 10817
wolfSSL 0:d92f9d21154c 10818 ssl->arrays->preMasterSz = size;
wolfSSL 0:d92f9d21154c 10819 wc_ecc_free(&myKey);
wolfSSL 0:d92f9d21154c 10820 }
wolfSSL 0:d92f9d21154c 10821 break;
wolfSSL 0:d92f9d21154c 10822 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 10823 default:
wolfSSL 0:d92f9d21154c 10824 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10825 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10826 #endif
wolfSSL 0:d92f9d21154c 10827 return ALGO_ID_E; /* unsupported kea */
wolfSSL 0:d92f9d21154c 10828 }
wolfSSL 0:d92f9d21154c 10829
wolfSSL 0:d92f9d21154c 10830 if (ret == 0) {
wolfSSL 0:d92f9d21154c 10831 byte *output;
wolfSSL 0:d92f9d21154c 10832 int sendSz;
wolfSSL 0:d92f9d21154c 10833 word32 tlsSz = 0;
wolfSSL 0:d92f9d21154c 10834
wolfSSL 0:d92f9d21154c 10835 if (ssl->options.tls || ssl->specs.kea == diffie_hellman_kea)
wolfSSL 0:d92f9d21154c 10836 tlsSz = 2;
wolfSSL 0:d92f9d21154c 10837
wolfSSL 0:d92f9d21154c 10838 if (ssl->specs.kea == ecc_diffie_hellman_kea ||
wolfSSL 0:d92f9d21154c 10839 ssl->specs.kea == dhe_psk_kea) /* always off */
wolfSSL 0:d92f9d21154c 10840 tlsSz = 0;
wolfSSL 0:d92f9d21154c 10841
wolfSSL 0:d92f9d21154c 10842 sendSz = encSz + tlsSz + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 10843 idx = HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 10844
wolfSSL 0:d92f9d21154c 10845 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 10846 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 10847 sendSz += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 10848 idx += DTLS_HANDSHAKE_EXTRA + DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 10849 }
wolfSSL 0:d92f9d21154c 10850 #endif
wolfSSL 0:d92f9d21154c 10851
wolfSSL 0:d92f9d21154c 10852 if (ssl->keys.encryptionOn)
wolfSSL 0:d92f9d21154c 10853 sendSz += MAX_MSG_EXTRA;
wolfSSL 0:d92f9d21154c 10854
wolfSSL 0:d92f9d21154c 10855 /* check for available size */
wolfSSL 0:d92f9d21154c 10856 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
wolfSSL 0:d92f9d21154c 10857 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10858 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10859 #endif
wolfSSL 0:d92f9d21154c 10860 return ret;
wolfSSL 0:d92f9d21154c 10861 }
wolfSSL 0:d92f9d21154c 10862
wolfSSL 0:d92f9d21154c 10863 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 10864 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 10865 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 10866
wolfSSL 0:d92f9d21154c 10867 AddHeaders(output, encSz + tlsSz, client_key_exchange, ssl);
wolfSSL 0:d92f9d21154c 10868
wolfSSL 0:d92f9d21154c 10869 if (tlsSz) {
wolfSSL 0:d92f9d21154c 10870 c16toa((word16)encSz, &output[idx]);
wolfSSL 0:d92f9d21154c 10871 idx += 2;
wolfSSL 0:d92f9d21154c 10872 }
wolfSSL 0:d92f9d21154c 10873 XMEMCPY(output + idx, encSecret, encSz);
wolfSSL 0:d92f9d21154c 10874 idx += encSz;
wolfSSL 0:d92f9d21154c 10875
wolfSSL 0:d92f9d21154c 10876 if (ssl->keys.encryptionOn) {
wolfSSL 0:d92f9d21154c 10877 byte* input;
wolfSSL 0:d92f9d21154c 10878 int inputSz = idx-RECORD_HEADER_SZ; /* buildmsg adds rechdr */
wolfSSL 0:d92f9d21154c 10879
wolfSSL 0:d92f9d21154c 10880 input = (byte*)XMALLOC(inputSz, ssl->heap,
wolfSSL 0:d92f9d21154c 10881 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10882 if (input == NULL) {
wolfSSL 0:d92f9d21154c 10883 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10884 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10885 #endif
wolfSSL 0:d92f9d21154c 10886 return MEMORY_E;
wolfSSL 0:d92f9d21154c 10887 }
wolfSSL 0:d92f9d21154c 10888
wolfSSL 0:d92f9d21154c 10889 XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
wolfSSL 0:d92f9d21154c 10890 sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
wolfSSL 0:d92f9d21154c 10891 handshake);
wolfSSL 0:d92f9d21154c 10892 XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10893 if (sendSz < 0) {
wolfSSL 0:d92f9d21154c 10894 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10895 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10896 #endif
wolfSSL 0:d92f9d21154c 10897 return sendSz;
wolfSSL 0:d92f9d21154c 10898 }
wolfSSL 0:d92f9d21154c 10899 } else {
wolfSSL 0:d92f9d21154c 10900 ret = HashOutput(ssl, output, sendSz, 0);
wolfSSL 0:d92f9d21154c 10901 if (ret != 0) {
wolfSSL 0:d92f9d21154c 10902 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10903 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10904 #endif
wolfSSL 0:d92f9d21154c 10905 return ret;
wolfSSL 0:d92f9d21154c 10906 }
wolfSSL 0:d92f9d21154c 10907 }
wolfSSL 0:d92f9d21154c 10908
wolfSSL 0:d92f9d21154c 10909 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 10910 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 10911 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) {
wolfSSL 0:d92f9d21154c 10912 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10913 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10914 #endif
wolfSSL 0:d92f9d21154c 10915 return ret;
wolfSSL 0:d92f9d21154c 10916 }
wolfSSL 0:d92f9d21154c 10917 }
wolfSSL 0:d92f9d21154c 10918 #endif
wolfSSL 0:d92f9d21154c 10919
wolfSSL 0:d92f9d21154c 10920 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 10921 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 10922 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 10923 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 10924 AddPacketInfo("ClientKeyExchange", &ssl->timeoutInfo,
wolfSSL 0:d92f9d21154c 10925 output, sendSz, ssl->heap);
wolfSSL 0:d92f9d21154c 10926 #endif
wolfSSL 0:d92f9d21154c 10927
wolfSSL 0:d92f9d21154c 10928 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 10929
wolfSSL 0:d92f9d21154c 10930 if (ssl->options.groupMessages)
wolfSSL 0:d92f9d21154c 10931 ret = 0;
wolfSSL 0:d92f9d21154c 10932 else
wolfSSL 0:d92f9d21154c 10933 ret = SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 10934 }
wolfSSL 0:d92f9d21154c 10935
wolfSSL 0:d92f9d21154c 10936 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 10937 XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 10938 #endif
wolfSSL 0:d92f9d21154c 10939
wolfSSL 0:d92f9d21154c 10940 if (ret == 0 || ret == WANT_WRITE) {
wolfSSL 0:d92f9d21154c 10941 int tmpRet = MakeMasterSecret(ssl);
wolfSSL 0:d92f9d21154c 10942 if (tmpRet != 0)
wolfSSL 0:d92f9d21154c 10943 ret = tmpRet; /* save WANT_WRITE unless more serious */
wolfSSL 0:d92f9d21154c 10944 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
wolfSSL 0:d92f9d21154c 10945 }
wolfSSL 0:d92f9d21154c 10946 /* No further need for PMS */
wolfSSL 0:d92f9d21154c 10947 ForceZero(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
wolfSSL 0:d92f9d21154c 10948 ssl->arrays->preMasterSz = 0;
wolfSSL 0:d92f9d21154c 10949
wolfSSL 0:d92f9d21154c 10950 return ret;
wolfSSL 0:d92f9d21154c 10951 }
wolfSSL 0:d92f9d21154c 10952
wolfSSL 0:d92f9d21154c 10953 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 10954 int SendCertificateVerify(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 10955 {
wolfSSL 0:d92f9d21154c 10956 byte *output;
wolfSSL 0:d92f9d21154c 10957 int sendSz = MAX_CERT_VERIFY_SZ, length, ret;
wolfSSL 0:d92f9d21154c 10958 word32 idx = 0;
wolfSSL 0:d92f9d21154c 10959 word32 sigOutSz = 0;
wolfSSL 0:d92f9d21154c 10960 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 10961 RsaKey key;
wolfSSL 0:d92f9d21154c 10962 int initRsaKey = 0;
wolfSSL 0:d92f9d21154c 10963 #endif
wolfSSL 0:d92f9d21154c 10964 int usingEcc = 0;
wolfSSL 0:d92f9d21154c 10965 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 10966 ecc_key eccKey;
wolfSSL 0:d92f9d21154c 10967 #endif
wolfSSL 0:d92f9d21154c 10968
wolfSSL 0:d92f9d21154c 10969 (void)idx;
wolfSSL 0:d92f9d21154c 10970
wolfSSL 0:d92f9d21154c 10971 if (ssl->options.sendVerify == SEND_BLANK_CERT)
wolfSSL 0:d92f9d21154c 10972 return 0; /* sent blank cert, can't verify */
wolfSSL 0:d92f9d21154c 10973
wolfSSL 0:d92f9d21154c 10974 if (ssl->keys.encryptionOn)
wolfSSL 0:d92f9d21154c 10975 sendSz += MAX_MSG_EXTRA;
wolfSSL 0:d92f9d21154c 10976
wolfSSL 0:d92f9d21154c 10977 /* check for available size */
wolfSSL 0:d92f9d21154c 10978 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 10979 return ret;
wolfSSL 0:d92f9d21154c 10980
wolfSSL 0:d92f9d21154c 10981 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 10982 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 10983 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 10984
wolfSSL 0:d92f9d21154c 10985 ret = BuildCertHashes(ssl, &ssl->hsHashes->certHashes);
wolfSSL 0:d92f9d21154c 10986 if (ret != 0)
wolfSSL 0:d92f9d21154c 10987 return ret;
wolfSSL 0:d92f9d21154c 10988
wolfSSL 0:d92f9d21154c 10989 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 10990 wc_ecc_init(&eccKey);
wolfSSL 0:d92f9d21154c 10991 #endif
wolfSSL 0:d92f9d21154c 10992 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 10993 ret = wc_InitRsaKey(&key, ssl->heap);
wolfSSL 0:d92f9d21154c 10994 if (ret == 0) initRsaKey = 1;
wolfSSL 0:d92f9d21154c 10995 if (ret == 0)
wolfSSL 0:d92f9d21154c 10996 ret = wc_RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
wolfSSL 0:d92f9d21154c 10997 ssl->buffers.key.length);
wolfSSL 0:d92f9d21154c 10998 if (ret == 0)
wolfSSL 0:d92f9d21154c 10999 sigOutSz = wc_RsaEncryptSize(&key);
wolfSSL 0:d92f9d21154c 11000 else
wolfSSL 0:d92f9d21154c 11001 #endif
wolfSSL 0:d92f9d21154c 11002 {
wolfSSL 0:d92f9d21154c 11003 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 11004 WOLFSSL_MSG("Trying ECC client cert, RSA didn't work");
wolfSSL 0:d92f9d21154c 11005
wolfSSL 0:d92f9d21154c 11006 idx = 0;
wolfSSL 0:d92f9d21154c 11007 ret = wc_EccPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &eccKey,
wolfSSL 0:d92f9d21154c 11008 ssl->buffers.key.length);
wolfSSL 0:d92f9d21154c 11009 if (ret == 0) {
wolfSSL 0:d92f9d21154c 11010 WOLFSSL_MSG("Using ECC client cert");
wolfSSL 0:d92f9d21154c 11011 usingEcc = 1;
wolfSSL 0:d92f9d21154c 11012 sigOutSz = MAX_ENCODED_SIG_SZ;
wolfSSL 0:d92f9d21154c 11013 }
wolfSSL 0:d92f9d21154c 11014 else {
wolfSSL 0:d92f9d21154c 11015 WOLFSSL_MSG("Bad client cert type");
wolfSSL 0:d92f9d21154c 11016 }
wolfSSL 0:d92f9d21154c 11017 #endif
wolfSSL 0:d92f9d21154c 11018 }
wolfSSL 0:d92f9d21154c 11019 if (ret == 0) {
wolfSSL 0:d92f9d21154c 11020 byte* verify = (byte*)&output[RECORD_HEADER_SZ +
wolfSSL 0:d92f9d21154c 11021 HANDSHAKE_HEADER_SZ];
wolfSSL 0:d92f9d21154c 11022 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 11023 byte* signBuffer = ssl->hsHashes->certHashes.md5;
wolfSSL 0:d92f9d21154c 11024 #else
wolfSSL 0:d92f9d21154c 11025 byte* signBuffer = NULL;
wolfSSL 0:d92f9d21154c 11026 #endif
wolfSSL 0:d92f9d21154c 11027 word32 signSz = FINISHED_SZ;
wolfSSL 0:d92f9d21154c 11028 word32 extraSz = 0; /* tls 1.2 hash/sig */
wolfSSL 0:d92f9d21154c 11029 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 11030 byte* encodedSig = NULL;
wolfSSL 0:d92f9d21154c 11031 #else
wolfSSL 0:d92f9d21154c 11032 byte encodedSig[MAX_ENCODED_SIG_SZ];
wolfSSL 0:d92f9d21154c 11033 #endif
wolfSSL 0:d92f9d21154c 11034
wolfSSL 0:d92f9d21154c 11035 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 11036 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
wolfSSL 0:d92f9d21154c 11037 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 11038 if (encodedSig == NULL) {
wolfSSL 0:d92f9d21154c 11039 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 11040 if (initRsaKey)
wolfSSL 0:d92f9d21154c 11041 wc_FreeRsaKey(&key);
wolfSSL 0:d92f9d21154c 11042 #endif
wolfSSL 0:d92f9d21154c 11043 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 11044 wc_ecc_free(&eccKey);
wolfSSL 0:d92f9d21154c 11045 #endif
wolfSSL 0:d92f9d21154c 11046 return MEMORY_E;
wolfSSL 0:d92f9d21154c 11047 }
wolfSSL 0:d92f9d21154c 11048 #endif
wolfSSL 0:d92f9d21154c 11049
wolfSSL 0:d92f9d21154c 11050 (void)encodedSig;
wolfSSL 0:d92f9d21154c 11051 (void)signSz;
wolfSSL 0:d92f9d21154c 11052 (void)signBuffer;
wolfSSL 0:d92f9d21154c 11053
wolfSSL 0:d92f9d21154c 11054 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 11055 if (ssl->options.dtls)
wolfSSL 0:d92f9d21154c 11056 verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 11057 #endif
wolfSSL 0:d92f9d21154c 11058 length = sigOutSz;
wolfSSL 0:d92f9d21154c 11059 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 11060 verify[0] = ssl->suites->hashAlgo;
wolfSSL 0:d92f9d21154c 11061 verify[1] = usingEcc ? ecc_dsa_sa_algo : rsa_sa_algo;
wolfSSL 0:d92f9d21154c 11062 extraSz = HASH_SIG_SIZE;
wolfSSL 0:d92f9d21154c 11063 }
wolfSSL 0:d92f9d21154c 11064
wolfSSL 0:d92f9d21154c 11065 if (usingEcc) {
wolfSSL 0:d92f9d21154c 11066 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 11067 word32 localSz = MAX_ENCODED_SIG_SZ;
wolfSSL 0:d92f9d21154c 11068 word32 digestSz;
wolfSSL 0:d92f9d21154c 11069 byte* digest;
wolfSSL 0:d92f9d21154c 11070 byte doUserEcc = 0;
wolfSSL 0:d92f9d21154c 11071 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 11072 /* old tls default */
wolfSSL 0:d92f9d21154c 11073 digestSz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 11074 digest = ssl->hsHashes->certHashes.sha;
wolfSSL 0:d92f9d21154c 11075 #else
wolfSSL 0:d92f9d21154c 11076 /* new tls default */
wolfSSL 0:d92f9d21154c 11077 digestSz = SHA256_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 11078 digest = ssl->hsHashes->certHashes.sha256;
wolfSSL 0:d92f9d21154c 11079 #endif
wolfSSL 0:d92f9d21154c 11080
wolfSSL 0:d92f9d21154c 11081 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 11082 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 11083 if (ssl->ctx->EccSignCb)
wolfSSL 0:d92f9d21154c 11084 doUserEcc = 1;
wolfSSL 0:d92f9d21154c 11085 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 11086 #endif /*HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 11087
wolfSSL 0:d92f9d21154c 11088 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 11089 if (ssl->suites->hashAlgo == sha_mac) {
wolfSSL 0:d92f9d21154c 11090 #ifndef NO_SHA
wolfSSL 0:d92f9d21154c 11091 digest = ssl->hsHashes->certHashes.sha;
wolfSSL 0:d92f9d21154c 11092 digestSz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 11093 #endif
wolfSSL 0:d92f9d21154c 11094 }
wolfSSL 0:d92f9d21154c 11095 else if (ssl->suites->hashAlgo == sha256_mac) {
wolfSSL 0:d92f9d21154c 11096 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 11097 digest = ssl->hsHashes->certHashes.sha256;
wolfSSL 0:d92f9d21154c 11098 digestSz = SHA256_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 11099 #endif
wolfSSL 0:d92f9d21154c 11100 }
wolfSSL 0:d92f9d21154c 11101 else if (ssl->suites->hashAlgo == sha384_mac) {
wolfSSL 0:d92f9d21154c 11102 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 11103 digest = ssl->hsHashes->certHashes.sha384;
wolfSSL 0:d92f9d21154c 11104 digestSz = SHA384_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 11105 #endif
wolfSSL 0:d92f9d21154c 11106 }
wolfSSL 0:d92f9d21154c 11107 else if (ssl->suites->hashAlgo == sha512_mac) {
wolfSSL 0:d92f9d21154c 11108 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 11109 digest = ssl->hsHashes->certHashes.sha512;
wolfSSL 0:d92f9d21154c 11110 digestSz = SHA512_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 11111 #endif
wolfSSL 0:d92f9d21154c 11112 }
wolfSSL 0:d92f9d21154c 11113 }
wolfSSL 0:d92f9d21154c 11114
wolfSSL 0:d92f9d21154c 11115 if (doUserEcc) {
wolfSSL 0:d92f9d21154c 11116 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 11117 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 11118 ret = ssl->ctx->EccSignCb(ssl, digest, digestSz,
wolfSSL 0:d92f9d21154c 11119 encodedSig, &localSz,
wolfSSL 0:d92f9d21154c 11120 ssl->buffers.key.buffer,
wolfSSL 0:d92f9d21154c 11121 ssl->buffers.key.length,
wolfSSL 0:d92f9d21154c 11122 ssl->EccSignCtx);
wolfSSL 0:d92f9d21154c 11123 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 11124 #endif /*HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 11125 }
wolfSSL 0:d92f9d21154c 11126 else {
wolfSSL 0:d92f9d21154c 11127 ret = wc_ecc_sign_hash(digest, digestSz, encodedSig,
wolfSSL 0:d92f9d21154c 11128 &localSz, ssl->rng, &eccKey);
wolfSSL 0:d92f9d21154c 11129 }
wolfSSL 0:d92f9d21154c 11130 if (ret == 0) {
wolfSSL 0:d92f9d21154c 11131 length = localSz;
wolfSSL 0:d92f9d21154c 11132 c16toa((word16)length, verify + extraSz); /* prepend hdr */
wolfSSL 0:d92f9d21154c 11133 XMEMCPY(verify + extraSz + VERIFY_HEADER,encodedSig,length);
wolfSSL 0:d92f9d21154c 11134 }
wolfSSL 0:d92f9d21154c 11135 #endif
wolfSSL 0:d92f9d21154c 11136 }
wolfSSL 0:d92f9d21154c 11137 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 11138 else {
wolfSSL 0:d92f9d21154c 11139 byte doUserRsa = 0;
wolfSSL 0:d92f9d21154c 11140
wolfSSL 0:d92f9d21154c 11141 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 11142 if (ssl->ctx->RsaSignCb)
wolfSSL 0:d92f9d21154c 11143 doUserRsa = 1;
wolfSSL 0:d92f9d21154c 11144 #endif /*HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 11145
wolfSSL 0:d92f9d21154c 11146 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 11147 /*
wolfSSL 0:d92f9d21154c 11148 * MSVC Compiler complains because it can not
wolfSSL 0:d92f9d21154c 11149 * guarantee any of the conditionals will succeed in
wolfSSL 0:d92f9d21154c 11150 * assigning a value before wc_EncodeSignature executes.
wolfSSL 0:d92f9d21154c 11151 */
wolfSSL 0:d92f9d21154c 11152 byte* digest = NULL;
wolfSSL 0:d92f9d21154c 11153 int digestSz = 0;
wolfSSL 0:d92f9d21154c 11154 int typeH = 0;
wolfSSL 0:d92f9d21154c 11155 int didSet = 0;
wolfSSL 0:d92f9d21154c 11156
wolfSSL 0:d92f9d21154c 11157 if (ssl->suites->hashAlgo == sha_mac) {
wolfSSL 0:d92f9d21154c 11158 #ifndef NO_SHA
wolfSSL 0:d92f9d21154c 11159 digest = ssl->hsHashes->certHashes.sha;
wolfSSL 0:d92f9d21154c 11160 typeH = SHAh;
wolfSSL 0:d92f9d21154c 11161 digestSz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 11162 didSet = 1;
wolfSSL 0:d92f9d21154c 11163 #endif
wolfSSL 0:d92f9d21154c 11164 }
wolfSSL 0:d92f9d21154c 11165 else if (ssl->suites->hashAlgo == sha256_mac) {
wolfSSL 0:d92f9d21154c 11166 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 11167 digest = ssl->hsHashes->certHashes.sha256;
wolfSSL 0:d92f9d21154c 11168 typeH = SHA256h;
wolfSSL 0:d92f9d21154c 11169 digestSz = SHA256_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 11170 didSet = 1;
wolfSSL 0:d92f9d21154c 11171 #endif
wolfSSL 0:d92f9d21154c 11172 }
wolfSSL 0:d92f9d21154c 11173 else if (ssl->suites->hashAlgo == sha384_mac) {
wolfSSL 0:d92f9d21154c 11174 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 11175 digest = ssl->hsHashes->certHashes.sha384;
wolfSSL 0:d92f9d21154c 11176 typeH = SHA384h;
wolfSSL 0:d92f9d21154c 11177 digestSz = SHA384_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 11178 didSet = 1;
wolfSSL 0:d92f9d21154c 11179 #endif
wolfSSL 0:d92f9d21154c 11180 }
wolfSSL 0:d92f9d21154c 11181 else if (ssl->suites->hashAlgo == sha512_mac) {
wolfSSL 0:d92f9d21154c 11182 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 11183 digest = ssl->hsHashes->certHashes.sha512;
wolfSSL 0:d92f9d21154c 11184 typeH = SHA512h;
wolfSSL 0:d92f9d21154c 11185 digestSz = SHA512_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 11186 didSet = 1;
wolfSSL 0:d92f9d21154c 11187 #endif
wolfSSL 0:d92f9d21154c 11188 }
wolfSSL 0:d92f9d21154c 11189
wolfSSL 0:d92f9d21154c 11190 if (didSet == 0) {
wolfSSL 0:d92f9d21154c 11191 /* defaults */
wolfSSL 0:d92f9d21154c 11192 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 11193 digest = ssl->hsHashes->certHashes.sha;
wolfSSL 0:d92f9d21154c 11194 digestSz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 11195 typeH = SHAh;
wolfSSL 0:d92f9d21154c 11196 #else
wolfSSL 0:d92f9d21154c 11197 digest = ssl->hsHashes->certHashes.sha256;
wolfSSL 0:d92f9d21154c 11198 digestSz = SHA256_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 11199 typeH = SHA256h;
wolfSSL 0:d92f9d21154c 11200 #endif
wolfSSL 0:d92f9d21154c 11201 }
wolfSSL 0:d92f9d21154c 11202
wolfSSL 0:d92f9d21154c 11203 signSz = wc_EncodeSignature(encodedSig, digest,digestSz,typeH);
wolfSSL 0:d92f9d21154c 11204 signBuffer = encodedSig;
wolfSSL 0:d92f9d21154c 11205 }
wolfSSL 0:d92f9d21154c 11206
wolfSSL 0:d92f9d21154c 11207 c16toa((word16)length, verify + extraSz); /* prepend hdr */
wolfSSL 0:d92f9d21154c 11208 if (doUserRsa) {
wolfSSL 0:d92f9d21154c 11209 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 11210 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 11211 word32 ioLen = ENCRYPT_LEN;
wolfSSL 0:d92f9d21154c 11212 ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
wolfSSL 0:d92f9d21154c 11213 verify + extraSz + VERIFY_HEADER,
wolfSSL 0:d92f9d21154c 11214 &ioLen,
wolfSSL 0:d92f9d21154c 11215 ssl->buffers.key.buffer,
wolfSSL 0:d92f9d21154c 11216 ssl->buffers.key.length,
wolfSSL 0:d92f9d21154c 11217 ssl->RsaSignCtx);
wolfSSL 0:d92f9d21154c 11218 #endif /* NO_RSA */
wolfSSL 0:d92f9d21154c 11219 #endif /*HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 11220 }
wolfSSL 0:d92f9d21154c 11221 else {
wolfSSL 0:d92f9d21154c 11222 ret = wc_RsaSSL_Sign(signBuffer, signSz, verify + extraSz +
wolfSSL 0:d92f9d21154c 11223 VERIFY_HEADER, ENCRYPT_LEN, &key, ssl->rng);
wolfSSL 0:d92f9d21154c 11224 }
wolfSSL 0:d92f9d21154c 11225
wolfSSL 0:d92f9d21154c 11226 if (ret > 0)
wolfSSL 0:d92f9d21154c 11227 ret = 0; /* RSA reset */
wolfSSL 0:d92f9d21154c 11228 }
wolfSSL 0:d92f9d21154c 11229 #endif
wolfSSL 0:d92f9d21154c 11230 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 11231 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 11232 #endif
wolfSSL 0:d92f9d21154c 11233
wolfSSL 0:d92f9d21154c 11234 if (ret == 0) {
wolfSSL 0:d92f9d21154c 11235 AddHeaders(output, length + extraSz + VERIFY_HEADER,
wolfSSL 0:d92f9d21154c 11236 certificate_verify, ssl);
wolfSSL 0:d92f9d21154c 11237
wolfSSL 0:d92f9d21154c 11238 sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length +
wolfSSL 0:d92f9d21154c 11239 extraSz + VERIFY_HEADER;
wolfSSL 0:d92f9d21154c 11240
wolfSSL 0:d92f9d21154c 11241 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 11242 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 11243 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 11244 }
wolfSSL 0:d92f9d21154c 11245 #endif
wolfSSL 0:d92f9d21154c 11246
wolfSSL 0:d92f9d21154c 11247 if (ssl->keys.encryptionOn) {
wolfSSL 0:d92f9d21154c 11248 byte* input;
wolfSSL 0:d92f9d21154c 11249 int inputSz = sendSz - RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 11250 /* build msg adds rec hdr */
wolfSSL 0:d92f9d21154c 11251 input = (byte*)XMALLOC(inputSz, ssl->heap,
wolfSSL 0:d92f9d21154c 11252 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 11253 if (input == NULL)
wolfSSL 0:d92f9d21154c 11254 ret = MEMORY_E;
wolfSSL 0:d92f9d21154c 11255 else {
wolfSSL 0:d92f9d21154c 11256 XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
wolfSSL 0:d92f9d21154c 11257 sendSz = BuildMessage(ssl, output,
wolfSSL 0:d92f9d21154c 11258 MAX_CERT_VERIFY_SZ +MAX_MSG_EXTRA,
wolfSSL 0:d92f9d21154c 11259 input, inputSz, handshake);
wolfSSL 0:d92f9d21154c 11260 XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 11261
wolfSSL 0:d92f9d21154c 11262 if (sendSz < 0)
wolfSSL 0:d92f9d21154c 11263 ret = sendSz;
wolfSSL 0:d92f9d21154c 11264 }
wolfSSL 0:d92f9d21154c 11265 } else {
wolfSSL 0:d92f9d21154c 11266 ret = HashOutput(ssl, output, sendSz, 0);
wolfSSL 0:d92f9d21154c 11267 }
wolfSSL 0:d92f9d21154c 11268
wolfSSL 0:d92f9d21154c 11269 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 11270 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 11271 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 11272 return ret;
wolfSSL 0:d92f9d21154c 11273 }
wolfSSL 0:d92f9d21154c 11274 #endif
wolfSSL 0:d92f9d21154c 11275 }
wolfSSL 0:d92f9d21154c 11276 }
wolfSSL 0:d92f9d21154c 11277 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 11278 if (initRsaKey)
wolfSSL 0:d92f9d21154c 11279 wc_FreeRsaKey(&key);
wolfSSL 0:d92f9d21154c 11280 #endif
wolfSSL 0:d92f9d21154c 11281 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 11282 wc_ecc_free(&eccKey);
wolfSSL 0:d92f9d21154c 11283 #endif
wolfSSL 0:d92f9d21154c 11284
wolfSSL 0:d92f9d21154c 11285 if (ret == 0) {
wolfSSL 0:d92f9d21154c 11286 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 11287 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 11288 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 11289 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 11290 AddPacketInfo("CertificateVerify", &ssl->timeoutInfo,
wolfSSL 0:d92f9d21154c 11291 output, sendSz, ssl->heap);
wolfSSL 0:d92f9d21154c 11292 #endif
wolfSSL 0:d92f9d21154c 11293 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 11294 if (ssl->options.groupMessages)
wolfSSL 0:d92f9d21154c 11295 return 0;
wolfSSL 0:d92f9d21154c 11296 else
wolfSSL 0:d92f9d21154c 11297 return SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 11298 }
wolfSSL 0:d92f9d21154c 11299 else
wolfSSL 0:d92f9d21154c 11300 return ret;
wolfSSL 0:d92f9d21154c 11301 }
wolfSSL 0:d92f9d21154c 11302 #endif /* NO_CERTS */
wolfSSL 0:d92f9d21154c 11303
wolfSSL 0:d92f9d21154c 11304 #ifdef HAVE_SESSION_TICKET
wolfSSL 0:d92f9d21154c 11305 int DoSessionTicket(WOLFSSL* ssl,
wolfSSL 0:d92f9d21154c 11306 const byte* input, word32* inOutIdx, word32 size)
wolfSSL 0:d92f9d21154c 11307 {
wolfSSL 0:d92f9d21154c 11308 word32 begin = *inOutIdx;
wolfSSL 0:d92f9d21154c 11309 word32 lifetime;
wolfSSL 0:d92f9d21154c 11310 word16 length;
wolfSSL 0:d92f9d21154c 11311
wolfSSL 0:d92f9d21154c 11312 if (ssl->expect_session_ticket == 0) {
wolfSSL 0:d92f9d21154c 11313 WOLFSSL_MSG("Unexpected session ticket");
wolfSSL 0:d92f9d21154c 11314 return SESSION_TICKET_EXPECT_E;
wolfSSL 0:d92f9d21154c 11315 }
wolfSSL 0:d92f9d21154c 11316
wolfSSL 0:d92f9d21154c 11317 if ((*inOutIdx - begin) + OPAQUE32_LEN > size)
wolfSSL 0:d92f9d21154c 11318 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 11319
wolfSSL 0:d92f9d21154c 11320 ato32(input + *inOutIdx, &lifetime);
wolfSSL 0:d92f9d21154c 11321 *inOutIdx += OPAQUE32_LEN;
wolfSSL 0:d92f9d21154c 11322
wolfSSL 0:d92f9d21154c 11323 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 11324 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 11325
wolfSSL 0:d92f9d21154c 11326 ato16(input + *inOutIdx, &length);
wolfSSL 0:d92f9d21154c 11327 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 11328
wolfSSL 0:d92f9d21154c 11329 if (length > sizeof(ssl->session.ticket))
wolfSSL 0:d92f9d21154c 11330 return SESSION_TICKET_LEN_E;
wolfSSL 0:d92f9d21154c 11331
wolfSSL 0:d92f9d21154c 11332 if ((*inOutIdx - begin) + length > size)
wolfSSL 0:d92f9d21154c 11333 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 11334
wolfSSL 0:d92f9d21154c 11335 /* If the received ticket including its length is greater than
wolfSSL 0:d92f9d21154c 11336 * a length value, the save it. Otherwise, don't save it. */
wolfSSL 0:d92f9d21154c 11337 if (length > 0) {
wolfSSL 0:d92f9d21154c 11338 XMEMCPY(ssl->session.ticket, input + *inOutIdx, length);
wolfSSL 0:d92f9d21154c 11339 *inOutIdx += length;
wolfSSL 0:d92f9d21154c 11340 ssl->session.ticketLen = length;
wolfSSL 0:d92f9d21154c 11341 ssl->timeout = lifetime;
wolfSSL 0:d92f9d21154c 11342 if (ssl->session_ticket_cb != NULL) {
wolfSSL 0:d92f9d21154c 11343 ssl->session_ticket_cb(ssl,
wolfSSL 0:d92f9d21154c 11344 ssl->session.ticket, ssl->session.ticketLen,
wolfSSL 0:d92f9d21154c 11345 ssl->session_ticket_ctx);
wolfSSL 0:d92f9d21154c 11346 }
wolfSSL 0:d92f9d21154c 11347 /* Create a fake sessionID based on the ticket, this will
wolfSSL 0:d92f9d21154c 11348 * supercede the existing session cache info. */
wolfSSL 0:d92f9d21154c 11349 ssl->options.haveSessionId = 1;
wolfSSL 0:d92f9d21154c 11350 XMEMCPY(ssl->arrays->sessionID,
wolfSSL 0:d92f9d21154c 11351 ssl->session.ticket + length - ID_LEN, ID_LEN);
wolfSSL 0:d92f9d21154c 11352 #ifndef NO_SESSION_CACHE
wolfSSL 0:d92f9d21154c 11353 AddSession(ssl);
wolfSSL 0:d92f9d21154c 11354 #endif
wolfSSL 0:d92f9d21154c 11355
wolfSSL 0:d92f9d21154c 11356 }
wolfSSL 0:d92f9d21154c 11357 else {
wolfSSL 0:d92f9d21154c 11358 ssl->session.ticketLen = 0;
wolfSSL 0:d92f9d21154c 11359 }
wolfSSL 0:d92f9d21154c 11360
wolfSSL 0:d92f9d21154c 11361 if (ssl->keys.encryptionOn) {
wolfSSL 0:d92f9d21154c 11362 *inOutIdx += ssl->keys.padSz;
wolfSSL 0:d92f9d21154c 11363 }
wolfSSL 0:d92f9d21154c 11364
wolfSSL 0:d92f9d21154c 11365 ssl->expect_session_ticket = 0;
wolfSSL 0:d92f9d21154c 11366
wolfSSL 0:d92f9d21154c 11367 return 0;
wolfSSL 0:d92f9d21154c 11368 }
wolfSSL 0:d92f9d21154c 11369 #endif /* HAVE_SESSION_TICKET */
wolfSSL 0:d92f9d21154c 11370
wolfSSL 0:d92f9d21154c 11371 #endif /* NO_WOLFSSL_CLIENT */
wolfSSL 0:d92f9d21154c 11372
wolfSSL 0:d92f9d21154c 11373
wolfSSL 0:d92f9d21154c 11374 #ifndef NO_WOLFSSL_SERVER
wolfSSL 0:d92f9d21154c 11375
wolfSSL 0:d92f9d21154c 11376 int SendServerHello(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 11377 {
wolfSSL 0:d92f9d21154c 11378 byte *output;
wolfSSL 0:d92f9d21154c 11379 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 11380 int sendSz;
wolfSSL 0:d92f9d21154c 11381 int ret;
wolfSSL 0:d92f9d21154c 11382 byte sessIdSz = ID_LEN;
wolfSSL 0:d92f9d21154c 11383
wolfSSL 0:d92f9d21154c 11384 length = VERSION_SZ + RAN_LEN
wolfSSL 0:d92f9d21154c 11385 + ID_LEN + ENUM_LEN
wolfSSL 0:d92f9d21154c 11386 + SUITE_LEN
wolfSSL 0:d92f9d21154c 11387 + ENUM_LEN;
wolfSSL 0:d92f9d21154c 11388
wolfSSL 0:d92f9d21154c 11389 #ifdef HAVE_TLS_EXTENSIONS
wolfSSL 0:d92f9d21154c 11390 length += TLSX_GetResponseSize(ssl);
wolfSSL 0:d92f9d21154c 11391
wolfSSL 0:d92f9d21154c 11392 #ifdef HAVE_SESSION_TICKET
wolfSSL 0:d92f9d21154c 11393 if (ssl->options.useTicket && ssl->arrays->sessionIDSz == 0) {
wolfSSL 0:d92f9d21154c 11394 /* no session id */
wolfSSL 0:d92f9d21154c 11395 length -= ID_LEN;
wolfSSL 0:d92f9d21154c 11396 sessIdSz = 0;
wolfSSL 0:d92f9d21154c 11397 }
wolfSSL 0:d92f9d21154c 11398 #endif /* HAVE_SESSION_TICKET */
wolfSSL 0:d92f9d21154c 11399 #endif
wolfSSL 0:d92f9d21154c 11400
wolfSSL 0:d92f9d21154c 11401 /* check for avalaible size */
wolfSSL 0:d92f9d21154c 11402 if ((ret = CheckAvailableSize(ssl, MAX_HELLO_SZ)) != 0)
wolfSSL 0:d92f9d21154c 11403 return ret;
wolfSSL 0:d92f9d21154c 11404
wolfSSL 0:d92f9d21154c 11405 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 11406 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 11407 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 11408
wolfSSL 0:d92f9d21154c 11409 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 11410 AddHeaders(output, length, server_hello, ssl);
wolfSSL 0:d92f9d21154c 11411
wolfSSL 0:d92f9d21154c 11412 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 11413 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 11414 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 11415 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 11416 }
wolfSSL 0:d92f9d21154c 11417 #endif
wolfSSL 0:d92f9d21154c 11418 /* now write to output */
wolfSSL 0:d92f9d21154c 11419 /* first version */
wolfSSL 0:d92f9d21154c 11420 output[idx++] = ssl->version.major;
wolfSSL 0:d92f9d21154c 11421 output[idx++] = ssl->version.minor;
wolfSSL 0:d92f9d21154c 11422
wolfSSL 0:d92f9d21154c 11423 /* then random */
wolfSSL 0:d92f9d21154c 11424 if (!ssl->options.resuming) {
wolfSSL 0:d92f9d21154c 11425 ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
wolfSSL 0:d92f9d21154c 11426 RAN_LEN);
wolfSSL 0:d92f9d21154c 11427 if (ret != 0)
wolfSSL 0:d92f9d21154c 11428 return ret;
wolfSSL 0:d92f9d21154c 11429 }
wolfSSL 0:d92f9d21154c 11430
wolfSSL 0:d92f9d21154c 11431 XMEMCPY(output + idx, ssl->arrays->serverRandom, RAN_LEN);
wolfSSL 0:d92f9d21154c 11432 idx += RAN_LEN;
wolfSSL 0:d92f9d21154c 11433
wolfSSL 0:d92f9d21154c 11434 #ifdef SHOW_SECRETS
wolfSSL 0:d92f9d21154c 11435 {
wolfSSL 0:d92f9d21154c 11436 int j;
wolfSSL 0:d92f9d21154c 11437 printf("server random: ");
wolfSSL 0:d92f9d21154c 11438 for (j = 0; j < RAN_LEN; j++)
wolfSSL 0:d92f9d21154c 11439 printf("%02x", ssl->arrays->serverRandom[j]);
wolfSSL 0:d92f9d21154c 11440 printf("\n");
wolfSSL 0:d92f9d21154c 11441 }
wolfSSL 0:d92f9d21154c 11442 #endif
wolfSSL 0:d92f9d21154c 11443 /* then session id */
wolfSSL 0:d92f9d21154c 11444 output[idx++] = sessIdSz;
wolfSSL 0:d92f9d21154c 11445 if (sessIdSz) {
wolfSSL 0:d92f9d21154c 11446
wolfSSL 0:d92f9d21154c 11447 if (!ssl->options.resuming) {
wolfSSL 0:d92f9d21154c 11448 ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->sessionID,
wolfSSL 0:d92f9d21154c 11449 sessIdSz);
wolfSSL 0:d92f9d21154c 11450 if (ret != 0) return ret;
wolfSSL 0:d92f9d21154c 11451 }
wolfSSL 0:d92f9d21154c 11452
wolfSSL 0:d92f9d21154c 11453 XMEMCPY(output + idx, ssl->arrays->sessionID, sessIdSz);
wolfSSL 0:d92f9d21154c 11454 idx += sessIdSz;
wolfSSL 0:d92f9d21154c 11455 }
wolfSSL 0:d92f9d21154c 11456
wolfSSL 0:d92f9d21154c 11457 /* then cipher suite */
wolfSSL 0:d92f9d21154c 11458 output[idx++] = ssl->options.cipherSuite0;
wolfSSL 0:d92f9d21154c 11459 output[idx++] = ssl->options.cipherSuite;
wolfSSL 0:d92f9d21154c 11460
wolfSSL 0:d92f9d21154c 11461 /* then compression */
wolfSSL 0:d92f9d21154c 11462 if (ssl->options.usingCompression)
wolfSSL 0:d92f9d21154c 11463 output[idx++] = ZLIB_COMPRESSION;
wolfSSL 0:d92f9d21154c 11464 else
wolfSSL 0:d92f9d21154c 11465 output[idx++] = NO_COMPRESSION;
wolfSSL 0:d92f9d21154c 11466
wolfSSL 0:d92f9d21154c 11467 /* last, extensions */
wolfSSL 0:d92f9d21154c 11468 #ifdef HAVE_TLS_EXTENSIONS
wolfSSL 0:d92f9d21154c 11469 TLSX_WriteResponse(ssl, output + idx);
wolfSSL 0:d92f9d21154c 11470 #endif
wolfSSL 0:d92f9d21154c 11471
wolfSSL 0:d92f9d21154c 11472 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 11473 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 11474 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 11475 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 11476 return ret;
wolfSSL 0:d92f9d21154c 11477 }
wolfSSL 0:d92f9d21154c 11478 #endif
wolfSSL 0:d92f9d21154c 11479
wolfSSL 0:d92f9d21154c 11480 ret = HashOutput(ssl, output, sendSz, 0);
wolfSSL 0:d92f9d21154c 11481 if (ret != 0)
wolfSSL 0:d92f9d21154c 11482 return ret;
wolfSSL 0:d92f9d21154c 11483
wolfSSL 0:d92f9d21154c 11484 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 11485 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 11486 AddPacketName("ServerHello", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 11487 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 11488 AddPacketInfo("ServerHello", &ssl->timeoutInfo, output, sendSz,
wolfSSL 0:d92f9d21154c 11489 ssl->heap);
wolfSSL 0:d92f9d21154c 11490 #endif
wolfSSL 0:d92f9d21154c 11491
wolfSSL 0:d92f9d21154c 11492 ssl->options.serverState = SERVER_HELLO_COMPLETE;
wolfSSL 0:d92f9d21154c 11493
wolfSSL 0:d92f9d21154c 11494 if (ssl->options.groupMessages)
wolfSSL 0:d92f9d21154c 11495 return 0;
wolfSSL 0:d92f9d21154c 11496 else
wolfSSL 0:d92f9d21154c 11497 return SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 11498 }
wolfSSL 0:d92f9d21154c 11499
wolfSSL 0:d92f9d21154c 11500
wolfSSL 0:d92f9d21154c 11501 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 11502
wolfSSL 0:d92f9d21154c 11503 static byte SetCurveId(int size)
wolfSSL 0:d92f9d21154c 11504 {
wolfSSL 0:d92f9d21154c 11505 switch(size) {
wolfSSL 0:d92f9d21154c 11506 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC160)
wolfSSL 0:d92f9d21154c 11507 case 20:
wolfSSL 0:d92f9d21154c 11508 return WOLFSSL_ECC_SECP160R1;
wolfSSL 0:d92f9d21154c 11509 #endif
wolfSSL 0:d92f9d21154c 11510 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC192)
wolfSSL 0:d92f9d21154c 11511 case 24:
wolfSSL 0:d92f9d21154c 11512 return WOLFSSL_ECC_SECP192R1;
wolfSSL 0:d92f9d21154c 11513 #endif
wolfSSL 0:d92f9d21154c 11514 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC224)
wolfSSL 0:d92f9d21154c 11515 case 28:
wolfSSL 0:d92f9d21154c 11516 return WOLFSSL_ECC_SECP224R1;
wolfSSL 0:d92f9d21154c 11517 #endif
wolfSSL 0:d92f9d21154c 11518 #if defined(HAVE_ALL_CURVES) || !defined(NO_ECC256)
wolfSSL 0:d92f9d21154c 11519 case 32:
wolfSSL 0:d92f9d21154c 11520 return WOLFSSL_ECC_SECP256R1;
wolfSSL 0:d92f9d21154c 11521 #endif
wolfSSL 0:d92f9d21154c 11522 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC384)
wolfSSL 0:d92f9d21154c 11523 case 48:
wolfSSL 0:d92f9d21154c 11524 return WOLFSSL_ECC_SECP384R1;
wolfSSL 0:d92f9d21154c 11525 #endif
wolfSSL 0:d92f9d21154c 11526 #if defined(HAVE_ALL_CURVES) || defined(HAVE_ECC521)
wolfSSL 0:d92f9d21154c 11527 case 66:
wolfSSL 0:d92f9d21154c 11528 return WOLFSSL_ECC_SECP521R1;
wolfSSL 0:d92f9d21154c 11529 #endif
wolfSSL 0:d92f9d21154c 11530 default:
wolfSSL 0:d92f9d21154c 11531 return 0;
wolfSSL 0:d92f9d21154c 11532 }
wolfSSL 0:d92f9d21154c 11533 }
wolfSSL 0:d92f9d21154c 11534
wolfSSL 0:d92f9d21154c 11535 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 11536
wolfSSL 0:d92f9d21154c 11537
wolfSSL 0:d92f9d21154c 11538 int SendServerKeyExchange(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 11539 {
wolfSSL 0:d92f9d21154c 11540 int ret = 0;
wolfSSL 0:d92f9d21154c 11541 (void)ssl;
wolfSSL 0:d92f9d21154c 11542 #define ERROR_OUT(err, eLabel) do { ret = err; goto eLabel; } while(0)
wolfSSL 0:d92f9d21154c 11543
wolfSSL 0:d92f9d21154c 11544 #ifndef NO_PSK
wolfSSL 0:d92f9d21154c 11545 if (ssl->specs.kea == psk_kea)
wolfSSL 0:d92f9d21154c 11546 {
wolfSSL 0:d92f9d21154c 11547 byte *output;
wolfSSL 0:d92f9d21154c 11548 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 11549 int sendSz;
wolfSSL 0:d92f9d21154c 11550 if (ssl->arrays->server_hint[0] == 0) return 0; /* don't send */
wolfSSL 0:d92f9d21154c 11551
wolfSSL 0:d92f9d21154c 11552 /* include size part */
wolfSSL 0:d92f9d21154c 11553 length = (word32)XSTRLEN(ssl->arrays->server_hint);
wolfSSL 0:d92f9d21154c 11554 if (length > MAX_PSK_ID_LEN)
wolfSSL 0:d92f9d21154c 11555 return SERVER_HINT_ERROR;
wolfSSL 0:d92f9d21154c 11556
wolfSSL 0:d92f9d21154c 11557 length += HINT_LEN_SZ;
wolfSSL 0:d92f9d21154c 11558 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 11559
wolfSSL 0:d92f9d21154c 11560 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 11561 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 11562 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 11563 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 11564 }
wolfSSL 0:d92f9d21154c 11565 #endif
wolfSSL 0:d92f9d21154c 11566 /* check for available size */
wolfSSL 0:d92f9d21154c 11567 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 11568 return ret;
wolfSSL 0:d92f9d21154c 11569
wolfSSL 0:d92f9d21154c 11570 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 11571 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 11572 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 11573
wolfSSL 0:d92f9d21154c 11574 AddHeaders(output, length, server_key_exchange, ssl);
wolfSSL 0:d92f9d21154c 11575
wolfSSL 0:d92f9d21154c 11576 /* key data */
wolfSSL 0:d92f9d21154c 11577 c16toa((word16)(length - HINT_LEN_SZ), output + idx);
wolfSSL 0:d92f9d21154c 11578 idx += HINT_LEN_SZ;
wolfSSL 0:d92f9d21154c 11579 XMEMCPY(output + idx, ssl->arrays->server_hint,length -HINT_LEN_SZ);
wolfSSL 0:d92f9d21154c 11580
wolfSSL 0:d92f9d21154c 11581 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 11582 if (ssl->options.dtls)
wolfSSL 0:d92f9d21154c 11583 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 11584 return ret;
wolfSSL 0:d92f9d21154c 11585 #endif
wolfSSL 0:d92f9d21154c 11586
wolfSSL 0:d92f9d21154c 11587 ret = HashOutput(ssl, output, sendSz, 0);
wolfSSL 0:d92f9d21154c 11588 if (ret != 0)
wolfSSL 0:d92f9d21154c 11589 return ret;
wolfSSL 0:d92f9d21154c 11590
wolfSSL 0:d92f9d21154c 11591 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 11592 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 11593 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 11594 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 11595 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, output,
wolfSSL 0:d92f9d21154c 11596 sendSz, ssl->heap);
wolfSSL 0:d92f9d21154c 11597 #endif
wolfSSL 0:d92f9d21154c 11598
wolfSSL 0:d92f9d21154c 11599 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 11600 if (ssl->options.groupMessages)
wolfSSL 0:d92f9d21154c 11601 ret = 0;
wolfSSL 0:d92f9d21154c 11602 else
wolfSSL 0:d92f9d21154c 11603 ret = SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 11604 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
wolfSSL 0:d92f9d21154c 11605 }
wolfSSL 0:d92f9d21154c 11606 #endif /*NO_PSK */
wolfSSL 0:d92f9d21154c 11607
wolfSSL 0:d92f9d21154c 11608 #if !defined(NO_DH) && !defined(NO_PSK)
wolfSSL 0:d92f9d21154c 11609 if (ssl->specs.kea == dhe_psk_kea) {
wolfSSL 0:d92f9d21154c 11610 byte *output;
wolfSSL 0:d92f9d21154c 11611 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 11612 word32 hintLen;
wolfSSL 0:d92f9d21154c 11613 int sendSz;
wolfSSL 0:d92f9d21154c 11614 DhKey dhKey;
wolfSSL 0:d92f9d21154c 11615
wolfSSL 0:d92f9d21154c 11616 if (ssl->buffers.serverDH_P.buffer == NULL ||
wolfSSL 0:d92f9d21154c 11617 ssl->buffers.serverDH_G.buffer == NULL)
wolfSSL 0:d92f9d21154c 11618 return NO_DH_PARAMS;
wolfSSL 0:d92f9d21154c 11619
wolfSSL 0:d92f9d21154c 11620 if (ssl->buffers.serverDH_Pub.buffer == NULL) {
wolfSSL 0:d92f9d21154c 11621 ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
wolfSSL 0:d92f9d21154c 11622 ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
wolfSSL 0:d92f9d21154c 11623 DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 11624 if (ssl->buffers.serverDH_Pub.buffer == NULL)
wolfSSL 0:d92f9d21154c 11625 return MEMORY_E;
wolfSSL 0:d92f9d21154c 11626 }
wolfSSL 0:d92f9d21154c 11627
wolfSSL 0:d92f9d21154c 11628 if (ssl->buffers.serverDH_Priv.buffer == NULL) {
wolfSSL 0:d92f9d21154c 11629 ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
wolfSSL 0:d92f9d21154c 11630 ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
wolfSSL 0:d92f9d21154c 11631 DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 11632 if (ssl->buffers.serverDH_Priv.buffer == NULL)
wolfSSL 0:d92f9d21154c 11633 return MEMORY_E;
wolfSSL 0:d92f9d21154c 11634 }
wolfSSL 0:d92f9d21154c 11635
wolfSSL 0:d92f9d21154c 11636 wc_InitDhKey(&dhKey);
wolfSSL 0:d92f9d21154c 11637 ret = wc_DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
wolfSSL 0:d92f9d21154c 11638 ssl->buffers.serverDH_P.length,
wolfSSL 0:d92f9d21154c 11639 ssl->buffers.serverDH_G.buffer,
wolfSSL 0:d92f9d21154c 11640 ssl->buffers.serverDH_G.length);
wolfSSL 0:d92f9d21154c 11641 if (ret == 0)
wolfSSL 0:d92f9d21154c 11642 ret = wc_DhGenerateKeyPair(&dhKey, ssl->rng,
wolfSSL 0:d92f9d21154c 11643 ssl->buffers.serverDH_Priv.buffer,
wolfSSL 0:d92f9d21154c 11644 &ssl->buffers.serverDH_Priv.length,
wolfSSL 0:d92f9d21154c 11645 ssl->buffers.serverDH_Pub.buffer,
wolfSSL 0:d92f9d21154c 11646 &ssl->buffers.serverDH_Pub.length);
wolfSSL 0:d92f9d21154c 11647 wc_FreeDhKey(&dhKey);
wolfSSL 0:d92f9d21154c 11648 if (ret != 0)
wolfSSL 0:d92f9d21154c 11649 return ret;
wolfSSL 0:d92f9d21154c 11650
wolfSSL 0:d92f9d21154c 11651 length = LENGTH_SZ * 3 + /* p, g, pub */
wolfSSL 0:d92f9d21154c 11652 ssl->buffers.serverDH_P.length +
wolfSSL 0:d92f9d21154c 11653 ssl->buffers.serverDH_G.length +
wolfSSL 0:d92f9d21154c 11654 ssl->buffers.serverDH_Pub.length;
wolfSSL 0:d92f9d21154c 11655
wolfSSL 0:d92f9d21154c 11656 /* include size part */
wolfSSL 0:d92f9d21154c 11657 hintLen = (word32)XSTRLEN(ssl->arrays->server_hint);
wolfSSL 0:d92f9d21154c 11658 if (hintLen > MAX_PSK_ID_LEN)
wolfSSL 0:d92f9d21154c 11659 return SERVER_HINT_ERROR;
wolfSSL 0:d92f9d21154c 11660 length += hintLen + HINT_LEN_SZ;
wolfSSL 0:d92f9d21154c 11661 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 11662
wolfSSL 0:d92f9d21154c 11663 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 11664 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 11665 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 11666 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 11667 }
wolfSSL 0:d92f9d21154c 11668 #endif
wolfSSL 0:d92f9d21154c 11669
wolfSSL 0:d92f9d21154c 11670 /* check for available size */
wolfSSL 0:d92f9d21154c 11671 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 11672 return ret;
wolfSSL 0:d92f9d21154c 11673
wolfSSL 0:d92f9d21154c 11674 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 11675 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 11676 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 11677
wolfSSL 0:d92f9d21154c 11678 AddHeaders(output, length, server_key_exchange, ssl);
wolfSSL 0:d92f9d21154c 11679
wolfSSL 0:d92f9d21154c 11680 /* key data */
wolfSSL 0:d92f9d21154c 11681 c16toa((word16)hintLen, output + idx);
wolfSSL 0:d92f9d21154c 11682 idx += HINT_LEN_SZ;
wolfSSL 0:d92f9d21154c 11683 XMEMCPY(output + idx, ssl->arrays->server_hint, hintLen);
wolfSSL 0:d92f9d21154c 11684 idx += hintLen;
wolfSSL 0:d92f9d21154c 11685
wolfSSL 0:d92f9d21154c 11686 /* add p, g, pub */
wolfSSL 0:d92f9d21154c 11687 c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
wolfSSL 0:d92f9d21154c 11688 idx += LENGTH_SZ;
wolfSSL 0:d92f9d21154c 11689 XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
wolfSSL 0:d92f9d21154c 11690 ssl->buffers.serverDH_P.length);
wolfSSL 0:d92f9d21154c 11691 idx += ssl->buffers.serverDH_P.length;
wolfSSL 0:d92f9d21154c 11692
wolfSSL 0:d92f9d21154c 11693 /* g */
wolfSSL 0:d92f9d21154c 11694 c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
wolfSSL 0:d92f9d21154c 11695 idx += LENGTH_SZ;
wolfSSL 0:d92f9d21154c 11696 XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
wolfSSL 0:d92f9d21154c 11697 ssl->buffers.serverDH_G.length);
wolfSSL 0:d92f9d21154c 11698 idx += ssl->buffers.serverDH_G.length;
wolfSSL 0:d92f9d21154c 11699
wolfSSL 0:d92f9d21154c 11700 /* pub */
wolfSSL 0:d92f9d21154c 11701 c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
wolfSSL 0:d92f9d21154c 11702 idx += LENGTH_SZ;
wolfSSL 0:d92f9d21154c 11703 XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
wolfSSL 0:d92f9d21154c 11704 ssl->buffers.serverDH_Pub.length);
wolfSSL 0:d92f9d21154c 11705 idx += ssl->buffers.serverDH_Pub.length;
wolfSSL 0:d92f9d21154c 11706 (void)idx; /* suppress analyzer warning, and keep idx current */
wolfSSL 0:d92f9d21154c 11707
wolfSSL 0:d92f9d21154c 11708 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 11709 if (ssl->options.dtls)
wolfSSL 0:d92f9d21154c 11710 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 11711 return ret;
wolfSSL 0:d92f9d21154c 11712 #endif
wolfSSL 0:d92f9d21154c 11713
wolfSSL 0:d92f9d21154c 11714 ret = HashOutput(ssl, output, sendSz, 0);
wolfSSL 0:d92f9d21154c 11715
wolfSSL 0:d92f9d21154c 11716 if (ret != 0)
wolfSSL 0:d92f9d21154c 11717 return ret;
wolfSSL 0:d92f9d21154c 11718
wolfSSL 0:d92f9d21154c 11719 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 11720 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 11721 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 11722 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 11723 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, output,
wolfSSL 0:d92f9d21154c 11724 sendSz, ssl->heap);
wolfSSL 0:d92f9d21154c 11725 #endif
wolfSSL 0:d92f9d21154c 11726
wolfSSL 0:d92f9d21154c 11727 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 11728 if (ssl->options.groupMessages)
wolfSSL 0:d92f9d21154c 11729 ret = 0;
wolfSSL 0:d92f9d21154c 11730 else
wolfSSL 0:d92f9d21154c 11731 ret = SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 11732 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
wolfSSL 0:d92f9d21154c 11733 }
wolfSSL 0:d92f9d21154c 11734 #endif /* !NO_DH && !NO_PSK */
wolfSSL 0:d92f9d21154c 11735
wolfSSL 0:d92f9d21154c 11736 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 11737 if (ssl->specs.kea == ecc_diffie_hellman_kea)
wolfSSL 0:d92f9d21154c 11738 {
wolfSSL 0:d92f9d21154c 11739 byte *output;
wolfSSL 0:d92f9d21154c 11740 word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 11741 int sendSz;
wolfSSL 0:d92f9d21154c 11742 word32 sigSz;
wolfSSL 0:d92f9d21154c 11743 word32 preSigSz, preSigIdx;
wolfSSL 0:d92f9d21154c 11744 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 11745 RsaKey rsaKey;
wolfSSL 0:d92f9d21154c 11746 #endif
wolfSSL 0:d92f9d21154c 11747 ecc_key dsaKey;
wolfSSL 0:d92f9d21154c 11748 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 11749 byte* exportBuf = NULL;
wolfSSL 0:d92f9d21154c 11750 #else
wolfSSL 0:d92f9d21154c 11751 byte exportBuf[MAX_EXPORT_ECC_SZ];
wolfSSL 0:d92f9d21154c 11752 #endif
wolfSSL 0:d92f9d21154c 11753 word32 expSz = MAX_EXPORT_ECC_SZ;
wolfSSL 0:d92f9d21154c 11754
wolfSSL 0:d92f9d21154c 11755 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 11756 byte doMd5 = 0;
wolfSSL 0:d92f9d21154c 11757 byte doSha = 0;
wolfSSL 0:d92f9d21154c 11758 #endif
wolfSSL 0:d92f9d21154c 11759 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 11760 byte doSha256 = 0;
wolfSSL 0:d92f9d21154c 11761 #endif
wolfSSL 0:d92f9d21154c 11762 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 11763 byte doSha384 = 0;
wolfSSL 0:d92f9d21154c 11764 #endif
wolfSSL 0:d92f9d21154c 11765 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 11766 byte doSha512 = 0;
wolfSSL 0:d92f9d21154c 11767 #endif
wolfSSL 0:d92f9d21154c 11768
wolfSSL 0:d92f9d21154c 11769 if (ssl->specs.static_ecdh) {
wolfSSL 0:d92f9d21154c 11770 WOLFSSL_MSG("Using Static ECDH, not sending ServerKeyExchagne");
wolfSSL 0:d92f9d21154c 11771 return 0;
wolfSSL 0:d92f9d21154c 11772 }
wolfSSL 0:d92f9d21154c 11773
wolfSSL 0:d92f9d21154c 11774 /* curve type, named curve, length(1) */
wolfSSL 0:d92f9d21154c 11775 length = ENUM_LEN + CURVE_LEN + ENUM_LEN;
wolfSSL 0:d92f9d21154c 11776 /* pub key size */
wolfSSL 0:d92f9d21154c 11777 WOLFSSL_MSG("Using ephemeral ECDH");
wolfSSL 0:d92f9d21154c 11778
wolfSSL 0:d92f9d21154c 11779 /* need ephemeral key now, create it if missing */
wolfSSL 0:d92f9d21154c 11780 if (ssl->eccTempKey == NULL) {
wolfSSL 0:d92f9d21154c 11781 /* alloc/init on demand */
wolfSSL 0:d92f9d21154c 11782 ssl->eccTempKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
wolfSSL 0:d92f9d21154c 11783 ssl->ctx->heap, DYNAMIC_TYPE_ECC);
wolfSSL 0:d92f9d21154c 11784 if (ssl->eccTempKey == NULL) {
wolfSSL 0:d92f9d21154c 11785 WOLFSSL_MSG("EccTempKey Memory error");
wolfSSL 0:d92f9d21154c 11786 return MEMORY_E;
wolfSSL 0:d92f9d21154c 11787 }
wolfSSL 0:d92f9d21154c 11788 wc_ecc_init(ssl->eccTempKey);
wolfSSL 0:d92f9d21154c 11789 }
wolfSSL 0:d92f9d21154c 11790 if (ssl->eccTempKeyPresent == 0) {
wolfSSL 0:d92f9d21154c 11791 if (wc_ecc_make_key(ssl->rng, ssl->eccTempKeySz,
wolfSSL 0:d92f9d21154c 11792 ssl->eccTempKey) != 0) {
wolfSSL 0:d92f9d21154c 11793 return ECC_MAKEKEY_ERROR;
wolfSSL 0:d92f9d21154c 11794 }
wolfSSL 0:d92f9d21154c 11795 ssl->eccTempKeyPresent = 1;
wolfSSL 0:d92f9d21154c 11796 }
wolfSSL 0:d92f9d21154c 11797
wolfSSL 0:d92f9d21154c 11798 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 11799 exportBuf = (byte*)XMALLOC(MAX_EXPORT_ECC_SZ, NULL,
wolfSSL 0:d92f9d21154c 11800 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 11801 if (exportBuf == NULL)
wolfSSL 0:d92f9d21154c 11802 return MEMORY_E;
wolfSSL 0:d92f9d21154c 11803 #endif
wolfSSL 0:d92f9d21154c 11804
wolfSSL 0:d92f9d21154c 11805 if (wc_ecc_export_x963(ssl->eccTempKey, exportBuf, &expSz) != 0)
wolfSSL 0:d92f9d21154c 11806 ERROR_OUT(ECC_EXPORT_ERROR, done_a);
wolfSSL 0:d92f9d21154c 11807 length += expSz;
wolfSSL 0:d92f9d21154c 11808
wolfSSL 0:d92f9d21154c 11809 preSigSz = length;
wolfSSL 0:d92f9d21154c 11810 preSigIdx = idx;
wolfSSL 0:d92f9d21154c 11811
wolfSSL 0:d92f9d21154c 11812 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 11813 ret = wc_InitRsaKey(&rsaKey, ssl->heap);
wolfSSL 0:d92f9d21154c 11814 if (ret != 0)
wolfSSL 0:d92f9d21154c 11815 goto done_a;
wolfSSL 0:d92f9d21154c 11816 #endif
wolfSSL 0:d92f9d21154c 11817
wolfSSL 0:d92f9d21154c 11818 wc_ecc_init(&dsaKey);
wolfSSL 0:d92f9d21154c 11819
wolfSSL 0:d92f9d21154c 11820 /* sig length */
wolfSSL 0:d92f9d21154c 11821 length += LENGTH_SZ;
wolfSSL 0:d92f9d21154c 11822
wolfSSL 0:d92f9d21154c 11823 if (!ssl->buffers.key.buffer) {
wolfSSL 0:d92f9d21154c 11824 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 11825 wc_FreeRsaKey(&rsaKey);
wolfSSL 0:d92f9d21154c 11826 #endif
wolfSSL 0:d92f9d21154c 11827 wc_ecc_free(&dsaKey);
wolfSSL 0:d92f9d21154c 11828 ERROR_OUT(NO_PRIVATE_KEY, done_a);
wolfSSL 0:d92f9d21154c 11829 }
wolfSSL 0:d92f9d21154c 11830
wolfSSL 0:d92f9d21154c 11831 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 11832 if (ssl->specs.sig_algo == rsa_sa_algo) {
wolfSSL 0:d92f9d21154c 11833 /* rsa sig size */
wolfSSL 0:d92f9d21154c 11834 word32 i = 0;
wolfSSL 0:d92f9d21154c 11835 ret = wc_RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i,
wolfSSL 0:d92f9d21154c 11836 &rsaKey, ssl->buffers.key.length);
wolfSSL 0:d92f9d21154c 11837 if (ret != 0)
wolfSSL 0:d92f9d21154c 11838 goto done_a;
wolfSSL 0:d92f9d21154c 11839 sigSz = wc_RsaEncryptSize(&rsaKey);
wolfSSL 0:d92f9d21154c 11840 } else
wolfSSL 0:d92f9d21154c 11841 #endif
wolfSSL 0:d92f9d21154c 11842
wolfSSL 0:d92f9d21154c 11843 if (ssl->specs.sig_algo == ecc_dsa_sa_algo) {
wolfSSL 0:d92f9d21154c 11844 /* ecdsa sig size */
wolfSSL 0:d92f9d21154c 11845 word32 i = 0;
wolfSSL 0:d92f9d21154c 11846 ret = wc_EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
wolfSSL 0:d92f9d21154c 11847 &dsaKey, ssl->buffers.key.length);
wolfSSL 0:d92f9d21154c 11848 if (ret != 0)
wolfSSL 0:d92f9d21154c 11849 goto done_a;
wolfSSL 0:d92f9d21154c 11850 sigSz = wc_ecc_sig_size(&dsaKey); /* worst case estimate */
wolfSSL 0:d92f9d21154c 11851 }
wolfSSL 0:d92f9d21154c 11852 else {
wolfSSL 0:d92f9d21154c 11853 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 11854 wc_FreeRsaKey(&rsaKey);
wolfSSL 0:d92f9d21154c 11855 #endif
wolfSSL 0:d92f9d21154c 11856 wc_ecc_free(&dsaKey);
wolfSSL 0:d92f9d21154c 11857 ERROR_OUT(ALGO_ID_E, done_a); /* unsupported type */
wolfSSL 0:d92f9d21154c 11858 }
wolfSSL 0:d92f9d21154c 11859 length += sigSz;
wolfSSL 0:d92f9d21154c 11860
wolfSSL 0:d92f9d21154c 11861 if (IsAtLeastTLSv1_2(ssl))
wolfSSL 0:d92f9d21154c 11862 length += HASH_SIG_SIZE;
wolfSSL 0:d92f9d21154c 11863
wolfSSL 0:d92f9d21154c 11864 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 11865
wolfSSL 0:d92f9d21154c 11866 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 11867 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 11868 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 11869 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 11870 preSigIdx = idx;
wolfSSL 0:d92f9d21154c 11871 }
wolfSSL 0:d92f9d21154c 11872 #endif
wolfSSL 0:d92f9d21154c 11873 /* check for available size */
wolfSSL 0:d92f9d21154c 11874 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
wolfSSL 0:d92f9d21154c 11875 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 11876 wc_FreeRsaKey(&rsaKey);
wolfSSL 0:d92f9d21154c 11877 #endif
wolfSSL 0:d92f9d21154c 11878 wc_ecc_free(&dsaKey);
wolfSSL 0:d92f9d21154c 11879 goto done_a;
wolfSSL 0:d92f9d21154c 11880 }
wolfSSL 0:d92f9d21154c 11881
wolfSSL 0:d92f9d21154c 11882 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 11883 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 11884 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 11885
wolfSSL 0:d92f9d21154c 11886 /* record and message headers will be added below, when we're sure
wolfSSL 0:d92f9d21154c 11887 of the sig length */
wolfSSL 0:d92f9d21154c 11888
wolfSSL 0:d92f9d21154c 11889 /* key exchange data */
wolfSSL 0:d92f9d21154c 11890 output[idx++] = named_curve;
wolfSSL 0:d92f9d21154c 11891 output[idx++] = 0x00; /* leading zero */
wolfSSL 0:d92f9d21154c 11892 output[idx++] = SetCurveId(wc_ecc_size(ssl->eccTempKey));
wolfSSL 0:d92f9d21154c 11893 output[idx++] = (byte)expSz;
wolfSSL 0:d92f9d21154c 11894 XMEMCPY(output + idx, exportBuf, expSz);
wolfSSL 0:d92f9d21154c 11895 idx += expSz;
wolfSSL 0:d92f9d21154c 11896 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 11897 byte setHash = 0;
wolfSSL 0:d92f9d21154c 11898
wolfSSL 0:d92f9d21154c 11899 output[idx++] = ssl->suites->hashAlgo;
wolfSSL 0:d92f9d21154c 11900 output[idx++] = ssl->suites->sigAlgo;
wolfSSL 0:d92f9d21154c 11901
wolfSSL 0:d92f9d21154c 11902 switch (ssl->suites->hashAlgo) {
wolfSSL 0:d92f9d21154c 11903 case sha512_mac:
wolfSSL 0:d92f9d21154c 11904 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 11905 doSha512 = 1;
wolfSSL 0:d92f9d21154c 11906 setHash = 1;
wolfSSL 0:d92f9d21154c 11907 #endif
wolfSSL 0:d92f9d21154c 11908 break;
wolfSSL 0:d92f9d21154c 11909
wolfSSL 0:d92f9d21154c 11910 case sha384_mac:
wolfSSL 0:d92f9d21154c 11911 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 11912 doSha384 = 1;
wolfSSL 0:d92f9d21154c 11913 setHash = 1;
wolfSSL 0:d92f9d21154c 11914 #endif
wolfSSL 0:d92f9d21154c 11915 break;
wolfSSL 0:d92f9d21154c 11916
wolfSSL 0:d92f9d21154c 11917 case sha256_mac:
wolfSSL 0:d92f9d21154c 11918 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 11919 doSha256 = 1;
wolfSSL 0:d92f9d21154c 11920 setHash = 1;
wolfSSL 0:d92f9d21154c 11921 #endif
wolfSSL 0:d92f9d21154c 11922 break;
wolfSSL 0:d92f9d21154c 11923
wolfSSL 0:d92f9d21154c 11924 case sha_mac:
wolfSSL 0:d92f9d21154c 11925 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 11926 doSha = 1;
wolfSSL 0:d92f9d21154c 11927 setHash = 1;
wolfSSL 0:d92f9d21154c 11928 #endif
wolfSSL 0:d92f9d21154c 11929 break;
wolfSSL 0:d92f9d21154c 11930
wolfSSL 0:d92f9d21154c 11931 default:
wolfSSL 0:d92f9d21154c 11932 WOLFSSL_MSG("Bad hash sig algo");
wolfSSL 0:d92f9d21154c 11933 break;
wolfSSL 0:d92f9d21154c 11934 }
wolfSSL 0:d92f9d21154c 11935
wolfSSL 0:d92f9d21154c 11936 if (setHash == 0) {
wolfSSL 0:d92f9d21154c 11937 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 11938 wc_FreeRsaKey(&rsaKey);
wolfSSL 0:d92f9d21154c 11939 #endif
wolfSSL 0:d92f9d21154c 11940 wc_ecc_free(&dsaKey);
wolfSSL 0:d92f9d21154c 11941 ERROR_OUT(ALGO_ID_E, done_a);
wolfSSL 0:d92f9d21154c 11942 }
wolfSSL 0:d92f9d21154c 11943 } else {
wolfSSL 0:d92f9d21154c 11944 /* only using sha and md5 for rsa */
wolfSSL 0:d92f9d21154c 11945 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 11946 doSha = 1;
wolfSSL 0:d92f9d21154c 11947 if (ssl->suites->sigAlgo == rsa_sa_algo) {
wolfSSL 0:d92f9d21154c 11948 doMd5 = 1;
wolfSSL 0:d92f9d21154c 11949 }
wolfSSL 0:d92f9d21154c 11950 #else
wolfSSL 0:d92f9d21154c 11951 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 11952 wc_FreeRsaKey(&rsaKey);
wolfSSL 0:d92f9d21154c 11953 #endif
wolfSSL 0:d92f9d21154c 11954 wc_ecc_free(&dsaKey);
wolfSSL 0:d92f9d21154c 11955 ERROR_OUT(ALGO_ID_E, done_a);
wolfSSL 0:d92f9d21154c 11956 #endif
wolfSSL 0:d92f9d21154c 11957 }
wolfSSL 0:d92f9d21154c 11958
wolfSSL 0:d92f9d21154c 11959 /* Signtaure length will be written later, when we're sure what it
wolfSSL 0:d92f9d21154c 11960 is */
wolfSSL 0:d92f9d21154c 11961
wolfSSL 0:d92f9d21154c 11962 #ifdef HAVE_FUZZER
wolfSSL 0:d92f9d21154c 11963 if (ssl->fuzzerCb)
wolfSSL 0:d92f9d21154c 11964 ssl->fuzzerCb(ssl, output + preSigIdx, preSigSz, FUZZ_SIGNATURE,
wolfSSL 0:d92f9d21154c 11965 ssl->fuzzerCtx);
wolfSSL 0:d92f9d21154c 11966 #endif
wolfSSL 0:d92f9d21154c 11967
wolfSSL 0:d92f9d21154c 11968 /* do signature */
wolfSSL 0:d92f9d21154c 11969 {
wolfSSL 0:d92f9d21154c 11970 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 11971 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 11972 Md5* md5 = NULL;
wolfSSL 0:d92f9d21154c 11973 Sha* sha = NULL;
wolfSSL 0:d92f9d21154c 11974 #else
wolfSSL 0:d92f9d21154c 11975 Md5 md5[1];
wolfSSL 0:d92f9d21154c 11976 Sha sha[1];
wolfSSL 0:d92f9d21154c 11977 #endif
wolfSSL 0:d92f9d21154c 11978 #endif
wolfSSL 0:d92f9d21154c 11979 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 11980 byte* hash = NULL;
wolfSSL 0:d92f9d21154c 11981 #else
wolfSSL 0:d92f9d21154c 11982 byte hash[FINISHED_SZ];
wolfSSL 0:d92f9d21154c 11983 #endif
wolfSSL 0:d92f9d21154c 11984 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 11985 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 11986 Sha256* sha256 = NULL;
wolfSSL 0:d92f9d21154c 11987 byte* hash256 = NULL;
wolfSSL 0:d92f9d21154c 11988 #else
wolfSSL 0:d92f9d21154c 11989 Sha256 sha256[1];
wolfSSL 0:d92f9d21154c 11990 byte hash256[SHA256_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 11991 #endif
wolfSSL 0:d92f9d21154c 11992 #endif
wolfSSL 0:d92f9d21154c 11993 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 11994 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 11995 Sha384* sha384 = NULL;
wolfSSL 0:d92f9d21154c 11996 byte* hash384 = NULL;
wolfSSL 0:d92f9d21154c 11997 #else
wolfSSL 0:d92f9d21154c 11998 Sha384 sha384[1];
wolfSSL 0:d92f9d21154c 11999 byte hash384[SHA384_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 12000 #endif
wolfSSL 0:d92f9d21154c 12001 #endif
wolfSSL 0:d92f9d21154c 12002 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 12003 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12004 Sha512* sha512 = NULL;
wolfSSL 0:d92f9d21154c 12005 byte* hash512 = NULL;
wolfSSL 0:d92f9d21154c 12006 #else
wolfSSL 0:d92f9d21154c 12007 Sha512 sha512[1];
wolfSSL 0:d92f9d21154c 12008 byte hash512[SHA512_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 12009 #endif
wolfSSL 0:d92f9d21154c 12010 #endif
wolfSSL 0:d92f9d21154c 12011
wolfSSL 0:d92f9d21154c 12012 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12013 hash = (byte*)XMALLOC(FINISHED_SZ, NULL,
wolfSSL 0:d92f9d21154c 12014 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12015 if (hash == NULL)
wolfSSL 0:d92f9d21154c 12016 ERROR_OUT(MEMORY_E, done_a);
wolfSSL 0:d92f9d21154c 12017 #endif
wolfSSL 0:d92f9d21154c 12018
wolfSSL 0:d92f9d21154c 12019 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 12020 /* md5 */
wolfSSL 0:d92f9d21154c 12021 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12022 if (doMd5) {
wolfSSL 0:d92f9d21154c 12023 md5 = (Md5*)XMALLOC(sizeof(Md5), NULL,
wolfSSL 0:d92f9d21154c 12024 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12025 if (md5 == NULL)
wolfSSL 0:d92f9d21154c 12026 ERROR_OUT(MEMORY_E, done_a2);
wolfSSL 0:d92f9d21154c 12027 }
wolfSSL 0:d92f9d21154c 12028 #endif
wolfSSL 0:d92f9d21154c 12029 if (doMd5) {
wolfSSL 0:d92f9d21154c 12030 wc_InitMd5(md5);
wolfSSL 0:d92f9d21154c 12031 wc_Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
wolfSSL 0:d92f9d21154c 12032 wc_Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
wolfSSL 0:d92f9d21154c 12033 wc_Md5Update(md5, output + preSigIdx, preSigSz);
wolfSSL 0:d92f9d21154c 12034 wc_Md5Final(md5, hash);
wolfSSL 0:d92f9d21154c 12035 }
wolfSSL 0:d92f9d21154c 12036 /* sha */
wolfSSL 0:d92f9d21154c 12037 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12038 if (doSha) {
wolfSSL 0:d92f9d21154c 12039 sha = (Sha*)XMALLOC(sizeof(Sha), NULL,
wolfSSL 0:d92f9d21154c 12040 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12041 if (sha == NULL)
wolfSSL 0:d92f9d21154c 12042 ERROR_OUT(MEMORY_E, done_a2);
wolfSSL 0:d92f9d21154c 12043 }
wolfSSL 0:d92f9d21154c 12044 #endif
wolfSSL 0:d92f9d21154c 12045 if (doSha) {
wolfSSL 0:d92f9d21154c 12046 ret = wc_InitSha(sha);
wolfSSL 0:d92f9d21154c 12047 if (ret != 0) goto done_a2;
wolfSSL 0:d92f9d21154c 12048 wc_ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
wolfSSL 0:d92f9d21154c 12049 wc_ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
wolfSSL 0:d92f9d21154c 12050 wc_ShaUpdate(sha, output + preSigIdx, preSigSz);
wolfSSL 0:d92f9d21154c 12051 wc_ShaFinal(sha, &hash[MD5_DIGEST_SIZE]);
wolfSSL 0:d92f9d21154c 12052 }
wolfSSL 0:d92f9d21154c 12053 #endif
wolfSSL 0:d92f9d21154c 12054
wolfSSL 0:d92f9d21154c 12055 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 12056 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12057 if (doSha256) {
wolfSSL 0:d92f9d21154c 12058 sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
wolfSSL 0:d92f9d21154c 12059 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12060 hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
wolfSSL 0:d92f9d21154c 12061 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12062 if (sha256 == NULL || hash256 == NULL)
wolfSSL 0:d92f9d21154c 12063 ERROR_OUT(MEMORY_E, done_a2);
wolfSSL 0:d92f9d21154c 12064 }
wolfSSL 0:d92f9d21154c 12065 #endif
wolfSSL 0:d92f9d21154c 12066
wolfSSL 0:d92f9d21154c 12067 if (doSha256) {
wolfSSL 0:d92f9d21154c 12068 if (!(ret = wc_InitSha256(sha256))
wolfSSL 0:d92f9d21154c 12069 && !(ret = wc_Sha256Update(sha256,
wolfSSL 0:d92f9d21154c 12070 ssl->arrays->clientRandom, RAN_LEN))
wolfSSL 0:d92f9d21154c 12071 && !(ret = wc_Sha256Update(sha256,
wolfSSL 0:d92f9d21154c 12072 ssl->arrays->serverRandom, RAN_LEN))
wolfSSL 0:d92f9d21154c 12073 && !(ret = wc_Sha256Update(sha256,
wolfSSL 0:d92f9d21154c 12074 output + preSigIdx, preSigSz)))
wolfSSL 0:d92f9d21154c 12075 ret = wc_Sha256Final(sha256, hash256);
wolfSSL 0:d92f9d21154c 12076
wolfSSL 0:d92f9d21154c 12077 if (ret != 0) goto done_a2;
wolfSSL 0:d92f9d21154c 12078 }
wolfSSL 0:d92f9d21154c 12079 #endif
wolfSSL 0:d92f9d21154c 12080
wolfSSL 0:d92f9d21154c 12081 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 12082 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12083 if (doSha384) {
wolfSSL 0:d92f9d21154c 12084 sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
wolfSSL 0:d92f9d21154c 12085 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12086 hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
wolfSSL 0:d92f9d21154c 12087 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12088 if (sha384 == NULL || hash384 == NULL)
wolfSSL 0:d92f9d21154c 12089 ERROR_OUT(MEMORY_E, done_a2);
wolfSSL 0:d92f9d21154c 12090 }
wolfSSL 0:d92f9d21154c 12091 #endif
wolfSSL 0:d92f9d21154c 12092
wolfSSL 0:d92f9d21154c 12093 if (doSha384) {
wolfSSL 0:d92f9d21154c 12094 if (!(ret = wc_InitSha384(sha384))
wolfSSL 0:d92f9d21154c 12095 && !(ret = wc_Sha384Update(sha384,
wolfSSL 0:d92f9d21154c 12096 ssl->arrays->clientRandom, RAN_LEN))
wolfSSL 0:d92f9d21154c 12097 && !(ret = wc_Sha384Update(sha384,
wolfSSL 0:d92f9d21154c 12098 ssl->arrays->serverRandom, RAN_LEN))
wolfSSL 0:d92f9d21154c 12099 && !(ret = wc_Sha384Update(sha384,
wolfSSL 0:d92f9d21154c 12100 output + preSigIdx, preSigSz)))
wolfSSL 0:d92f9d21154c 12101 ret = wc_Sha384Final(sha384, hash384);
wolfSSL 0:d92f9d21154c 12102
wolfSSL 0:d92f9d21154c 12103 if (ret != 0) goto done_a2;
wolfSSL 0:d92f9d21154c 12104 }
wolfSSL 0:d92f9d21154c 12105 #endif
wolfSSL 0:d92f9d21154c 12106
wolfSSL 0:d92f9d21154c 12107 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 12108 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12109 if (doSha512) {
wolfSSL 0:d92f9d21154c 12110 sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL,
wolfSSL 0:d92f9d21154c 12111 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12112 hash512 = (byte*)XMALLOC(SHA512_DIGEST_SIZE, NULL,
wolfSSL 0:d92f9d21154c 12113 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12114 if (sha512 == NULL || hash512 == NULL)
wolfSSL 0:d92f9d21154c 12115 ERROR_OUT(MEMORY_E, done_a2);
wolfSSL 0:d92f9d21154c 12116 }
wolfSSL 0:d92f9d21154c 12117 #endif
wolfSSL 0:d92f9d21154c 12118
wolfSSL 0:d92f9d21154c 12119 if (doSha512) {
wolfSSL 0:d92f9d21154c 12120 if (!(ret = wc_InitSha512(sha512))
wolfSSL 0:d92f9d21154c 12121 && !(ret = wc_Sha512Update(sha512,
wolfSSL 0:d92f9d21154c 12122 ssl->arrays->clientRandom, RAN_LEN))
wolfSSL 0:d92f9d21154c 12123 && !(ret = wc_Sha512Update(sha512,
wolfSSL 0:d92f9d21154c 12124 ssl->arrays->serverRandom, RAN_LEN))
wolfSSL 0:d92f9d21154c 12125 && !(ret = wc_Sha512Update(sha512,
wolfSSL 0:d92f9d21154c 12126 output + preSigIdx, preSigSz)))
wolfSSL 0:d92f9d21154c 12127 ret = wc_Sha512Final(sha512, hash512);
wolfSSL 0:d92f9d21154c 12128
wolfSSL 0:d92f9d21154c 12129 if (ret != 0) goto done_a2;
wolfSSL 0:d92f9d21154c 12130 }
wolfSSL 0:d92f9d21154c 12131 #endif
wolfSSL 0:d92f9d21154c 12132
wolfSSL 0:d92f9d21154c 12133 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 12134 if (ssl->suites->sigAlgo == rsa_sa_algo) {
wolfSSL 0:d92f9d21154c 12135 byte* signBuffer = hash;
wolfSSL 0:d92f9d21154c 12136 word32 signSz = FINISHED_SZ;
wolfSSL 0:d92f9d21154c 12137 byte doUserRsa = 0;
wolfSSL 0:d92f9d21154c 12138 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12139 byte* encodedSig = NULL;
wolfSSL 0:d92f9d21154c 12140 #else
wolfSSL 0:d92f9d21154c 12141 byte encodedSig[MAX_ENCODED_SIG_SZ];
wolfSSL 0:d92f9d21154c 12142 #endif
wolfSSL 0:d92f9d21154c 12143
wolfSSL 0:d92f9d21154c 12144 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 12145 if (ssl->ctx->RsaSignCb)
wolfSSL 0:d92f9d21154c 12146 doUserRsa = 1;
wolfSSL 0:d92f9d21154c 12147 #endif
wolfSSL 0:d92f9d21154c 12148
wolfSSL 0:d92f9d21154c 12149 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12150 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
wolfSSL 0:d92f9d21154c 12151 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12152 if (encodedSig == NULL)
wolfSSL 0:d92f9d21154c 12153 ERROR_OUT(MEMORY_E, done_a2);
wolfSSL 0:d92f9d21154c 12154 #endif
wolfSSL 0:d92f9d21154c 12155
wolfSSL 0:d92f9d21154c 12156 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 12157 byte* digest = &hash[MD5_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 12158 int typeH = SHAh;
wolfSSL 0:d92f9d21154c 12159 int digestSz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 12160
wolfSSL 0:d92f9d21154c 12161 if (ssl->suites->hashAlgo == sha256_mac) {
wolfSSL 0:d92f9d21154c 12162 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 12163 digest = hash256;
wolfSSL 0:d92f9d21154c 12164 typeH = SHA256h;
wolfSSL 0:d92f9d21154c 12165 digestSz = SHA256_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 12166 #endif
wolfSSL 0:d92f9d21154c 12167 }
wolfSSL 0:d92f9d21154c 12168 else if (ssl->suites->hashAlgo == sha384_mac) {
wolfSSL 0:d92f9d21154c 12169 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 12170 digest = hash384;
wolfSSL 0:d92f9d21154c 12171 typeH = SHA384h;
wolfSSL 0:d92f9d21154c 12172 digestSz = SHA384_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 12173 #endif
wolfSSL 0:d92f9d21154c 12174 }
wolfSSL 0:d92f9d21154c 12175 else if (ssl->suites->hashAlgo == sha512_mac) {
wolfSSL 0:d92f9d21154c 12176 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 12177 digest = hash512;
wolfSSL 0:d92f9d21154c 12178 typeH = SHA512h;
wolfSSL 0:d92f9d21154c 12179 digestSz = SHA512_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 12180 #endif
wolfSSL 0:d92f9d21154c 12181 }
wolfSSL 0:d92f9d21154c 12182
wolfSSL 0:d92f9d21154c 12183 if (digest == NULL) {
wolfSSL 0:d92f9d21154c 12184 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 12185 wc_FreeRsaKey(&rsaKey);
wolfSSL 0:d92f9d21154c 12186 #endif
wolfSSL 0:d92f9d21154c 12187 wc_ecc_free(&dsaKey);
wolfSSL 0:d92f9d21154c 12188 ERROR_OUT(ALGO_ID_E, done_a2);
wolfSSL 0:d92f9d21154c 12189 }
wolfSSL 0:d92f9d21154c 12190 signSz = wc_EncodeSignature(encodedSig, digest,
wolfSSL 0:d92f9d21154c 12191 digestSz, typeH);
wolfSSL 0:d92f9d21154c 12192 signBuffer = encodedSig;
wolfSSL 0:d92f9d21154c 12193 }
wolfSSL 0:d92f9d21154c 12194 /* write sig size here */
wolfSSL 0:d92f9d21154c 12195 c16toa((word16)sigSz, output + idx);
wolfSSL 0:d92f9d21154c 12196 idx += LENGTH_SZ;
wolfSSL 0:d92f9d21154c 12197
wolfSSL 0:d92f9d21154c 12198 if (doUserRsa) {
wolfSSL 0:d92f9d21154c 12199 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 12200 word32 ioLen = sigSz;
wolfSSL 0:d92f9d21154c 12201 ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
wolfSSL 0:d92f9d21154c 12202 output + idx, &ioLen,
wolfSSL 0:d92f9d21154c 12203 ssl->buffers.key.buffer,
wolfSSL 0:d92f9d21154c 12204 ssl->buffers.key.length,
wolfSSL 0:d92f9d21154c 12205 ssl->RsaSignCtx);
wolfSSL 0:d92f9d21154c 12206 #endif /*HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 12207 }
wolfSSL 0:d92f9d21154c 12208 else
wolfSSL 0:d92f9d21154c 12209 ret = wc_RsaSSL_Sign(signBuffer, signSz, output + idx,
wolfSSL 0:d92f9d21154c 12210 sigSz, &rsaKey, ssl->rng);
wolfSSL 0:d92f9d21154c 12211
wolfSSL 0:d92f9d21154c 12212 wc_FreeRsaKey(&rsaKey);
wolfSSL 0:d92f9d21154c 12213 wc_ecc_free(&dsaKey);
wolfSSL 0:d92f9d21154c 12214
wolfSSL 0:d92f9d21154c 12215 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12216 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12217 #endif
wolfSSL 0:d92f9d21154c 12218
wolfSSL 0:d92f9d21154c 12219 if (ret < 0)
wolfSSL 0:d92f9d21154c 12220 goto done_a2;
wolfSSL 0:d92f9d21154c 12221 } else
wolfSSL 0:d92f9d21154c 12222 #endif
wolfSSL 0:d92f9d21154c 12223
wolfSSL 0:d92f9d21154c 12224 if (ssl->suites->sigAlgo == ecc_dsa_sa_algo) {
wolfSSL 0:d92f9d21154c 12225 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 12226 byte* digest = &hash[MD5_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 12227 word32 digestSz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 12228 #else
wolfSSL 0:d92f9d21154c 12229 byte* digest = hash256;
wolfSSL 0:d92f9d21154c 12230 word32 digestSz = SHA256_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 12231 #endif
wolfSSL 0:d92f9d21154c 12232 word32 sz = sigSz;
wolfSSL 0:d92f9d21154c 12233 byte doUserEcc = 0;
wolfSSL 0:d92f9d21154c 12234
wolfSSL 0:d92f9d21154c 12235 #if defined(HAVE_PK_CALLBACKS) && defined(HAVE_ECC)
wolfSSL 0:d92f9d21154c 12236 if (ssl->ctx->EccSignCb)
wolfSSL 0:d92f9d21154c 12237 doUserEcc = 1;
wolfSSL 0:d92f9d21154c 12238 #endif
wolfSSL 0:d92f9d21154c 12239
wolfSSL 0:d92f9d21154c 12240 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 12241 if (ssl->suites->hashAlgo == sha_mac) {
wolfSSL 0:d92f9d21154c 12242 #ifndef NO_SHA
wolfSSL 0:d92f9d21154c 12243 digest = &hash[MD5_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 12244 digestSz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 12245 #endif
wolfSSL 0:d92f9d21154c 12246 }
wolfSSL 0:d92f9d21154c 12247 else if (ssl->suites->hashAlgo == sha256_mac) {
wolfSSL 0:d92f9d21154c 12248 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 12249 digest = hash256;
wolfSSL 0:d92f9d21154c 12250 digestSz = SHA256_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 12251 #endif
wolfSSL 0:d92f9d21154c 12252 }
wolfSSL 0:d92f9d21154c 12253 else if (ssl->suites->hashAlgo == sha384_mac) {
wolfSSL 0:d92f9d21154c 12254 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 12255 digest = hash384;
wolfSSL 0:d92f9d21154c 12256 digestSz = SHA384_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 12257 #endif
wolfSSL 0:d92f9d21154c 12258 }
wolfSSL 0:d92f9d21154c 12259 else if (ssl->suites->hashAlgo == sha512_mac) {
wolfSSL 0:d92f9d21154c 12260 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 12261 digest = hash512;
wolfSSL 0:d92f9d21154c 12262 digestSz = SHA512_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 12263 #endif
wolfSSL 0:d92f9d21154c 12264 }
wolfSSL 0:d92f9d21154c 12265 }
wolfSSL 0:d92f9d21154c 12266
wolfSSL 0:d92f9d21154c 12267 if (doUserEcc) {
wolfSSL 0:d92f9d21154c 12268 #if defined(HAVE_PK_CALLBACKS) && defined(HAVE_ECC)
wolfSSL 0:d92f9d21154c 12269 ret = ssl->ctx->EccSignCb(ssl, digest, digestSz,
wolfSSL 0:d92f9d21154c 12270 output + LENGTH_SZ + idx, &sz,
wolfSSL 0:d92f9d21154c 12271 ssl->buffers.key.buffer,
wolfSSL 0:d92f9d21154c 12272 ssl->buffers.key.length,
wolfSSL 0:d92f9d21154c 12273 ssl->EccSignCtx);
wolfSSL 0:d92f9d21154c 12274 #endif
wolfSSL 0:d92f9d21154c 12275 }
wolfSSL 0:d92f9d21154c 12276 else {
wolfSSL 0:d92f9d21154c 12277 ret = wc_ecc_sign_hash(digest, digestSz,
wolfSSL 0:d92f9d21154c 12278 output + LENGTH_SZ + idx, &sz, ssl->rng, &dsaKey);
wolfSSL 0:d92f9d21154c 12279 }
wolfSSL 0:d92f9d21154c 12280 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 12281 wc_FreeRsaKey(&rsaKey);
wolfSSL 0:d92f9d21154c 12282 #endif
wolfSSL 0:d92f9d21154c 12283 wc_ecc_free(&dsaKey);
wolfSSL 0:d92f9d21154c 12284
wolfSSL 0:d92f9d21154c 12285 if (ret < 0)
wolfSSL 0:d92f9d21154c 12286 goto done_a2;
wolfSSL 0:d92f9d21154c 12287
wolfSSL 0:d92f9d21154c 12288 /* Now that we know the real sig size, write it. */
wolfSSL 0:d92f9d21154c 12289 c16toa((word16)sz, output + idx);
wolfSSL 0:d92f9d21154c 12290
wolfSSL 0:d92f9d21154c 12291 /* And adjust length and sendSz from estimates */
wolfSSL 0:d92f9d21154c 12292 length += sz - sigSz;
wolfSSL 0:d92f9d21154c 12293 sendSz += sz - sigSz;
wolfSSL 0:d92f9d21154c 12294 }
wolfSSL 0:d92f9d21154c 12295
wolfSSL 0:d92f9d21154c 12296 done_a2:
wolfSSL 0:d92f9d21154c 12297 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12298 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 12299 XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12300 XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12301 #endif
wolfSSL 0:d92f9d21154c 12302 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12303 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 12304 XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12305 XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12306 #endif
wolfSSL 0:d92f9d21154c 12307 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 12308 XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12309 XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12310 #endif
wolfSSL 0:d92f9d21154c 12311 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 12312 XFREE(sha512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12313 XFREE(hash512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12314 #endif
wolfSSL 0:d92f9d21154c 12315 #endif
wolfSSL 0:d92f9d21154c 12316
wolfSSL 0:d92f9d21154c 12317 if (ret < 0)
wolfSSL 0:d92f9d21154c 12318 goto done_a;
wolfSSL 0:d92f9d21154c 12319 }
wolfSSL 0:d92f9d21154c 12320
wolfSSL 0:d92f9d21154c 12321 AddHeaders(output, length, server_key_exchange, ssl);
wolfSSL 0:d92f9d21154c 12322
wolfSSL 0:d92f9d21154c 12323 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 12324 if (ssl->options.dtls)
wolfSSL 0:d92f9d21154c 12325 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 12326 goto done_a;
wolfSSL 0:d92f9d21154c 12327 #endif
wolfSSL 0:d92f9d21154c 12328
wolfSSL 0:d92f9d21154c 12329 if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0)
wolfSSL 0:d92f9d21154c 12330 goto done_a;
wolfSSL 0:d92f9d21154c 12331
wolfSSL 0:d92f9d21154c 12332 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 12333 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 12334 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 12335 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 12336 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
wolfSSL 0:d92f9d21154c 12337 output, sendSz, ssl->heap);
wolfSSL 0:d92f9d21154c 12338 #endif
wolfSSL 0:d92f9d21154c 12339
wolfSSL 0:d92f9d21154c 12340 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 12341 if (ssl->options.groupMessages)
wolfSSL 0:d92f9d21154c 12342 ret = 0;
wolfSSL 0:d92f9d21154c 12343 else
wolfSSL 0:d92f9d21154c 12344 ret = SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 12345 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
wolfSSL 0:d92f9d21154c 12346
wolfSSL 0:d92f9d21154c 12347 done_a:
wolfSSL 0:d92f9d21154c 12348 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12349 XFREE(exportBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12350 #endif
wolfSSL 0:d92f9d21154c 12351
wolfSSL 0:d92f9d21154c 12352 return ret;
wolfSSL 0:d92f9d21154c 12353 }
wolfSSL 0:d92f9d21154c 12354 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 12355
wolfSSL 0:d92f9d21154c 12356 #if !defined(NO_DH) && !defined(NO_RSA)
wolfSSL 0:d92f9d21154c 12357 if (ssl->specs.kea == diffie_hellman_kea) {
wolfSSL 0:d92f9d21154c 12358 byte *output;
wolfSSL 0:d92f9d21154c 12359 word32 length = 0, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 12360 int sendSz;
wolfSSL 0:d92f9d21154c 12361 word32 sigSz = 0, i = 0;
wolfSSL 0:d92f9d21154c 12362 word32 preSigSz = 0, preSigIdx = 0;
wolfSSL 0:d92f9d21154c 12363 RsaKey rsaKey;
wolfSSL 0:d92f9d21154c 12364 DhKey dhKey;
wolfSSL 0:d92f9d21154c 12365
wolfSSL 0:d92f9d21154c 12366 if (ssl->buffers.serverDH_P.buffer == NULL ||
wolfSSL 0:d92f9d21154c 12367 ssl->buffers.serverDH_G.buffer == NULL)
wolfSSL 0:d92f9d21154c 12368 return NO_DH_PARAMS;
wolfSSL 0:d92f9d21154c 12369
wolfSSL 0:d92f9d21154c 12370 if (ssl->buffers.serverDH_Pub.buffer == NULL) {
wolfSSL 0:d92f9d21154c 12371 ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
wolfSSL 0:d92f9d21154c 12372 ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
wolfSSL 0:d92f9d21154c 12373 DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 12374 if (ssl->buffers.serverDH_Pub.buffer == NULL)
wolfSSL 0:d92f9d21154c 12375 return MEMORY_E;
wolfSSL 0:d92f9d21154c 12376 }
wolfSSL 0:d92f9d21154c 12377
wolfSSL 0:d92f9d21154c 12378 if (ssl->buffers.serverDH_Priv.buffer == NULL) {
wolfSSL 0:d92f9d21154c 12379 ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
wolfSSL 0:d92f9d21154c 12380 ssl->buffers.serverDH_P.length + 2, ssl->ctx->heap,
wolfSSL 0:d92f9d21154c 12381 DYNAMIC_TYPE_DH);
wolfSSL 0:d92f9d21154c 12382 if (ssl->buffers.serverDH_Priv.buffer == NULL)
wolfSSL 0:d92f9d21154c 12383 return MEMORY_E;
wolfSSL 0:d92f9d21154c 12384 }
wolfSSL 0:d92f9d21154c 12385
wolfSSL 0:d92f9d21154c 12386 wc_InitDhKey(&dhKey);
wolfSSL 0:d92f9d21154c 12387 ret = wc_DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
wolfSSL 0:d92f9d21154c 12388 ssl->buffers.serverDH_P.length,
wolfSSL 0:d92f9d21154c 12389 ssl->buffers.serverDH_G.buffer,
wolfSSL 0:d92f9d21154c 12390 ssl->buffers.serverDH_G.length);
wolfSSL 0:d92f9d21154c 12391 if (ret == 0)
wolfSSL 0:d92f9d21154c 12392 ret = wc_DhGenerateKeyPair(&dhKey, ssl->rng,
wolfSSL 0:d92f9d21154c 12393 ssl->buffers.serverDH_Priv.buffer,
wolfSSL 0:d92f9d21154c 12394 &ssl->buffers.serverDH_Priv.length,
wolfSSL 0:d92f9d21154c 12395 ssl->buffers.serverDH_Pub.buffer,
wolfSSL 0:d92f9d21154c 12396 &ssl->buffers.serverDH_Pub.length);
wolfSSL 0:d92f9d21154c 12397 wc_FreeDhKey(&dhKey);
wolfSSL 0:d92f9d21154c 12398
wolfSSL 0:d92f9d21154c 12399 if (ret != 0) return ret;
wolfSSL 0:d92f9d21154c 12400
wolfSSL 0:d92f9d21154c 12401 length = LENGTH_SZ * 3; /* p, g, pub */
wolfSSL 0:d92f9d21154c 12402 length += ssl->buffers.serverDH_P.length +
wolfSSL 0:d92f9d21154c 12403 ssl->buffers.serverDH_G.length +
wolfSSL 0:d92f9d21154c 12404 ssl->buffers.serverDH_Pub.length;
wolfSSL 0:d92f9d21154c 12405
wolfSSL 0:d92f9d21154c 12406 preSigIdx = idx;
wolfSSL 0:d92f9d21154c 12407 preSigSz = length;
wolfSSL 0:d92f9d21154c 12408
wolfSSL 0:d92f9d21154c 12409 if (!ssl->options.usingAnon_cipher) {
wolfSSL 0:d92f9d21154c 12410 ret = wc_InitRsaKey(&rsaKey, ssl->heap);
wolfSSL 0:d92f9d21154c 12411 if (ret != 0) return ret;
wolfSSL 0:d92f9d21154c 12412
wolfSSL 0:d92f9d21154c 12413 /* sig length */
wolfSSL 0:d92f9d21154c 12414 length += LENGTH_SZ;
wolfSSL 0:d92f9d21154c 12415
wolfSSL 0:d92f9d21154c 12416 if (!ssl->buffers.key.buffer)
wolfSSL 0:d92f9d21154c 12417 return NO_PRIVATE_KEY;
wolfSSL 0:d92f9d21154c 12418
wolfSSL 0:d92f9d21154c 12419 ret = wc_RsaPrivateKeyDecode(ssl->buffers.key.buffer, &i, &rsaKey,
wolfSSL 0:d92f9d21154c 12420 ssl->buffers.key.length);
wolfSSL 0:d92f9d21154c 12421 if (ret == 0) {
wolfSSL 0:d92f9d21154c 12422 sigSz = wc_RsaEncryptSize(&rsaKey);
wolfSSL 0:d92f9d21154c 12423 length += sigSz;
wolfSSL 0:d92f9d21154c 12424 }
wolfSSL 0:d92f9d21154c 12425 else {
wolfSSL 0:d92f9d21154c 12426 wc_FreeRsaKey(&rsaKey);
wolfSSL 0:d92f9d21154c 12427 return ret;
wolfSSL 0:d92f9d21154c 12428 }
wolfSSL 0:d92f9d21154c 12429
wolfSSL 0:d92f9d21154c 12430 if (IsAtLeastTLSv1_2(ssl))
wolfSSL 0:d92f9d21154c 12431 length += HASH_SIG_SIZE;
wolfSSL 0:d92f9d21154c 12432 }
wolfSSL 0:d92f9d21154c 12433
wolfSSL 0:d92f9d21154c 12434 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 12435
wolfSSL 0:d92f9d21154c 12436 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 12437 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 12438 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 12439 idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 12440 preSigIdx = idx;
wolfSSL 0:d92f9d21154c 12441 }
wolfSSL 0:d92f9d21154c 12442 #endif
wolfSSL 0:d92f9d21154c 12443
wolfSSL 0:d92f9d21154c 12444 /* check for available size */
wolfSSL 0:d92f9d21154c 12445 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) {
wolfSSL 0:d92f9d21154c 12446 if (!ssl->options.usingAnon_cipher)
wolfSSL 0:d92f9d21154c 12447 wc_FreeRsaKey(&rsaKey);
wolfSSL 0:d92f9d21154c 12448 return ret;
wolfSSL 0:d92f9d21154c 12449 }
wolfSSL 0:d92f9d21154c 12450
wolfSSL 0:d92f9d21154c 12451 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 12452 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 12453 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 12454
wolfSSL 0:d92f9d21154c 12455 AddHeaders(output, length, server_key_exchange, ssl);
wolfSSL 0:d92f9d21154c 12456
wolfSSL 0:d92f9d21154c 12457 /* add p, g, pub */
wolfSSL 0:d92f9d21154c 12458 c16toa((word16)ssl->buffers.serverDH_P.length, output + idx);
wolfSSL 0:d92f9d21154c 12459 idx += LENGTH_SZ;
wolfSSL 0:d92f9d21154c 12460 XMEMCPY(output + idx, ssl->buffers.serverDH_P.buffer,
wolfSSL 0:d92f9d21154c 12461 ssl->buffers.serverDH_P.length);
wolfSSL 0:d92f9d21154c 12462 idx += ssl->buffers.serverDH_P.length;
wolfSSL 0:d92f9d21154c 12463
wolfSSL 0:d92f9d21154c 12464 /* g */
wolfSSL 0:d92f9d21154c 12465 c16toa((word16)ssl->buffers.serverDH_G.length, output + idx);
wolfSSL 0:d92f9d21154c 12466 idx += LENGTH_SZ;
wolfSSL 0:d92f9d21154c 12467 XMEMCPY(output + idx, ssl->buffers.serverDH_G.buffer,
wolfSSL 0:d92f9d21154c 12468 ssl->buffers.serverDH_G.length);
wolfSSL 0:d92f9d21154c 12469 idx += ssl->buffers.serverDH_G.length;
wolfSSL 0:d92f9d21154c 12470
wolfSSL 0:d92f9d21154c 12471 /* pub */
wolfSSL 0:d92f9d21154c 12472 c16toa((word16)ssl->buffers.serverDH_Pub.length, output + idx);
wolfSSL 0:d92f9d21154c 12473 idx += LENGTH_SZ;
wolfSSL 0:d92f9d21154c 12474 XMEMCPY(output + idx, ssl->buffers.serverDH_Pub.buffer,
wolfSSL 0:d92f9d21154c 12475 ssl->buffers.serverDH_Pub.length);
wolfSSL 0:d92f9d21154c 12476 idx += ssl->buffers.serverDH_Pub.length;
wolfSSL 0:d92f9d21154c 12477
wolfSSL 0:d92f9d21154c 12478 #ifdef HAVE_FUZZER
wolfSSL 0:d92f9d21154c 12479 if (ssl->fuzzerCb)
wolfSSL 0:d92f9d21154c 12480 ssl->fuzzerCb(ssl, output + preSigIdx, preSigSz, FUZZ_SIGNATURE,
wolfSSL 0:d92f9d21154c 12481 ssl->fuzzerCtx);
wolfSSL 0:d92f9d21154c 12482 #endif
wolfSSL 0:d92f9d21154c 12483
wolfSSL 0:d92f9d21154c 12484 /* Add signature */
wolfSSL 0:d92f9d21154c 12485 if (!ssl->options.usingAnon_cipher) {
wolfSSL 0:d92f9d21154c 12486 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 12487 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12488 Md5* md5 = NULL;
wolfSSL 0:d92f9d21154c 12489 Sha* sha = NULL;
wolfSSL 0:d92f9d21154c 12490 #else
wolfSSL 0:d92f9d21154c 12491 Md5 md5[1];
wolfSSL 0:d92f9d21154c 12492 Sha sha[1];
wolfSSL 0:d92f9d21154c 12493 #endif
wolfSSL 0:d92f9d21154c 12494 #endif
wolfSSL 0:d92f9d21154c 12495 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12496 byte* hash = NULL;
wolfSSL 0:d92f9d21154c 12497 #else
wolfSSL 0:d92f9d21154c 12498 byte hash[FINISHED_SZ];
wolfSSL 0:d92f9d21154c 12499 #endif
wolfSSL 0:d92f9d21154c 12500 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 12501 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12502 Sha256* sha256 = NULL;
wolfSSL 0:d92f9d21154c 12503 byte* hash256 = NULL;
wolfSSL 0:d92f9d21154c 12504 #else
wolfSSL 0:d92f9d21154c 12505 Sha256 sha256[1];
wolfSSL 0:d92f9d21154c 12506 byte hash256[SHA256_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 12507 #endif
wolfSSL 0:d92f9d21154c 12508 #endif
wolfSSL 0:d92f9d21154c 12509 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 12510 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12511 Sha384* sha384 = NULL;
wolfSSL 0:d92f9d21154c 12512 byte* hash384 = NULL;
wolfSSL 0:d92f9d21154c 12513 #else
wolfSSL 0:d92f9d21154c 12514 Sha384 sha384[1];
wolfSSL 0:d92f9d21154c 12515 byte hash384[SHA384_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 12516 #endif
wolfSSL 0:d92f9d21154c 12517 #endif
wolfSSL 0:d92f9d21154c 12518 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 12519 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12520 Sha512* sha512 = NULL;
wolfSSL 0:d92f9d21154c 12521 byte* hash512 = NULL;
wolfSSL 0:d92f9d21154c 12522 #else
wolfSSL 0:d92f9d21154c 12523 Sha512 sha512[1];
wolfSSL 0:d92f9d21154c 12524 byte hash512[SHA512_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 12525 #endif
wolfSSL 0:d92f9d21154c 12526 #endif
wolfSSL 0:d92f9d21154c 12527
wolfSSL 0:d92f9d21154c 12528 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 12529 byte doMd5 = 0;
wolfSSL 0:d92f9d21154c 12530 byte doSha = 0;
wolfSSL 0:d92f9d21154c 12531 #endif
wolfSSL 0:d92f9d21154c 12532 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 12533 byte doSha256 = 0;
wolfSSL 0:d92f9d21154c 12534 #endif
wolfSSL 0:d92f9d21154c 12535 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 12536 byte doSha384 = 0;
wolfSSL 0:d92f9d21154c 12537 #endif
wolfSSL 0:d92f9d21154c 12538 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 12539 byte doSha512 = 0;
wolfSSL 0:d92f9d21154c 12540 #endif
wolfSSL 0:d92f9d21154c 12541
wolfSSL 0:d92f9d21154c 12542 /* Add hash/signature algo ID */
wolfSSL 0:d92f9d21154c 12543 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 12544 byte setHash = 0;
wolfSSL 0:d92f9d21154c 12545
wolfSSL 0:d92f9d21154c 12546 output[idx++] = ssl->suites->hashAlgo;
wolfSSL 0:d92f9d21154c 12547 output[idx++] = ssl->suites->sigAlgo;
wolfSSL 0:d92f9d21154c 12548
wolfSSL 0:d92f9d21154c 12549 switch (ssl->suites->hashAlgo) {
wolfSSL 0:d92f9d21154c 12550 case sha512_mac:
wolfSSL 0:d92f9d21154c 12551 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 12552 doSha512 = 1;
wolfSSL 0:d92f9d21154c 12553 setHash = 1;
wolfSSL 0:d92f9d21154c 12554 #endif
wolfSSL 0:d92f9d21154c 12555 break;
wolfSSL 0:d92f9d21154c 12556
wolfSSL 0:d92f9d21154c 12557 case sha384_mac:
wolfSSL 0:d92f9d21154c 12558 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 12559 doSha384 = 1;
wolfSSL 0:d92f9d21154c 12560 setHash = 1;
wolfSSL 0:d92f9d21154c 12561 #endif
wolfSSL 0:d92f9d21154c 12562 break;
wolfSSL 0:d92f9d21154c 12563
wolfSSL 0:d92f9d21154c 12564 case sha256_mac:
wolfSSL 0:d92f9d21154c 12565 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 12566 doSha256 = 1;
wolfSSL 0:d92f9d21154c 12567 setHash = 1;
wolfSSL 0:d92f9d21154c 12568 #endif
wolfSSL 0:d92f9d21154c 12569 break;
wolfSSL 0:d92f9d21154c 12570
wolfSSL 0:d92f9d21154c 12571 case sha_mac:
wolfSSL 0:d92f9d21154c 12572 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 12573 doSha = 1;
wolfSSL 0:d92f9d21154c 12574 setHash = 1;
wolfSSL 0:d92f9d21154c 12575 #endif
wolfSSL 0:d92f9d21154c 12576 break;
wolfSSL 0:d92f9d21154c 12577
wolfSSL 0:d92f9d21154c 12578 default:
wolfSSL 0:d92f9d21154c 12579 WOLFSSL_MSG("Bad hash sig algo");
wolfSSL 0:d92f9d21154c 12580 break;
wolfSSL 0:d92f9d21154c 12581 }
wolfSSL 0:d92f9d21154c 12582
wolfSSL 0:d92f9d21154c 12583 if (setHash == 0) {
wolfSSL 0:d92f9d21154c 12584 wc_FreeRsaKey(&rsaKey);
wolfSSL 0:d92f9d21154c 12585 return ALGO_ID_E;
wolfSSL 0:d92f9d21154c 12586 }
wolfSSL 0:d92f9d21154c 12587 } else {
wolfSSL 0:d92f9d21154c 12588 /* only using sha and md5 for rsa */
wolfSSL 0:d92f9d21154c 12589 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 12590 doSha = 1;
wolfSSL 0:d92f9d21154c 12591 if (ssl->suites->sigAlgo == rsa_sa_algo) {
wolfSSL 0:d92f9d21154c 12592 doMd5 = 1;
wolfSSL 0:d92f9d21154c 12593 }
wolfSSL 0:d92f9d21154c 12594 #else
wolfSSL 0:d92f9d21154c 12595 wc_FreeRsaKey(&rsaKey);
wolfSSL 0:d92f9d21154c 12596 return ALGO_ID_E;
wolfSSL 0:d92f9d21154c 12597 #endif
wolfSSL 0:d92f9d21154c 12598 }
wolfSSL 0:d92f9d21154c 12599
wolfSSL 0:d92f9d21154c 12600 /* signature size */
wolfSSL 0:d92f9d21154c 12601 c16toa((word16)sigSz, output + idx);
wolfSSL 0:d92f9d21154c 12602 idx += LENGTH_SZ;
wolfSSL 0:d92f9d21154c 12603
wolfSSL 0:d92f9d21154c 12604 /* do signature */
wolfSSL 0:d92f9d21154c 12605 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12606 hash = (byte*)XMALLOC(FINISHED_SZ, NULL,
wolfSSL 0:d92f9d21154c 12607 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12608 if (hash == NULL)
wolfSSL 0:d92f9d21154c 12609 return MEMORY_E; /* No heap commitment before this point,
wolfSSL 0:d92f9d21154c 12610 from now on, the resources are freed
wolfSSL 0:d92f9d21154c 12611 at done_b. */
wolfSSL 0:d92f9d21154c 12612 #endif
wolfSSL 0:d92f9d21154c 12613
wolfSSL 0:d92f9d21154c 12614 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 12615 /* md5 */
wolfSSL 0:d92f9d21154c 12616 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12617 if (doMd5) {
wolfSSL 0:d92f9d21154c 12618 md5 = (Md5*)XMALLOC(sizeof(Md5), NULL,
wolfSSL 0:d92f9d21154c 12619 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12620 if (md5 == NULL)
wolfSSL 0:d92f9d21154c 12621 ERROR_OUT(MEMORY_E, done_b);
wolfSSL 0:d92f9d21154c 12622 }
wolfSSL 0:d92f9d21154c 12623 #endif
wolfSSL 0:d92f9d21154c 12624 if (doMd5) {
wolfSSL 0:d92f9d21154c 12625 wc_InitMd5(md5);
wolfSSL 0:d92f9d21154c 12626 wc_Md5Update(md5, ssl->arrays->clientRandom, RAN_LEN);
wolfSSL 0:d92f9d21154c 12627 wc_Md5Update(md5, ssl->arrays->serverRandom, RAN_LEN);
wolfSSL 0:d92f9d21154c 12628 wc_Md5Update(md5, output + preSigIdx, preSigSz);
wolfSSL 0:d92f9d21154c 12629 wc_Md5Final(md5, hash);
wolfSSL 0:d92f9d21154c 12630 }
wolfSSL 0:d92f9d21154c 12631
wolfSSL 0:d92f9d21154c 12632 /* sha */
wolfSSL 0:d92f9d21154c 12633 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12634 if (doSha) {
wolfSSL 0:d92f9d21154c 12635 sha = (Sha*)XMALLOC(sizeof(Sha), NULL,
wolfSSL 0:d92f9d21154c 12636 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12637 if (sha == NULL)
wolfSSL 0:d92f9d21154c 12638 ERROR_OUT(MEMORY_E, done_b);
wolfSSL 0:d92f9d21154c 12639 }
wolfSSL 0:d92f9d21154c 12640 #endif
wolfSSL 0:d92f9d21154c 12641
wolfSSL 0:d92f9d21154c 12642 if (doSha) {
wolfSSL 0:d92f9d21154c 12643 if ((ret = wc_InitSha(sha)) != 0)
wolfSSL 0:d92f9d21154c 12644 goto done_b;
wolfSSL 0:d92f9d21154c 12645 wc_ShaUpdate(sha, ssl->arrays->clientRandom, RAN_LEN);
wolfSSL 0:d92f9d21154c 12646 wc_ShaUpdate(sha, ssl->arrays->serverRandom, RAN_LEN);
wolfSSL 0:d92f9d21154c 12647 wc_ShaUpdate(sha, output + preSigIdx, preSigSz);
wolfSSL 0:d92f9d21154c 12648 wc_ShaFinal(sha, &hash[MD5_DIGEST_SIZE]);
wolfSSL 0:d92f9d21154c 12649 }
wolfSSL 0:d92f9d21154c 12650 #endif
wolfSSL 0:d92f9d21154c 12651
wolfSSL 0:d92f9d21154c 12652 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 12653 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12654 if (doSha256) {
wolfSSL 0:d92f9d21154c 12655 sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL,
wolfSSL 0:d92f9d21154c 12656 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12657 hash256 = (byte*)XMALLOC(SHA256_DIGEST_SIZE, NULL,
wolfSSL 0:d92f9d21154c 12658 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12659 if (sha256 == NULL || hash256 == NULL)
wolfSSL 0:d92f9d21154c 12660 ERROR_OUT(MEMORY_E, done_b);
wolfSSL 0:d92f9d21154c 12661 }
wolfSSL 0:d92f9d21154c 12662 #endif
wolfSSL 0:d92f9d21154c 12663
wolfSSL 0:d92f9d21154c 12664 if (doSha256) {
wolfSSL 0:d92f9d21154c 12665 if (!(ret = wc_InitSha256(sha256))
wolfSSL 0:d92f9d21154c 12666 && !(ret = wc_Sha256Update(sha256,
wolfSSL 0:d92f9d21154c 12667 ssl->arrays->clientRandom, RAN_LEN))
wolfSSL 0:d92f9d21154c 12668 && !(ret = wc_Sha256Update(sha256,
wolfSSL 0:d92f9d21154c 12669 ssl->arrays->serverRandom, RAN_LEN))
wolfSSL 0:d92f9d21154c 12670 && !(ret = wc_Sha256Update(sha256,
wolfSSL 0:d92f9d21154c 12671 output + preSigIdx, preSigSz)))
wolfSSL 0:d92f9d21154c 12672 ret = wc_Sha256Final(sha256, hash256);
wolfSSL 0:d92f9d21154c 12673
wolfSSL 0:d92f9d21154c 12674 if (ret != 0) goto done_b;
wolfSSL 0:d92f9d21154c 12675 }
wolfSSL 0:d92f9d21154c 12676 #endif
wolfSSL 0:d92f9d21154c 12677
wolfSSL 0:d92f9d21154c 12678 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 12679 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12680 if (doSha384) {
wolfSSL 0:d92f9d21154c 12681 sha384 = (Sha384*)XMALLOC(sizeof(Sha384), NULL,
wolfSSL 0:d92f9d21154c 12682 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12683 hash384 = (byte*)XMALLOC(SHA384_DIGEST_SIZE, NULL,
wolfSSL 0:d92f9d21154c 12684 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12685 if (sha384 == NULL || hash384 == NULL)
wolfSSL 0:d92f9d21154c 12686 ERROR_OUT(MEMORY_E, done_b);
wolfSSL 0:d92f9d21154c 12687 }
wolfSSL 0:d92f9d21154c 12688 #endif
wolfSSL 0:d92f9d21154c 12689
wolfSSL 0:d92f9d21154c 12690 if (doSha384) {
wolfSSL 0:d92f9d21154c 12691 if (!(ret = wc_InitSha384(sha384))
wolfSSL 0:d92f9d21154c 12692 && !(ret = wc_Sha384Update(sha384,
wolfSSL 0:d92f9d21154c 12693 ssl->arrays->clientRandom, RAN_LEN))
wolfSSL 0:d92f9d21154c 12694 && !(ret = wc_Sha384Update(sha384,
wolfSSL 0:d92f9d21154c 12695 ssl->arrays->serverRandom, RAN_LEN))
wolfSSL 0:d92f9d21154c 12696 && !(ret = wc_Sha384Update(sha384,
wolfSSL 0:d92f9d21154c 12697 output + preSigIdx, preSigSz)))
wolfSSL 0:d92f9d21154c 12698 ret = wc_Sha384Final(sha384, hash384);
wolfSSL 0:d92f9d21154c 12699
wolfSSL 0:d92f9d21154c 12700 if (ret != 0) goto done_b;
wolfSSL 0:d92f9d21154c 12701 }
wolfSSL 0:d92f9d21154c 12702 #endif
wolfSSL 0:d92f9d21154c 12703
wolfSSL 0:d92f9d21154c 12704 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 12705 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12706 if (doSha512) {
wolfSSL 0:d92f9d21154c 12707 sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL,
wolfSSL 0:d92f9d21154c 12708 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12709 hash512 = (byte*)XMALLOC(SHA512_DIGEST_SIZE, NULL,
wolfSSL 0:d92f9d21154c 12710 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12711 if (sha512 == NULL || hash512 == NULL)
wolfSSL 0:d92f9d21154c 12712 ERROR_OUT(MEMORY_E, done_b);
wolfSSL 0:d92f9d21154c 12713 }
wolfSSL 0:d92f9d21154c 12714 #endif
wolfSSL 0:d92f9d21154c 12715
wolfSSL 0:d92f9d21154c 12716 if (doSha512) {
wolfSSL 0:d92f9d21154c 12717 if (!(ret = wc_InitSha512(sha512))
wolfSSL 0:d92f9d21154c 12718 && !(ret = wc_Sha512Update(sha512,
wolfSSL 0:d92f9d21154c 12719 ssl->arrays->clientRandom, RAN_LEN))
wolfSSL 0:d92f9d21154c 12720 && !(ret = wc_Sha512Update(sha512,
wolfSSL 0:d92f9d21154c 12721 ssl->arrays->serverRandom, RAN_LEN))
wolfSSL 0:d92f9d21154c 12722 && !(ret = wc_Sha512Update(sha512,
wolfSSL 0:d92f9d21154c 12723 output + preSigIdx, preSigSz)))
wolfSSL 0:d92f9d21154c 12724 ret = wc_Sha512Final(sha512, hash512);
wolfSSL 0:d92f9d21154c 12725
wolfSSL 0:d92f9d21154c 12726 if (ret != 0) goto done_b;
wolfSSL 0:d92f9d21154c 12727 }
wolfSSL 0:d92f9d21154c 12728 #endif
wolfSSL 0:d92f9d21154c 12729
wolfSSL 0:d92f9d21154c 12730 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 12731 if (ssl->suites->sigAlgo == rsa_sa_algo) {
wolfSSL 0:d92f9d21154c 12732 byte* signBuffer = hash;
wolfSSL 0:d92f9d21154c 12733 word32 signSz = FINISHED_SZ;
wolfSSL 0:d92f9d21154c 12734 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12735 byte* encodedSig = NULL;
wolfSSL 0:d92f9d21154c 12736 #else
wolfSSL 0:d92f9d21154c 12737 byte encodedSig[MAX_ENCODED_SIG_SZ];
wolfSSL 0:d92f9d21154c 12738 #endif
wolfSSL 0:d92f9d21154c 12739 byte doUserRsa = 0;
wolfSSL 0:d92f9d21154c 12740
wolfSSL 0:d92f9d21154c 12741 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 12742 if (ssl->ctx->RsaSignCb)
wolfSSL 0:d92f9d21154c 12743 doUserRsa = 1;
wolfSSL 0:d92f9d21154c 12744 #endif
wolfSSL 0:d92f9d21154c 12745
wolfSSL 0:d92f9d21154c 12746 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12747 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
wolfSSL 0:d92f9d21154c 12748 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12749 if (encodedSig == NULL)
wolfSSL 0:d92f9d21154c 12750 ERROR_OUT(MEMORY_E, done_b);
wolfSSL 0:d92f9d21154c 12751 #endif
wolfSSL 0:d92f9d21154c 12752
wolfSSL 0:d92f9d21154c 12753 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 12754 byte* digest = &hash[MD5_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 12755 int typeH = SHAh;
wolfSSL 0:d92f9d21154c 12756 int digestSz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 12757
wolfSSL 0:d92f9d21154c 12758 if (ssl->suites->hashAlgo == sha256_mac) {
wolfSSL 0:d92f9d21154c 12759 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 12760 digest = hash256;
wolfSSL 0:d92f9d21154c 12761 typeH = SHA256h;
wolfSSL 0:d92f9d21154c 12762 digestSz = SHA256_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 12763 #endif
wolfSSL 0:d92f9d21154c 12764 }
wolfSSL 0:d92f9d21154c 12765 else if (ssl->suites->hashAlgo == sha384_mac) {
wolfSSL 0:d92f9d21154c 12766 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 12767 digest = hash384;
wolfSSL 0:d92f9d21154c 12768 typeH = SHA384h;
wolfSSL 0:d92f9d21154c 12769 digestSz = SHA384_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 12770 #endif
wolfSSL 0:d92f9d21154c 12771 }
wolfSSL 0:d92f9d21154c 12772 else if (ssl->suites->hashAlgo == sha512_mac) {
wolfSSL 0:d92f9d21154c 12773 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 12774 digest = hash512;
wolfSSL 0:d92f9d21154c 12775 typeH = SHA512h;
wolfSSL 0:d92f9d21154c 12776 digestSz = SHA512_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 12777 #endif
wolfSSL 0:d92f9d21154c 12778 }
wolfSSL 0:d92f9d21154c 12779
wolfSSL 0:d92f9d21154c 12780 if (digest == NULL) {
wolfSSL 0:d92f9d21154c 12781 ret = ALGO_ID_E;
wolfSSL 0:d92f9d21154c 12782 } else {
wolfSSL 0:d92f9d21154c 12783 signSz = wc_EncodeSignature(encodedSig, digest,
wolfSSL 0:d92f9d21154c 12784 digestSz, typeH);
wolfSSL 0:d92f9d21154c 12785 signBuffer = encodedSig;
wolfSSL 0:d92f9d21154c 12786 }
wolfSSL 0:d92f9d21154c 12787 }
wolfSSL 0:d92f9d21154c 12788 if (doUserRsa && ret == 0) {
wolfSSL 0:d92f9d21154c 12789 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 12790 word32 ioLen = sigSz;
wolfSSL 0:d92f9d21154c 12791 ret = ssl->ctx->RsaSignCb(ssl, signBuffer, signSz,
wolfSSL 0:d92f9d21154c 12792 output + idx, &ioLen,
wolfSSL 0:d92f9d21154c 12793 ssl->buffers.key.buffer,
wolfSSL 0:d92f9d21154c 12794 ssl->buffers.key.length,
wolfSSL 0:d92f9d21154c 12795 ssl->RsaSignCtx);
wolfSSL 0:d92f9d21154c 12796 #endif
wolfSSL 0:d92f9d21154c 12797 } else if (ret == 0) {
wolfSSL 0:d92f9d21154c 12798 ret = wc_RsaSSL_Sign(signBuffer, signSz, output + idx,
wolfSSL 0:d92f9d21154c 12799 sigSz, &rsaKey, ssl->rng);
wolfSSL 0:d92f9d21154c 12800 }
wolfSSL 0:d92f9d21154c 12801
wolfSSL 0:d92f9d21154c 12802 wc_FreeRsaKey(&rsaKey);
wolfSSL 0:d92f9d21154c 12803
wolfSSL 0:d92f9d21154c 12804 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12805 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12806 #endif
wolfSSL 0:d92f9d21154c 12807 }
wolfSSL 0:d92f9d21154c 12808 #endif
wolfSSL 0:d92f9d21154c 12809
wolfSSL 0:d92f9d21154c 12810 done_b:
wolfSSL 0:d92f9d21154c 12811 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 12812 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 12813 XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12814 XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12815 #endif
wolfSSL 0:d92f9d21154c 12816 XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12817 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 12818 XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12819 XFREE(hash256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12820 #endif
wolfSSL 0:d92f9d21154c 12821 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 12822 XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12823 XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12824 #endif
wolfSSL 0:d92f9d21154c 12825 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 12826 XFREE(sha512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12827 XFREE(hash512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 12828 #endif
wolfSSL 0:d92f9d21154c 12829 #endif
wolfSSL 0:d92f9d21154c 12830
wolfSSL 0:d92f9d21154c 12831 if (ret < 0) return ret;
wolfSSL 0:d92f9d21154c 12832 }
wolfSSL 0:d92f9d21154c 12833
wolfSSL 0:d92f9d21154c 12834 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 12835 if (ssl->options.dtls)
wolfSSL 0:d92f9d21154c 12836 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 12837 return ret;
wolfSSL 0:d92f9d21154c 12838 #endif
wolfSSL 0:d92f9d21154c 12839
wolfSSL 0:d92f9d21154c 12840 if ((ret = HashOutput(ssl, output, sendSz, 0)) != 0)
wolfSSL 0:d92f9d21154c 12841 return ret;
wolfSSL 0:d92f9d21154c 12842
wolfSSL 0:d92f9d21154c 12843 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 12844 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 12845 AddPacketName("ServerKeyExchange", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 12846 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 12847 AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo,
wolfSSL 0:d92f9d21154c 12848 output, sendSz, ssl->heap);
wolfSSL 0:d92f9d21154c 12849 #endif
wolfSSL 0:d92f9d21154c 12850
wolfSSL 0:d92f9d21154c 12851 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 12852 if (ssl->options.groupMessages)
wolfSSL 0:d92f9d21154c 12853 ret = 0;
wolfSSL 0:d92f9d21154c 12854 else
wolfSSL 0:d92f9d21154c 12855 ret = SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 12856 ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE;
wolfSSL 0:d92f9d21154c 12857 }
wolfSSL 0:d92f9d21154c 12858 #endif /* NO_DH */
wolfSSL 0:d92f9d21154c 12859
wolfSSL 0:d92f9d21154c 12860 return ret;
wolfSSL 0:d92f9d21154c 12861 #undef ERROR_OUT
wolfSSL 0:d92f9d21154c 12862 }
wolfSSL 0:d92f9d21154c 12863
wolfSSL 0:d92f9d21154c 12864
wolfSSL 0:d92f9d21154c 12865 /* Make sure server cert/key are valid for this suite, true on success */
wolfSSL 0:d92f9d21154c 12866 static int VerifyServerSuite(WOLFSSL* ssl, word16 idx)
wolfSSL 0:d92f9d21154c 12867 {
wolfSSL 0:d92f9d21154c 12868 int haveRSA = !ssl->options.haveStaticECC;
wolfSSL 0:d92f9d21154c 12869 int havePSK = 0;
wolfSSL 0:d92f9d21154c 12870 byte first;
wolfSSL 0:d92f9d21154c 12871 byte second;
wolfSSL 0:d92f9d21154c 12872
wolfSSL 0:d92f9d21154c 12873 WOLFSSL_ENTER("VerifyServerSuite");
wolfSSL 0:d92f9d21154c 12874
wolfSSL 0:d92f9d21154c 12875 if (ssl->suites == NULL) {
wolfSSL 0:d92f9d21154c 12876 WOLFSSL_MSG("Suites pointer error");
wolfSSL 0:d92f9d21154c 12877 return 0;
wolfSSL 0:d92f9d21154c 12878 }
wolfSSL 0:d92f9d21154c 12879
wolfSSL 0:d92f9d21154c 12880 first = ssl->suites->suites[idx];
wolfSSL 0:d92f9d21154c 12881 second = ssl->suites->suites[idx+1];
wolfSSL 0:d92f9d21154c 12882
wolfSSL 0:d92f9d21154c 12883 #ifndef NO_PSK
wolfSSL 0:d92f9d21154c 12884 havePSK = ssl->options.havePSK;
wolfSSL 0:d92f9d21154c 12885 #endif
wolfSSL 0:d92f9d21154c 12886
wolfSSL 0:d92f9d21154c 12887 if (ssl->options.haveNTRU)
wolfSSL 0:d92f9d21154c 12888 haveRSA = 0;
wolfSSL 0:d92f9d21154c 12889
wolfSSL 0:d92f9d21154c 12890 if (CipherRequires(first, second, REQUIRES_RSA)) {
wolfSSL 0:d92f9d21154c 12891 WOLFSSL_MSG("Requires RSA");
wolfSSL 0:d92f9d21154c 12892 if (haveRSA == 0) {
wolfSSL 0:d92f9d21154c 12893 WOLFSSL_MSG("Don't have RSA");
wolfSSL 0:d92f9d21154c 12894 return 0;
wolfSSL 0:d92f9d21154c 12895 }
wolfSSL 0:d92f9d21154c 12896 }
wolfSSL 0:d92f9d21154c 12897
wolfSSL 0:d92f9d21154c 12898 if (CipherRequires(first, second, REQUIRES_DHE)) {
wolfSSL 0:d92f9d21154c 12899 WOLFSSL_MSG("Requires DHE");
wolfSSL 0:d92f9d21154c 12900 if (ssl->options.haveDH == 0) {
wolfSSL 0:d92f9d21154c 12901 WOLFSSL_MSG("Don't have DHE");
wolfSSL 0:d92f9d21154c 12902 return 0;
wolfSSL 0:d92f9d21154c 12903 }
wolfSSL 0:d92f9d21154c 12904 }
wolfSSL 0:d92f9d21154c 12905
wolfSSL 0:d92f9d21154c 12906 if (CipherRequires(first, second, REQUIRES_ECC_DSA)) {
wolfSSL 0:d92f9d21154c 12907 WOLFSSL_MSG("Requires ECCDSA");
wolfSSL 0:d92f9d21154c 12908 if (ssl->options.haveECDSAsig == 0) {
wolfSSL 0:d92f9d21154c 12909 WOLFSSL_MSG("Don't have ECCDSA");
wolfSSL 0:d92f9d21154c 12910 return 0;
wolfSSL 0:d92f9d21154c 12911 }
wolfSSL 0:d92f9d21154c 12912 }
wolfSSL 0:d92f9d21154c 12913
wolfSSL 0:d92f9d21154c 12914 if (CipherRequires(first, second, REQUIRES_ECC_STATIC)) {
wolfSSL 0:d92f9d21154c 12915 WOLFSSL_MSG("Requires static ECC");
wolfSSL 0:d92f9d21154c 12916 if (ssl->options.haveStaticECC == 0) {
wolfSSL 0:d92f9d21154c 12917 WOLFSSL_MSG("Don't have static ECC");
wolfSSL 0:d92f9d21154c 12918 return 0;
wolfSSL 0:d92f9d21154c 12919 }
wolfSSL 0:d92f9d21154c 12920 }
wolfSSL 0:d92f9d21154c 12921
wolfSSL 0:d92f9d21154c 12922 if (CipherRequires(first, second, REQUIRES_PSK)) {
wolfSSL 0:d92f9d21154c 12923 WOLFSSL_MSG("Requires PSK");
wolfSSL 0:d92f9d21154c 12924 if (havePSK == 0) {
wolfSSL 0:d92f9d21154c 12925 WOLFSSL_MSG("Don't have PSK");
wolfSSL 0:d92f9d21154c 12926 return 0;
wolfSSL 0:d92f9d21154c 12927 }
wolfSSL 0:d92f9d21154c 12928 }
wolfSSL 0:d92f9d21154c 12929
wolfSSL 0:d92f9d21154c 12930 if (CipherRequires(first, second, REQUIRES_NTRU)) {
wolfSSL 0:d92f9d21154c 12931 WOLFSSL_MSG("Requires NTRU");
wolfSSL 0:d92f9d21154c 12932 if (ssl->options.haveNTRU == 0) {
wolfSSL 0:d92f9d21154c 12933 WOLFSSL_MSG("Don't have NTRU");
wolfSSL 0:d92f9d21154c 12934 return 0;
wolfSSL 0:d92f9d21154c 12935 }
wolfSSL 0:d92f9d21154c 12936 }
wolfSSL 0:d92f9d21154c 12937
wolfSSL 0:d92f9d21154c 12938 if (CipherRequires(first, second, REQUIRES_RSA_SIG)) {
wolfSSL 0:d92f9d21154c 12939 WOLFSSL_MSG("Requires RSA Signature");
wolfSSL 0:d92f9d21154c 12940 if (ssl->options.side == WOLFSSL_SERVER_END &&
wolfSSL 0:d92f9d21154c 12941 ssl->options.haveECDSAsig == 1) {
wolfSSL 0:d92f9d21154c 12942 WOLFSSL_MSG("Don't have RSA Signature");
wolfSSL 0:d92f9d21154c 12943 return 0;
wolfSSL 0:d92f9d21154c 12944 }
wolfSSL 0:d92f9d21154c 12945 }
wolfSSL 0:d92f9d21154c 12946
wolfSSL 0:d92f9d21154c 12947 #ifdef HAVE_SUPPORTED_CURVES
wolfSSL 0:d92f9d21154c 12948 if (!TLSX_ValidateEllipticCurves(ssl, first, second)) {
wolfSSL 0:d92f9d21154c 12949 WOLFSSL_MSG("Don't have matching curves");
wolfSSL 0:d92f9d21154c 12950 return 0;
wolfSSL 0:d92f9d21154c 12951 }
wolfSSL 0:d92f9d21154c 12952 #endif
wolfSSL 0:d92f9d21154c 12953
wolfSSL 0:d92f9d21154c 12954 /* ECCDHE is always supported if ECC on */
wolfSSL 0:d92f9d21154c 12955
wolfSSL 0:d92f9d21154c 12956 return 1;
wolfSSL 0:d92f9d21154c 12957 }
wolfSSL 0:d92f9d21154c 12958
wolfSSL 0:d92f9d21154c 12959
wolfSSL 0:d92f9d21154c 12960 static int MatchSuite(WOLFSSL* ssl, Suites* peerSuites)
wolfSSL 0:d92f9d21154c 12961 {
wolfSSL 0:d92f9d21154c 12962 word16 i, j;
wolfSSL 0:d92f9d21154c 12963
wolfSSL 0:d92f9d21154c 12964 WOLFSSL_ENTER("MatchSuite");
wolfSSL 0:d92f9d21154c 12965
wolfSSL 0:d92f9d21154c 12966 /* & 0x1 equivalent % 2 */
wolfSSL 0:d92f9d21154c 12967 if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
wolfSSL 0:d92f9d21154c 12968 return MATCH_SUITE_ERROR;
wolfSSL 0:d92f9d21154c 12969
wolfSSL 0:d92f9d21154c 12970 if (ssl->suites == NULL)
wolfSSL 0:d92f9d21154c 12971 return SUITES_ERROR;
wolfSSL 0:d92f9d21154c 12972 /* start with best, if a match we are good */
wolfSSL 0:d92f9d21154c 12973 for (i = 0; i < ssl->suites->suiteSz; i += 2)
wolfSSL 0:d92f9d21154c 12974 for (j = 0; j < peerSuites->suiteSz; j += 2)
wolfSSL 0:d92f9d21154c 12975 if (ssl->suites->suites[i] == peerSuites->suites[j] &&
wolfSSL 0:d92f9d21154c 12976 ssl->suites->suites[i+1] == peerSuites->suites[j+1] ) {
wolfSSL 0:d92f9d21154c 12977
wolfSSL 0:d92f9d21154c 12978 if (VerifyServerSuite(ssl, i)) {
wolfSSL 0:d92f9d21154c 12979 int result;
wolfSSL 0:d92f9d21154c 12980 WOLFSSL_MSG("Verified suite validity");
wolfSSL 0:d92f9d21154c 12981 ssl->options.cipherSuite0 = ssl->suites->suites[i];
wolfSSL 0:d92f9d21154c 12982 ssl->options.cipherSuite = ssl->suites->suites[i+1];
wolfSSL 0:d92f9d21154c 12983 result = SetCipherSpecs(ssl);
wolfSSL 0:d92f9d21154c 12984 if (result == 0)
wolfSSL 0:d92f9d21154c 12985 PickHashSigAlgo(ssl, peerSuites->hashSigAlgo,
wolfSSL 0:d92f9d21154c 12986 peerSuites->hashSigAlgoSz);
wolfSSL 0:d92f9d21154c 12987 return result;
wolfSSL 0:d92f9d21154c 12988 }
wolfSSL 0:d92f9d21154c 12989 else {
wolfSSL 0:d92f9d21154c 12990 WOLFSSL_MSG("Could not verify suite validity, continue");
wolfSSL 0:d92f9d21154c 12991 }
wolfSSL 0:d92f9d21154c 12992 }
wolfSSL 0:d92f9d21154c 12993
wolfSSL 0:d92f9d21154c 12994 return MATCH_SUITE_ERROR;
wolfSSL 0:d92f9d21154c 12995 }
wolfSSL 0:d92f9d21154c 12996
wolfSSL 0:d92f9d21154c 12997
wolfSSL 0:d92f9d21154c 12998 #ifdef OLD_HELLO_ALLOWED
wolfSSL 0:d92f9d21154c 12999
wolfSSL 0:d92f9d21154c 13000 /* process old style client hello, deprecate? */
wolfSSL 0:d92f9d21154c 13001 int ProcessOldClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
wolfSSL 0:d92f9d21154c 13002 word32 inSz, word16 sz)
wolfSSL 0:d92f9d21154c 13003 {
wolfSSL 0:d92f9d21154c 13004 word32 idx = *inOutIdx;
wolfSSL 0:d92f9d21154c 13005 word16 sessionSz;
wolfSSL 0:d92f9d21154c 13006 word16 randomSz;
wolfSSL 0:d92f9d21154c 13007 word16 i, j;
wolfSSL 0:d92f9d21154c 13008 ProtocolVersion pv;
wolfSSL 0:d92f9d21154c 13009 Suites clSuites;
wolfSSL 0:d92f9d21154c 13010
wolfSSL 0:d92f9d21154c 13011 (void)inSz;
wolfSSL 0:d92f9d21154c 13012 WOLFSSL_MSG("Got old format client hello");
wolfSSL 0:d92f9d21154c 13013 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 13014 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 13015 AddPacketName("ClientHello", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 13016 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 13017 AddLateName("ClientHello", &ssl->timeoutInfo);
wolfSSL 0:d92f9d21154c 13018 #endif
wolfSSL 0:d92f9d21154c 13019
wolfSSL 0:d92f9d21154c 13020 /* manually hash input since different format */
wolfSSL 0:d92f9d21154c 13021 #ifndef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 13022 #ifndef NO_MD5
wolfSSL 0:d92f9d21154c 13023 wc_Md5Update(&ssl->hsHashes->hashMd5, input + idx, sz);
wolfSSL 0:d92f9d21154c 13024 #endif
wolfSSL 0:d92f9d21154c 13025 #ifndef NO_SHA
wolfSSL 0:d92f9d21154c 13026 wc_ShaUpdate(&ssl->hsHashes->hashSha, input + idx, sz);
wolfSSL 0:d92f9d21154c 13027 #endif
wolfSSL 0:d92f9d21154c 13028 #endif
wolfSSL 0:d92f9d21154c 13029 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 13030 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 13031 int shaRet = wc_Sha256Update(&ssl->hsHashes->hashSha256,
wolfSSL 0:d92f9d21154c 13032 input + idx, sz);
wolfSSL 0:d92f9d21154c 13033 if (shaRet != 0)
wolfSSL 0:d92f9d21154c 13034 return shaRet;
wolfSSL 0:d92f9d21154c 13035 }
wolfSSL 0:d92f9d21154c 13036 #endif
wolfSSL 0:d92f9d21154c 13037
wolfSSL 0:d92f9d21154c 13038 /* does this value mean client_hello? */
wolfSSL 0:d92f9d21154c 13039 idx++;
wolfSSL 0:d92f9d21154c 13040
wolfSSL 0:d92f9d21154c 13041 /* version */
wolfSSL 0:d92f9d21154c 13042 pv.major = input[idx++];
wolfSSL 0:d92f9d21154c 13043 pv.minor = input[idx++];
wolfSSL 0:d92f9d21154c 13044 ssl->chVersion = pv; /* store */
wolfSSL 0:d92f9d21154c 13045
wolfSSL 0:d92f9d21154c 13046 if (ssl->version.minor > pv.minor) {
wolfSSL 0:d92f9d21154c 13047 byte haveRSA = 0;
wolfSSL 0:d92f9d21154c 13048 byte havePSK = 0;
wolfSSL 0:d92f9d21154c 13049 if (!ssl->options.downgrade) {
wolfSSL 0:d92f9d21154c 13050 WOLFSSL_MSG("Client trying to connect with lesser version");
wolfSSL 0:d92f9d21154c 13051 return VERSION_ERROR;
wolfSSL 0:d92f9d21154c 13052 }
wolfSSL 0:d92f9d21154c 13053 if (pv.minor < ssl->options.minDowngrade) {
wolfSSL 0:d92f9d21154c 13054 WOLFSSL_MSG(" version below minimum allowed, fatal error");
wolfSSL 0:d92f9d21154c 13055 return VERSION_ERROR;
wolfSSL 0:d92f9d21154c 13056 }
wolfSSL 0:d92f9d21154c 13057 if (pv.minor == SSLv3_MINOR) {
wolfSSL 0:d92f9d21154c 13058 /* turn off tls */
wolfSSL 0:d92f9d21154c 13059 WOLFSSL_MSG(" downgrading to SSLv3");
wolfSSL 0:d92f9d21154c 13060 ssl->options.tls = 0;
wolfSSL 0:d92f9d21154c 13061 ssl->options.tls1_1 = 0;
wolfSSL 0:d92f9d21154c 13062 ssl->version.minor = SSLv3_MINOR;
wolfSSL 0:d92f9d21154c 13063 }
wolfSSL 0:d92f9d21154c 13064 else if (pv.minor == TLSv1_MINOR) {
wolfSSL 0:d92f9d21154c 13065 WOLFSSL_MSG(" downgrading to TLSv1");
wolfSSL 0:d92f9d21154c 13066 /* turn off tls 1.1+ */
wolfSSL 0:d92f9d21154c 13067 ssl->options.tls1_1 = 0;
wolfSSL 0:d92f9d21154c 13068 ssl->version.minor = TLSv1_MINOR;
wolfSSL 0:d92f9d21154c 13069 }
wolfSSL 0:d92f9d21154c 13070 else if (pv.minor == TLSv1_1_MINOR) {
wolfSSL 0:d92f9d21154c 13071 WOLFSSL_MSG(" downgrading to TLSv1.1");
wolfSSL 0:d92f9d21154c 13072 ssl->version.minor = TLSv1_1_MINOR;
wolfSSL 0:d92f9d21154c 13073 }
wolfSSL 0:d92f9d21154c 13074 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 13075 haveRSA = 1;
wolfSSL 0:d92f9d21154c 13076 #endif
wolfSSL 0:d92f9d21154c 13077 #ifndef NO_PSK
wolfSSL 0:d92f9d21154c 13078 havePSK = ssl->options.havePSK;
wolfSSL 0:d92f9d21154c 13079 #endif
wolfSSL 0:d92f9d21154c 13080
wolfSSL 0:d92f9d21154c 13081 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
wolfSSL 0:d92f9d21154c 13082 ssl->options.haveDH, ssl->options.haveNTRU,
wolfSSL 0:d92f9d21154c 13083 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
wolfSSL 0:d92f9d21154c 13084 ssl->options.side);
wolfSSL 0:d92f9d21154c 13085 }
wolfSSL 0:d92f9d21154c 13086
wolfSSL 0:d92f9d21154c 13087 /* suite size */
wolfSSL 0:d92f9d21154c 13088 ato16(&input[idx], &clSuites.suiteSz);
wolfSSL 0:d92f9d21154c 13089 idx += 2;
wolfSSL 0:d92f9d21154c 13090
wolfSSL 0:d92f9d21154c 13091 if (clSuites.suiteSz > MAX_SUITE_SZ)
wolfSSL 0:d92f9d21154c 13092 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13093 clSuites.hashSigAlgoSz = 0;
wolfSSL 0:d92f9d21154c 13094
wolfSSL 0:d92f9d21154c 13095 /* session size */
wolfSSL 0:d92f9d21154c 13096 ato16(&input[idx], &sessionSz);
wolfSSL 0:d92f9d21154c 13097 idx += 2;
wolfSSL 0:d92f9d21154c 13098
wolfSSL 0:d92f9d21154c 13099 if (sessionSz > ID_LEN)
wolfSSL 0:d92f9d21154c 13100 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13101
wolfSSL 0:d92f9d21154c 13102 /* random size */
wolfSSL 0:d92f9d21154c 13103 ato16(&input[idx], &randomSz);
wolfSSL 0:d92f9d21154c 13104 idx += 2;
wolfSSL 0:d92f9d21154c 13105
wolfSSL 0:d92f9d21154c 13106 if (randomSz > RAN_LEN)
wolfSSL 0:d92f9d21154c 13107 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13108
wolfSSL 0:d92f9d21154c 13109 /* suites */
wolfSSL 0:d92f9d21154c 13110 for (i = 0, j = 0; i < clSuites.suiteSz; i += 3) {
wolfSSL 0:d92f9d21154c 13111 byte first = input[idx++];
wolfSSL 0:d92f9d21154c 13112 if (!first) { /* implicit: skip sslv2 type */
wolfSSL 0:d92f9d21154c 13113 XMEMCPY(&clSuites.suites[j], &input[idx], 2);
wolfSSL 0:d92f9d21154c 13114 j += 2;
wolfSSL 0:d92f9d21154c 13115 }
wolfSSL 0:d92f9d21154c 13116 idx += 2;
wolfSSL 0:d92f9d21154c 13117 }
wolfSSL 0:d92f9d21154c 13118 clSuites.suiteSz = j;
wolfSSL 0:d92f9d21154c 13119
wolfSSL 0:d92f9d21154c 13120 /* session id */
wolfSSL 0:d92f9d21154c 13121 if (sessionSz) {
wolfSSL 0:d92f9d21154c 13122 XMEMCPY(ssl->arrays->sessionID, input + idx, sessionSz);
wolfSSL 0:d92f9d21154c 13123 ssl->arrays->sessionIDSz = (byte)sessionSz;
wolfSSL 0:d92f9d21154c 13124 idx += sessionSz;
wolfSSL 0:d92f9d21154c 13125 ssl->options.resuming = 1;
wolfSSL 0:d92f9d21154c 13126 }
wolfSSL 0:d92f9d21154c 13127
wolfSSL 0:d92f9d21154c 13128 /* random */
wolfSSL 0:d92f9d21154c 13129 if (randomSz < RAN_LEN)
wolfSSL 0:d92f9d21154c 13130 XMEMSET(ssl->arrays->clientRandom, 0, RAN_LEN - randomSz);
wolfSSL 0:d92f9d21154c 13131 XMEMCPY(&ssl->arrays->clientRandom[RAN_LEN - randomSz], input + idx,
wolfSSL 0:d92f9d21154c 13132 randomSz);
wolfSSL 0:d92f9d21154c 13133 idx += randomSz;
wolfSSL 0:d92f9d21154c 13134
wolfSSL 0:d92f9d21154c 13135 if (ssl->options.usingCompression)
wolfSSL 0:d92f9d21154c 13136 ssl->options.usingCompression = 0; /* turn off */
wolfSSL 0:d92f9d21154c 13137
wolfSSL 0:d92f9d21154c 13138 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
wolfSSL 0:d92f9d21154c 13139 *inOutIdx = idx;
wolfSSL 0:d92f9d21154c 13140
wolfSSL 0:d92f9d21154c 13141 ssl->options.haveSessionId = 1;
wolfSSL 0:d92f9d21154c 13142 /* DoClientHello uses same resume code */
wolfSSL 0:d92f9d21154c 13143 if (ssl->options.resuming) { /* let's try */
wolfSSL 0:d92f9d21154c 13144 int ret = -1;
wolfSSL 0:d92f9d21154c 13145 WOLFSSL_SESSION* session = GetSession(ssl,
wolfSSL 0:d92f9d21154c 13146 ssl->arrays->masterSecret);
wolfSSL 0:d92f9d21154c 13147 #ifdef HAVE_SESSION_TICKET
wolfSSL 0:d92f9d21154c 13148 if (ssl->options.useTicket == 1) {
wolfSSL 0:d92f9d21154c 13149 session = &ssl->session;
wolfSSL 0:d92f9d21154c 13150 }
wolfSSL 0:d92f9d21154c 13151 #endif
wolfSSL 0:d92f9d21154c 13152
wolfSSL 0:d92f9d21154c 13153 if (!session) {
wolfSSL 0:d92f9d21154c 13154 WOLFSSL_MSG("Session lookup for resume failed");
wolfSSL 0:d92f9d21154c 13155 ssl->options.resuming = 0;
wolfSSL 0:d92f9d21154c 13156 } else {
wolfSSL 0:d92f9d21154c 13157 if (MatchSuite(ssl, &clSuites) < 0) {
wolfSSL 0:d92f9d21154c 13158 WOLFSSL_MSG("Unsupported cipher suite, OldClientHello");
wolfSSL 0:d92f9d21154c 13159 return UNSUPPORTED_SUITE;
wolfSSL 0:d92f9d21154c 13160 }
wolfSSL 0:d92f9d21154c 13161 #ifdef SESSION_CERTS
wolfSSL 0:d92f9d21154c 13162 ssl->session = *session; /* restore session certs. */
wolfSSL 0:d92f9d21154c 13163 #endif
wolfSSL 0:d92f9d21154c 13164
wolfSSL 0:d92f9d21154c 13165 ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
wolfSSL 0:d92f9d21154c 13166 RAN_LEN);
wolfSSL 0:d92f9d21154c 13167 if (ret != 0)
wolfSSL 0:d92f9d21154c 13168 return ret;
wolfSSL 0:d92f9d21154c 13169
wolfSSL 0:d92f9d21154c 13170 #ifdef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 13171 ret = DeriveTlsKeys(ssl);
wolfSSL 0:d92f9d21154c 13172 #else
wolfSSL 0:d92f9d21154c 13173 #ifndef NO_TLS
wolfSSL 0:d92f9d21154c 13174 if (ssl->options.tls)
wolfSSL 0:d92f9d21154c 13175 ret = DeriveTlsKeys(ssl);
wolfSSL 0:d92f9d21154c 13176 #endif
wolfSSL 0:d92f9d21154c 13177 if (!ssl->options.tls)
wolfSSL 0:d92f9d21154c 13178 ret = DeriveKeys(ssl);
wolfSSL 0:d92f9d21154c 13179 #endif
wolfSSL 0:d92f9d21154c 13180 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
wolfSSL 0:d92f9d21154c 13181
wolfSSL 0:d92f9d21154c 13182 return ret;
wolfSSL 0:d92f9d21154c 13183 }
wolfSSL 0:d92f9d21154c 13184 }
wolfSSL 0:d92f9d21154c 13185
wolfSSL 0:d92f9d21154c 13186 return MatchSuite(ssl, &clSuites);
wolfSSL 0:d92f9d21154c 13187 }
wolfSSL 0:d92f9d21154c 13188
wolfSSL 0:d92f9d21154c 13189 #endif /* OLD_HELLO_ALLOWED */
wolfSSL 0:d92f9d21154c 13190
wolfSSL 0:d92f9d21154c 13191
wolfSSL 0:d92f9d21154c 13192 static int DoClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
wolfSSL 0:d92f9d21154c 13193 word32 helloSz)
wolfSSL 0:d92f9d21154c 13194 {
wolfSSL 0:d92f9d21154c 13195 byte b;
wolfSSL 0:d92f9d21154c 13196 ProtocolVersion pv;
wolfSSL 0:d92f9d21154c 13197 Suites clSuites;
wolfSSL 0:d92f9d21154c 13198 word32 i = *inOutIdx;
wolfSSL 0:d92f9d21154c 13199 word32 begin = i;
wolfSSL 0:d92f9d21154c 13200
wolfSSL 0:d92f9d21154c 13201 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 13202 if (ssl->hsInfoOn) AddPacketName("ClientHello", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 13203 if (ssl->toInfoOn) AddLateName("ClientHello", &ssl->timeoutInfo);
wolfSSL 0:d92f9d21154c 13204 #endif
wolfSSL 0:d92f9d21154c 13205
wolfSSL 0:d92f9d21154c 13206 /* protocol version, random and session id length check */
wolfSSL 0:d92f9d21154c 13207 if ((i - begin) + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN > helloSz)
wolfSSL 0:d92f9d21154c 13208 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13209
wolfSSL 0:d92f9d21154c 13210 /* protocol version */
wolfSSL 0:d92f9d21154c 13211 XMEMCPY(&pv, input + i, OPAQUE16_LEN);
wolfSSL 0:d92f9d21154c 13212 ssl->chVersion = pv; /* store */
wolfSSL 0:d92f9d21154c 13213 i += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 13214
wolfSSL 0:d92f9d21154c 13215 if (ssl->version.minor > pv.minor) {
wolfSSL 0:d92f9d21154c 13216 byte haveRSA = 0;
wolfSSL 0:d92f9d21154c 13217 byte havePSK = 0;
wolfSSL 0:d92f9d21154c 13218
wolfSSL 0:d92f9d21154c 13219 if (!ssl->options.downgrade) {
wolfSSL 0:d92f9d21154c 13220 WOLFSSL_MSG("Client trying to connect with lesser version");
wolfSSL 0:d92f9d21154c 13221 return VERSION_ERROR;
wolfSSL 0:d92f9d21154c 13222 }
wolfSSL 0:d92f9d21154c 13223 if (pv.minor < ssl->options.minDowngrade) {
wolfSSL 0:d92f9d21154c 13224 WOLFSSL_MSG(" version below minimum allowed, fatal error");
wolfSSL 0:d92f9d21154c 13225 return VERSION_ERROR;
wolfSSL 0:d92f9d21154c 13226 }
wolfSSL 0:d92f9d21154c 13227
wolfSSL 0:d92f9d21154c 13228 if (pv.minor == SSLv3_MINOR) {
wolfSSL 0:d92f9d21154c 13229 /* turn off tls */
wolfSSL 0:d92f9d21154c 13230 WOLFSSL_MSG(" downgrading to SSLv3");
wolfSSL 0:d92f9d21154c 13231 ssl->options.tls = 0;
wolfSSL 0:d92f9d21154c 13232 ssl->options.tls1_1 = 0;
wolfSSL 0:d92f9d21154c 13233 ssl->version.minor = SSLv3_MINOR;
wolfSSL 0:d92f9d21154c 13234 }
wolfSSL 0:d92f9d21154c 13235 else if (pv.minor == TLSv1_MINOR) {
wolfSSL 0:d92f9d21154c 13236 /* turn off tls 1.1+ */
wolfSSL 0:d92f9d21154c 13237 WOLFSSL_MSG(" downgrading to TLSv1");
wolfSSL 0:d92f9d21154c 13238 ssl->options.tls1_1 = 0;
wolfSSL 0:d92f9d21154c 13239 ssl->version.minor = TLSv1_MINOR;
wolfSSL 0:d92f9d21154c 13240 }
wolfSSL 0:d92f9d21154c 13241 else if (pv.minor == TLSv1_1_MINOR) {
wolfSSL 0:d92f9d21154c 13242 WOLFSSL_MSG(" downgrading to TLSv1.1");
wolfSSL 0:d92f9d21154c 13243 ssl->version.minor = TLSv1_1_MINOR;
wolfSSL 0:d92f9d21154c 13244 }
wolfSSL 0:d92f9d21154c 13245 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 13246 haveRSA = 1;
wolfSSL 0:d92f9d21154c 13247 #endif
wolfSSL 0:d92f9d21154c 13248 #ifndef NO_PSK
wolfSSL 0:d92f9d21154c 13249 havePSK = ssl->options.havePSK;
wolfSSL 0:d92f9d21154c 13250 #endif
wolfSSL 0:d92f9d21154c 13251 InitSuites(ssl->suites, ssl->version, haveRSA, havePSK,
wolfSSL 0:d92f9d21154c 13252 ssl->options.haveDH, ssl->options.haveNTRU,
wolfSSL 0:d92f9d21154c 13253 ssl->options.haveECDSAsig, ssl->options.haveStaticECC,
wolfSSL 0:d92f9d21154c 13254 ssl->options.side);
wolfSSL 0:d92f9d21154c 13255 }
wolfSSL 0:d92f9d21154c 13256
wolfSSL 0:d92f9d21154c 13257 /* random */
wolfSSL 0:d92f9d21154c 13258 XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN);
wolfSSL 0:d92f9d21154c 13259 i += RAN_LEN;
wolfSSL 0:d92f9d21154c 13260
wolfSSL 0:d92f9d21154c 13261 #ifdef SHOW_SECRETS
wolfSSL 0:d92f9d21154c 13262 {
wolfSSL 0:d92f9d21154c 13263 int j;
wolfSSL 0:d92f9d21154c 13264 printf("client random: ");
wolfSSL 0:d92f9d21154c 13265 for (j = 0; j < RAN_LEN; j++)
wolfSSL 0:d92f9d21154c 13266 printf("%02x", ssl->arrays->clientRandom[j]);
wolfSSL 0:d92f9d21154c 13267 printf("\n");
wolfSSL 0:d92f9d21154c 13268 }
wolfSSL 0:d92f9d21154c 13269 #endif
wolfSSL 0:d92f9d21154c 13270
wolfSSL 0:d92f9d21154c 13271 /* session id */
wolfSSL 0:d92f9d21154c 13272 b = input[i++];
wolfSSL 0:d92f9d21154c 13273
wolfSSL 0:d92f9d21154c 13274 if (b == ID_LEN) {
wolfSSL 0:d92f9d21154c 13275 if ((i - begin) + ID_LEN > helloSz)
wolfSSL 0:d92f9d21154c 13276 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13277
wolfSSL 0:d92f9d21154c 13278 XMEMCPY(ssl->arrays->sessionID, input + i, ID_LEN);
wolfSSL 0:d92f9d21154c 13279 ssl->arrays->sessionIDSz = ID_LEN;
wolfSSL 0:d92f9d21154c 13280 i += ID_LEN;
wolfSSL 0:d92f9d21154c 13281 ssl->options.resuming = 1; /* client wants to resume */
wolfSSL 0:d92f9d21154c 13282 WOLFSSL_MSG("Client wants to resume session");
wolfSSL 0:d92f9d21154c 13283 }
wolfSSL 0:d92f9d21154c 13284 else if (b) {
wolfSSL 0:d92f9d21154c 13285 WOLFSSL_MSG("Invalid session ID size");
wolfSSL 0:d92f9d21154c 13286 return BUFFER_ERROR; /* session ID nor 0 neither 32 bytes long */
wolfSSL 0:d92f9d21154c 13287 }
wolfSSL 0:d92f9d21154c 13288
wolfSSL 0:d92f9d21154c 13289 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 13290 /* cookie */
wolfSSL 0:d92f9d21154c 13291 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 13292
wolfSSL 0:d92f9d21154c 13293 if ((i - begin) + OPAQUE8_LEN > helloSz)
wolfSSL 0:d92f9d21154c 13294 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13295
wolfSSL 0:d92f9d21154c 13296 b = input[i++];
wolfSSL 0:d92f9d21154c 13297
wolfSSL 0:d92f9d21154c 13298 if (b) {
wolfSSL 0:d92f9d21154c 13299 byte cookie[MAX_COOKIE_LEN];
wolfSSL 0:d92f9d21154c 13300
wolfSSL 0:d92f9d21154c 13301 if (b > MAX_COOKIE_LEN)
wolfSSL 0:d92f9d21154c 13302 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13303
wolfSSL 0:d92f9d21154c 13304 if ((i - begin) + b > helloSz)
wolfSSL 0:d92f9d21154c 13305 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13306
wolfSSL 0:d92f9d21154c 13307 if (ssl->ctx->CBIOCookie == NULL) {
wolfSSL 0:d92f9d21154c 13308 WOLFSSL_MSG("Your Cookie callback is null, please set");
wolfSSL 0:d92f9d21154c 13309 return COOKIE_ERROR;
wolfSSL 0:d92f9d21154c 13310 }
wolfSSL 0:d92f9d21154c 13311
wolfSSL 0:d92f9d21154c 13312 if ((ssl->ctx->CBIOCookie(ssl, cookie, COOKIE_SZ,
wolfSSL 0:d92f9d21154c 13313 ssl->IOCB_CookieCtx) != COOKIE_SZ)
wolfSSL 0:d92f9d21154c 13314 || (b != COOKIE_SZ)
wolfSSL 0:d92f9d21154c 13315 || (XMEMCMP(cookie, input + i, b) != 0)) {
wolfSSL 0:d92f9d21154c 13316 return COOKIE_ERROR;
wolfSSL 0:d92f9d21154c 13317 }
wolfSSL 0:d92f9d21154c 13318
wolfSSL 0:d92f9d21154c 13319 i += b;
wolfSSL 0:d92f9d21154c 13320 }
wolfSSL 0:d92f9d21154c 13321 }
wolfSSL 0:d92f9d21154c 13322 #endif
wolfSSL 0:d92f9d21154c 13323
wolfSSL 0:d92f9d21154c 13324 /* suites */
wolfSSL 0:d92f9d21154c 13325 if ((i - begin) + OPAQUE16_LEN > helloSz)
wolfSSL 0:d92f9d21154c 13326 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13327
wolfSSL 0:d92f9d21154c 13328 ato16(&input[i], &clSuites.suiteSz);
wolfSSL 0:d92f9d21154c 13329 i += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 13330
wolfSSL 0:d92f9d21154c 13331 /* suites and compression length check */
wolfSSL 0:d92f9d21154c 13332 if ((i - begin) + clSuites.suiteSz + OPAQUE8_LEN > helloSz)
wolfSSL 0:d92f9d21154c 13333 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13334
wolfSSL 0:d92f9d21154c 13335 if (clSuites.suiteSz > MAX_SUITE_SZ)
wolfSSL 0:d92f9d21154c 13336 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13337
wolfSSL 0:d92f9d21154c 13338 XMEMCPY(clSuites.suites, input + i, clSuites.suiteSz);
wolfSSL 0:d92f9d21154c 13339 i += clSuites.suiteSz;
wolfSSL 0:d92f9d21154c 13340 clSuites.hashSigAlgoSz = 0;
wolfSSL 0:d92f9d21154c 13341
wolfSSL 0:d92f9d21154c 13342 /* compression length */
wolfSSL 0:d92f9d21154c 13343 b = input[i++];
wolfSSL 0:d92f9d21154c 13344
wolfSSL 0:d92f9d21154c 13345 if ((i - begin) + b > helloSz)
wolfSSL 0:d92f9d21154c 13346 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13347
wolfSSL 0:d92f9d21154c 13348 if (ssl->options.usingCompression) {
wolfSSL 0:d92f9d21154c 13349 int match = 0;
wolfSSL 0:d92f9d21154c 13350
wolfSSL 0:d92f9d21154c 13351 while (b--) {
wolfSSL 0:d92f9d21154c 13352 byte comp = input[i++];
wolfSSL 0:d92f9d21154c 13353
wolfSSL 0:d92f9d21154c 13354 if (comp == ZLIB_COMPRESSION)
wolfSSL 0:d92f9d21154c 13355 match = 1;
wolfSSL 0:d92f9d21154c 13356 }
wolfSSL 0:d92f9d21154c 13357
wolfSSL 0:d92f9d21154c 13358 if (!match) {
wolfSSL 0:d92f9d21154c 13359 WOLFSSL_MSG("Not matching compression, turning off");
wolfSSL 0:d92f9d21154c 13360 ssl->options.usingCompression = 0; /* turn off */
wolfSSL 0:d92f9d21154c 13361 }
wolfSSL 0:d92f9d21154c 13362 }
wolfSSL 0:d92f9d21154c 13363 else
wolfSSL 0:d92f9d21154c 13364 i += b; /* ignore, since we're not on */
wolfSSL 0:d92f9d21154c 13365
wolfSSL 0:d92f9d21154c 13366 *inOutIdx = i;
wolfSSL 0:d92f9d21154c 13367
wolfSSL 0:d92f9d21154c 13368 /* tls extensions */
wolfSSL 0:d92f9d21154c 13369 if ((i - begin) < helloSz) {
wolfSSL 0:d92f9d21154c 13370 #ifdef HAVE_TLS_EXTENSIONS
wolfSSL 0:d92f9d21154c 13371 if (TLSX_SupportExtensions(ssl)) {
wolfSSL 0:d92f9d21154c 13372 int ret = 0;
wolfSSL 0:d92f9d21154c 13373 #else
wolfSSL 0:d92f9d21154c 13374 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 13375 #endif
wolfSSL 0:d92f9d21154c 13376 /* Process the hello extension. Skip unsupported. */
wolfSSL 0:d92f9d21154c 13377 word16 totalExtSz;
wolfSSL 0:d92f9d21154c 13378
wolfSSL 0:d92f9d21154c 13379 if ((i - begin) + OPAQUE16_LEN > helloSz)
wolfSSL 0:d92f9d21154c 13380 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13381
wolfSSL 0:d92f9d21154c 13382 ato16(&input[i], &totalExtSz);
wolfSSL 0:d92f9d21154c 13383 i += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 13384
wolfSSL 0:d92f9d21154c 13385 if ((i - begin) + totalExtSz > helloSz)
wolfSSL 0:d92f9d21154c 13386 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13387
wolfSSL 0:d92f9d21154c 13388 #ifdef HAVE_TLS_EXTENSIONS
wolfSSL 0:d92f9d21154c 13389 if ((ret = TLSX_Parse(ssl, (byte *) input + i,
wolfSSL 0:d92f9d21154c 13390 totalExtSz, 1, &clSuites)))
wolfSSL 0:d92f9d21154c 13391 return ret;
wolfSSL 0:d92f9d21154c 13392
wolfSSL 0:d92f9d21154c 13393 i += totalExtSz;
wolfSSL 0:d92f9d21154c 13394 #else
wolfSSL 0:d92f9d21154c 13395 while (totalExtSz) {
wolfSSL 0:d92f9d21154c 13396 word16 extId, extSz;
wolfSSL 0:d92f9d21154c 13397
wolfSSL 0:d92f9d21154c 13398 if (OPAQUE16_LEN + OPAQUE16_LEN > totalExtSz)
wolfSSL 0:d92f9d21154c 13399 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13400
wolfSSL 0:d92f9d21154c 13401 ato16(&input[i], &extId);
wolfSSL 0:d92f9d21154c 13402 i += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 13403 ato16(&input[i], &extSz);
wolfSSL 0:d92f9d21154c 13404 i += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 13405
wolfSSL 0:d92f9d21154c 13406 if (OPAQUE16_LEN + OPAQUE16_LEN + extSz > totalExtSz)
wolfSSL 0:d92f9d21154c 13407 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13408
wolfSSL 0:d92f9d21154c 13409 if (extId == HELLO_EXT_SIG_ALGO) {
wolfSSL 0:d92f9d21154c 13410 ato16(&input[i], &clSuites.hashSigAlgoSz);
wolfSSL 0:d92f9d21154c 13411 i += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 13412
wolfSSL 0:d92f9d21154c 13413 if (OPAQUE16_LEN + clSuites.hashSigAlgoSz > extSz)
wolfSSL 0:d92f9d21154c 13414 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13415
wolfSSL 0:d92f9d21154c 13416 XMEMCPY(clSuites.hashSigAlgo, &input[i],
wolfSSL 0:d92f9d21154c 13417 min(clSuites.hashSigAlgoSz, HELLO_EXT_SIGALGO_MAX));
wolfSSL 0:d92f9d21154c 13418 i += clSuites.hashSigAlgoSz;
wolfSSL 0:d92f9d21154c 13419
wolfSSL 0:d92f9d21154c 13420 if (clSuites.hashSigAlgoSz > HELLO_EXT_SIGALGO_MAX)
wolfSSL 0:d92f9d21154c 13421 clSuites.hashSigAlgoSz = HELLO_EXT_SIGALGO_MAX;
wolfSSL 0:d92f9d21154c 13422 }
wolfSSL 0:d92f9d21154c 13423 else
wolfSSL 0:d92f9d21154c 13424 i += extSz;
wolfSSL 0:d92f9d21154c 13425
wolfSSL 0:d92f9d21154c 13426 totalExtSz -= OPAQUE16_LEN + OPAQUE16_LEN + extSz;
wolfSSL 0:d92f9d21154c 13427 }
wolfSSL 0:d92f9d21154c 13428 #endif
wolfSSL 0:d92f9d21154c 13429 *inOutIdx = i;
wolfSSL 0:d92f9d21154c 13430 }
wolfSSL 0:d92f9d21154c 13431 else
wolfSSL 0:d92f9d21154c 13432 *inOutIdx = begin + helloSz; /* skip extensions */
wolfSSL 0:d92f9d21154c 13433 }
wolfSSL 0:d92f9d21154c 13434
wolfSSL 0:d92f9d21154c 13435 ssl->options.clientState = CLIENT_HELLO_COMPLETE;
wolfSSL 0:d92f9d21154c 13436 ssl->options.haveSessionId = 1;
wolfSSL 0:d92f9d21154c 13437
wolfSSL 0:d92f9d21154c 13438 /* ProcessOld uses same resume code */
wolfSSL 0:d92f9d21154c 13439 if (ssl->options.resuming && (!ssl->options.dtls ||
wolfSSL 0:d92f9d21154c 13440 ssl->options.acceptState == HELLO_VERIFY_SENT)) { /* let's try */
wolfSSL 0:d92f9d21154c 13441 int ret = -1;
wolfSSL 0:d92f9d21154c 13442 WOLFSSL_SESSION* session = GetSession(ssl,
wolfSSL 0:d92f9d21154c 13443 ssl->arrays->masterSecret);
wolfSSL 0:d92f9d21154c 13444 #ifdef HAVE_SESSION_TICKET
wolfSSL 0:d92f9d21154c 13445 if (ssl->options.useTicket == 1) {
wolfSSL 0:d92f9d21154c 13446 session = &ssl->session;
wolfSSL 0:d92f9d21154c 13447 }
wolfSSL 0:d92f9d21154c 13448 #endif
wolfSSL 0:d92f9d21154c 13449
wolfSSL 0:d92f9d21154c 13450 if (!session) {
wolfSSL 0:d92f9d21154c 13451 WOLFSSL_MSG("Session lookup for resume failed");
wolfSSL 0:d92f9d21154c 13452 ssl->options.resuming = 0;
wolfSSL 0:d92f9d21154c 13453 }
wolfSSL 0:d92f9d21154c 13454 else {
wolfSSL 0:d92f9d21154c 13455 if (MatchSuite(ssl, &clSuites) < 0) {
wolfSSL 0:d92f9d21154c 13456 WOLFSSL_MSG("Unsupported cipher suite, ClientHello");
wolfSSL 0:d92f9d21154c 13457 return UNSUPPORTED_SUITE;
wolfSSL 0:d92f9d21154c 13458 }
wolfSSL 0:d92f9d21154c 13459 #ifdef SESSION_CERTS
wolfSSL 0:d92f9d21154c 13460 ssl->session = *session; /* restore session certs. */
wolfSSL 0:d92f9d21154c 13461 #endif
wolfSSL 0:d92f9d21154c 13462
wolfSSL 0:d92f9d21154c 13463 ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom,
wolfSSL 0:d92f9d21154c 13464 RAN_LEN);
wolfSSL 0:d92f9d21154c 13465 if (ret != 0)
wolfSSL 0:d92f9d21154c 13466 return ret;
wolfSSL 0:d92f9d21154c 13467
wolfSSL 0:d92f9d21154c 13468 #ifdef NO_OLD_TLS
wolfSSL 0:d92f9d21154c 13469 ret = DeriveTlsKeys(ssl);
wolfSSL 0:d92f9d21154c 13470 #else
wolfSSL 0:d92f9d21154c 13471 #ifndef NO_TLS
wolfSSL 0:d92f9d21154c 13472 if (ssl->options.tls)
wolfSSL 0:d92f9d21154c 13473 ret = DeriveTlsKeys(ssl);
wolfSSL 0:d92f9d21154c 13474 #endif
wolfSSL 0:d92f9d21154c 13475 if (!ssl->options.tls)
wolfSSL 0:d92f9d21154c 13476 ret = DeriveKeys(ssl);
wolfSSL 0:d92f9d21154c 13477 #endif
wolfSSL 0:d92f9d21154c 13478 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
wolfSSL 0:d92f9d21154c 13479
wolfSSL 0:d92f9d21154c 13480 return ret;
wolfSSL 0:d92f9d21154c 13481 }
wolfSSL 0:d92f9d21154c 13482 }
wolfSSL 0:d92f9d21154c 13483 return MatchSuite(ssl, &clSuites);
wolfSSL 0:d92f9d21154c 13484 }
wolfSSL 0:d92f9d21154c 13485
wolfSSL 0:d92f9d21154c 13486 #if !defined(NO_RSA) || defined(HAVE_ECC)
wolfSSL 0:d92f9d21154c 13487 static int DoCertificateVerify(WOLFSSL* ssl, byte* input, word32* inOutIdx,
wolfSSL 0:d92f9d21154c 13488 word32 size)
wolfSSL 0:d92f9d21154c 13489 {
wolfSSL 0:d92f9d21154c 13490 word16 sz = 0;
wolfSSL 0:d92f9d21154c 13491 int ret = VERIFY_CERT_ERROR; /* start in error state */
wolfSSL 0:d92f9d21154c 13492 byte hashAlgo = sha_mac;
wolfSSL 0:d92f9d21154c 13493 byte sigAlgo = anonymous_sa_algo;
wolfSSL 0:d92f9d21154c 13494 word32 begin = *inOutIdx;
wolfSSL 0:d92f9d21154c 13495
wolfSSL 0:d92f9d21154c 13496 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 13497 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 13498 AddPacketName("CertificateVerify", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 13499 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 13500 AddLateName("CertificateVerify", &ssl->timeoutInfo);
wolfSSL 0:d92f9d21154c 13501 #endif
wolfSSL 0:d92f9d21154c 13502
wolfSSL 0:d92f9d21154c 13503
wolfSSL 0:d92f9d21154c 13504 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 13505 if ((*inOutIdx - begin) + ENUM_LEN + ENUM_LEN > size)
wolfSSL 0:d92f9d21154c 13506 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13507
wolfSSL 0:d92f9d21154c 13508 hashAlgo = input[(*inOutIdx)++];
wolfSSL 0:d92f9d21154c 13509 sigAlgo = input[(*inOutIdx)++];
wolfSSL 0:d92f9d21154c 13510 }
wolfSSL 0:d92f9d21154c 13511
wolfSSL 0:d92f9d21154c 13512 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 13513 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13514
wolfSSL 0:d92f9d21154c 13515 ato16(input + *inOutIdx, &sz);
wolfSSL 0:d92f9d21154c 13516 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 13517
wolfSSL 0:d92f9d21154c 13518 if ((*inOutIdx - begin) + sz > size || sz > ENCRYPT_LEN)
wolfSSL 0:d92f9d21154c 13519 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 13520
wolfSSL 0:d92f9d21154c 13521 /* RSA */
wolfSSL 0:d92f9d21154c 13522 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 13523 if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) {
wolfSSL 0:d92f9d21154c 13524 byte* out = NULL;
wolfSSL 0:d92f9d21154c 13525 int outLen = 0;
wolfSSL 0:d92f9d21154c 13526 byte doUserRsa = 0;
wolfSSL 0:d92f9d21154c 13527
wolfSSL 0:d92f9d21154c 13528 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 13529 if (ssl->ctx->RsaVerifyCb)
wolfSSL 0:d92f9d21154c 13530 doUserRsa = 1;
wolfSSL 0:d92f9d21154c 13531 #endif /*HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 13532
wolfSSL 0:d92f9d21154c 13533 WOLFSSL_MSG("Doing RSA peer cert verify");
wolfSSL 0:d92f9d21154c 13534
wolfSSL 0:d92f9d21154c 13535 if (doUserRsa) {
wolfSSL 0:d92f9d21154c 13536 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 13537 outLen = ssl->ctx->RsaVerifyCb(ssl, input + *inOutIdx, sz,
wolfSSL 0:d92f9d21154c 13538 &out,
wolfSSL 0:d92f9d21154c 13539 ssl->buffers.peerRsaKey.buffer,
wolfSSL 0:d92f9d21154c 13540 ssl->buffers.peerRsaKey.length,
wolfSSL 0:d92f9d21154c 13541 ssl->RsaVerifyCtx);
wolfSSL 0:d92f9d21154c 13542 #endif /*HAVE_PK_CALLBACKS */
wolfSSL 0:d92f9d21154c 13543 }
wolfSSL 0:d92f9d21154c 13544 else {
wolfSSL 0:d92f9d21154c 13545 outLen = wc_RsaSSL_VerifyInline(input + *inOutIdx, sz, &out,
wolfSSL 0:d92f9d21154c 13546 ssl->peerRsaKey);
wolfSSL 0:d92f9d21154c 13547 }
wolfSSL 0:d92f9d21154c 13548
wolfSSL 0:d92f9d21154c 13549 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 13550 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 13551 byte* encodedSig = NULL;
wolfSSL 0:d92f9d21154c 13552 #else
wolfSSL 0:d92f9d21154c 13553 byte encodedSig[MAX_ENCODED_SIG_SZ];
wolfSSL 0:d92f9d21154c 13554 #endif
wolfSSL 0:d92f9d21154c 13555 word32 sigSz;
wolfSSL 0:d92f9d21154c 13556 byte* digest = ssl->hsHashes->certHashes.sha;
wolfSSL 0:d92f9d21154c 13557 int typeH = SHAh;
wolfSSL 0:d92f9d21154c 13558 int digestSz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 13559
wolfSSL 0:d92f9d21154c 13560 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 13561 encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL,
wolfSSL 0:d92f9d21154c 13562 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 13563 if (encodedSig == NULL)
wolfSSL 0:d92f9d21154c 13564 return MEMORY_E;
wolfSSL 0:d92f9d21154c 13565 #endif
wolfSSL 0:d92f9d21154c 13566
wolfSSL 0:d92f9d21154c 13567 if (sigAlgo != rsa_sa_algo) {
wolfSSL 0:d92f9d21154c 13568 WOLFSSL_MSG("Oops, peer sent RSA key but not in verify");
wolfSSL 0:d92f9d21154c 13569 }
wolfSSL 0:d92f9d21154c 13570
wolfSSL 0:d92f9d21154c 13571 if (hashAlgo == sha256_mac) {
wolfSSL 0:d92f9d21154c 13572 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 13573 digest = ssl->hsHashes->certHashes.sha256;
wolfSSL 0:d92f9d21154c 13574 typeH = SHA256h;
wolfSSL 0:d92f9d21154c 13575 digestSz = SHA256_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 13576 #endif
wolfSSL 0:d92f9d21154c 13577 }
wolfSSL 0:d92f9d21154c 13578 else if (hashAlgo == sha384_mac) {
wolfSSL 0:d92f9d21154c 13579 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 13580 digest = ssl->hsHashes->certHashes.sha384;
wolfSSL 0:d92f9d21154c 13581 typeH = SHA384h;
wolfSSL 0:d92f9d21154c 13582 digestSz = SHA384_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 13583 #endif
wolfSSL 0:d92f9d21154c 13584 }
wolfSSL 0:d92f9d21154c 13585 else if (hashAlgo == sha512_mac) {
wolfSSL 0:d92f9d21154c 13586 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 13587 digest = ssl->hsHashes->certHashes.sha512;
wolfSSL 0:d92f9d21154c 13588 typeH = SHA512h;
wolfSSL 0:d92f9d21154c 13589 digestSz = SHA512_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 13590 #endif
wolfSSL 0:d92f9d21154c 13591 }
wolfSSL 0:d92f9d21154c 13592
wolfSSL 0:d92f9d21154c 13593 sigSz = wc_EncodeSignature(encodedSig, digest, digestSz, typeH);
wolfSSL 0:d92f9d21154c 13594
wolfSSL 0:d92f9d21154c 13595 if (outLen == (int)sigSz && out && XMEMCMP(out, encodedSig,
wolfSSL 0:d92f9d21154c 13596 min(sigSz, MAX_ENCODED_SIG_SZ)) == 0)
wolfSSL 0:d92f9d21154c 13597 ret = 0; /* verified */
wolfSSL 0:d92f9d21154c 13598
wolfSSL 0:d92f9d21154c 13599 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 13600 XFREE(encodedSig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 13601 #endif
wolfSSL 0:d92f9d21154c 13602 }
wolfSSL 0:d92f9d21154c 13603 else {
wolfSSL 0:d92f9d21154c 13604 if (outLen == FINISHED_SZ && out && XMEMCMP(out,
wolfSSL 0:d92f9d21154c 13605 &ssl->hsHashes->certHashes,
wolfSSL 0:d92f9d21154c 13606 FINISHED_SZ) == 0) {
wolfSSL 0:d92f9d21154c 13607 ret = 0; /* verified */
wolfSSL 0:d92f9d21154c 13608 }
wolfSSL 0:d92f9d21154c 13609 }
wolfSSL 0:d92f9d21154c 13610 }
wolfSSL 0:d92f9d21154c 13611 #endif
wolfSSL 0:d92f9d21154c 13612 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 13613 if (ssl->peerEccDsaKeyPresent) {
wolfSSL 0:d92f9d21154c 13614 int verify = 0;
wolfSSL 0:d92f9d21154c 13615 int err = -1;
wolfSSL 0:d92f9d21154c 13616 byte* digest = ssl->hsHashes->certHashes.sha;
wolfSSL 0:d92f9d21154c 13617 word32 digestSz = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 13618 byte doUserEcc = 0;
wolfSSL 0:d92f9d21154c 13619
wolfSSL 0:d92f9d21154c 13620 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 13621 if (ssl->ctx->EccVerifyCb)
wolfSSL 0:d92f9d21154c 13622 doUserEcc = 1;
wolfSSL 0:d92f9d21154c 13623 #endif
wolfSSL 0:d92f9d21154c 13624
wolfSSL 0:d92f9d21154c 13625 WOLFSSL_MSG("Doing ECC peer cert verify");
wolfSSL 0:d92f9d21154c 13626
wolfSSL 0:d92f9d21154c 13627 if (IsAtLeastTLSv1_2(ssl)) {
wolfSSL 0:d92f9d21154c 13628 if (sigAlgo != ecc_dsa_sa_algo) {
wolfSSL 0:d92f9d21154c 13629 WOLFSSL_MSG("Oops, peer sent ECC key but not in verify");
wolfSSL 0:d92f9d21154c 13630 }
wolfSSL 0:d92f9d21154c 13631
wolfSSL 0:d92f9d21154c 13632 if (hashAlgo == sha256_mac) {
wolfSSL 0:d92f9d21154c 13633 #ifndef NO_SHA256
wolfSSL 0:d92f9d21154c 13634 digest = ssl->hsHashes->certHashes.sha256;
wolfSSL 0:d92f9d21154c 13635 digestSz = SHA256_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 13636 #endif
wolfSSL 0:d92f9d21154c 13637 }
wolfSSL 0:d92f9d21154c 13638 else if (hashAlgo == sha384_mac) {
wolfSSL 0:d92f9d21154c 13639 #ifdef WOLFSSL_SHA384
wolfSSL 0:d92f9d21154c 13640 digest = ssl->hsHashes->certHashes.sha384;
wolfSSL 0:d92f9d21154c 13641 digestSz = SHA384_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 13642 #endif
wolfSSL 0:d92f9d21154c 13643 }
wolfSSL 0:d92f9d21154c 13644 else if (hashAlgo == sha512_mac) {
wolfSSL 0:d92f9d21154c 13645 #ifdef WOLFSSL_SHA512
wolfSSL 0:d92f9d21154c 13646 digest = ssl->hsHashes->certHashes.sha512;
wolfSSL 0:d92f9d21154c 13647 digestSz = SHA512_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 13648 #endif
wolfSSL 0:d92f9d21154c 13649 }
wolfSSL 0:d92f9d21154c 13650 }
wolfSSL 0:d92f9d21154c 13651
wolfSSL 0:d92f9d21154c 13652 if (doUserEcc) {
wolfSSL 0:d92f9d21154c 13653 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 13654 ret = ssl->ctx->EccVerifyCb(ssl, input + *inOutIdx, sz, digest,
wolfSSL 0:d92f9d21154c 13655 digestSz,
wolfSSL 0:d92f9d21154c 13656 ssl->buffers.peerEccDsaKey.buffer,
wolfSSL 0:d92f9d21154c 13657 ssl->buffers.peerEccDsaKey.length,
wolfSSL 0:d92f9d21154c 13658 &verify, ssl->EccVerifyCtx);
wolfSSL 0:d92f9d21154c 13659 #endif
wolfSSL 0:d92f9d21154c 13660 }
wolfSSL 0:d92f9d21154c 13661 else {
wolfSSL 0:d92f9d21154c 13662 err = wc_ecc_verify_hash(input + *inOutIdx, sz, digest,
wolfSSL 0:d92f9d21154c 13663 digestSz, &verify, ssl->peerEccDsaKey);
wolfSSL 0:d92f9d21154c 13664 }
wolfSSL 0:d92f9d21154c 13665
wolfSSL 0:d92f9d21154c 13666 if (err == 0 && verify == 1)
wolfSSL 0:d92f9d21154c 13667 ret = 0; /* verified */
wolfSSL 0:d92f9d21154c 13668 }
wolfSSL 0:d92f9d21154c 13669 #endif
wolfSSL 0:d92f9d21154c 13670 *inOutIdx += sz;
wolfSSL 0:d92f9d21154c 13671
wolfSSL 0:d92f9d21154c 13672 if (ret == 0)
wolfSSL 0:d92f9d21154c 13673 ssl->options.havePeerVerify = 1;
wolfSSL 0:d92f9d21154c 13674
wolfSSL 0:d92f9d21154c 13675 return ret;
wolfSSL 0:d92f9d21154c 13676 }
wolfSSL 0:d92f9d21154c 13677 #endif /* !NO_RSA || HAVE_ECC */
wolfSSL 0:d92f9d21154c 13678
wolfSSL 0:d92f9d21154c 13679 int SendServerHelloDone(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 13680 {
wolfSSL 0:d92f9d21154c 13681 byte *output;
wolfSSL 0:d92f9d21154c 13682 int sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 13683 int ret;
wolfSSL 0:d92f9d21154c 13684
wolfSSL 0:d92f9d21154c 13685 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 13686 if (ssl->options.dtls)
wolfSSL 0:d92f9d21154c 13687 sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
wolfSSL 0:d92f9d21154c 13688 #endif
wolfSSL 0:d92f9d21154c 13689 /* check for available size */
wolfSSL 0:d92f9d21154c 13690 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 13691 return ret;
wolfSSL 0:d92f9d21154c 13692
wolfSSL 0:d92f9d21154c 13693 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 13694 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 13695 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 13696
wolfSSL 0:d92f9d21154c 13697 AddHeaders(output, 0, server_hello_done, ssl);
wolfSSL 0:d92f9d21154c 13698
wolfSSL 0:d92f9d21154c 13699 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 13700 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 13701 if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 13702 return 0;
wolfSSL 0:d92f9d21154c 13703 }
wolfSSL 0:d92f9d21154c 13704 #endif
wolfSSL 0:d92f9d21154c 13705
wolfSSL 0:d92f9d21154c 13706 ret = HashOutput(ssl, output, sendSz, 0);
wolfSSL 0:d92f9d21154c 13707 if (ret != 0)
wolfSSL 0:d92f9d21154c 13708 return ret;
wolfSSL 0:d92f9d21154c 13709
wolfSSL 0:d92f9d21154c 13710 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 13711 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 13712 AddPacketName("ServerHelloDone", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 13713 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 13714 AddPacketInfo("ServerHelloDone", &ssl->timeoutInfo, output, sendSz,
wolfSSL 0:d92f9d21154c 13715 ssl->heap);
wolfSSL 0:d92f9d21154c 13716 #endif
wolfSSL 0:d92f9d21154c 13717 ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
wolfSSL 0:d92f9d21154c 13718
wolfSSL 0:d92f9d21154c 13719 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 13720
wolfSSL 0:d92f9d21154c 13721 return SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 13722 }
wolfSSL 0:d92f9d21154c 13723
wolfSSL 0:d92f9d21154c 13724
wolfSSL 0:d92f9d21154c 13725 #ifdef HAVE_SESSION_TICKET
wolfSSL 0:d92f9d21154c 13726
wolfSSL 0:d92f9d21154c 13727 #define WOLFSSL_TICKET_FIXED_SZ (WOLFSSL_TICKET_NAME_SZ + \
wolfSSL 0:d92f9d21154c 13728 WOLFSSL_TICKET_IV_SZ + WOLFSSL_TICKET_MAC_SZ + LENGTH_SZ)
wolfSSL 0:d92f9d21154c 13729 #define WOLFSSL_TICKET_ENC_SZ (SESSION_TICKET_LEN - WOLFSSL_TICKET_FIXED_SZ)
wolfSSL 0:d92f9d21154c 13730
wolfSSL 0:d92f9d21154c 13731 /* our ticket format */
wolfSSL 0:d92f9d21154c 13732 typedef struct InternalTicket {
wolfSSL 0:d92f9d21154c 13733 ProtocolVersion pv; /* version when ticket created */
wolfSSL 0:d92f9d21154c 13734 byte suite[SUITE_LEN]; /* cipher suite when created */
wolfSSL 0:d92f9d21154c 13735 byte msecret[SECRET_LEN]; /* master secret */
wolfSSL 0:d92f9d21154c 13736 word32 timestamp; /* born on */
wolfSSL 0:d92f9d21154c 13737 } InternalTicket;
wolfSSL 0:d92f9d21154c 13738
wolfSSL 0:d92f9d21154c 13739 /* fit within SESSION_TICKET_LEN */
wolfSSL 0:d92f9d21154c 13740 typedef struct ExternalTicket {
wolfSSL 0:d92f9d21154c 13741 byte key_name[WOLFSSL_TICKET_NAME_SZ]; /* key context name */
wolfSSL 0:d92f9d21154c 13742 byte iv[WOLFSSL_TICKET_IV_SZ]; /* this ticket's iv */
wolfSSL 0:d92f9d21154c 13743 byte enc_len[LENGTH_SZ]; /* encrypted length */
wolfSSL 0:d92f9d21154c 13744 byte enc_ticket[WOLFSSL_TICKET_ENC_SZ]; /* encrypted internal ticket */
wolfSSL 0:d92f9d21154c 13745 byte mac[WOLFSSL_TICKET_MAC_SZ]; /* total mac */
wolfSSL 0:d92f9d21154c 13746 /* !! if add to structure, add to TICKET_FIXED_SZ !! */
wolfSSL 0:d92f9d21154c 13747 } ExternalTicket;
wolfSSL 0:d92f9d21154c 13748
wolfSSL 0:d92f9d21154c 13749 /* create a new session ticket, 0 on success */
wolfSSL 0:d92f9d21154c 13750 static int CreateTicket(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 13751 {
wolfSSL 0:d92f9d21154c 13752 InternalTicket it;
wolfSSL 0:d92f9d21154c 13753 ExternalTicket* et = (ExternalTicket*)ssl->session.ticket;
wolfSSL 0:d92f9d21154c 13754 int encLen;
wolfSSL 0:d92f9d21154c 13755 int ret;
wolfSSL 0:d92f9d21154c 13756 byte zeros[WOLFSSL_TICKET_MAC_SZ]; /* biggest cmp size */
wolfSSL 0:d92f9d21154c 13757
wolfSSL 0:d92f9d21154c 13758 /* build internal */
wolfSSL 0:d92f9d21154c 13759 it.pv.major = ssl->version.major;
wolfSSL 0:d92f9d21154c 13760 it.pv.minor = ssl->version.minor;
wolfSSL 0:d92f9d21154c 13761
wolfSSL 0:d92f9d21154c 13762 it.suite[0] = ssl->options.cipherSuite0;
wolfSSL 0:d92f9d21154c 13763 it.suite[1] = ssl->options.cipherSuite;
wolfSSL 0:d92f9d21154c 13764
wolfSSL 0:d92f9d21154c 13765 XMEMCPY(it.msecret, ssl->arrays->masterSecret, SECRET_LEN);
wolfSSL 0:d92f9d21154c 13766 c32toa(LowResTimer(), (byte*)&it.timestamp);
wolfSSL 0:d92f9d21154c 13767
wolfSSL 0:d92f9d21154c 13768 /* build external */
wolfSSL 0:d92f9d21154c 13769 XMEMCPY(et->enc_ticket, &it, sizeof(InternalTicket));
wolfSSL 0:d92f9d21154c 13770
wolfSSL 0:d92f9d21154c 13771 /* encrypt */
wolfSSL 0:d92f9d21154c 13772 encLen = WOLFSSL_TICKET_ENC_SZ; /* max size user can use */
wolfSSL 0:d92f9d21154c 13773 ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv, et->mac, 1,
wolfSSL 0:d92f9d21154c 13774 et->enc_ticket, sizeof(InternalTicket),
wolfSSL 0:d92f9d21154c 13775 &encLen, ssl->ctx->ticketEncCtx);
wolfSSL 0:d92f9d21154c 13776 if (ret == WOLFSSL_TICKET_RET_OK) {
wolfSSL 0:d92f9d21154c 13777 if (encLen < (int)sizeof(InternalTicket) ||
wolfSSL 0:d92f9d21154c 13778 encLen > WOLFSSL_TICKET_ENC_SZ) {
wolfSSL 0:d92f9d21154c 13779 WOLFSSL_MSG("Bad user ticket encrypt size");
wolfSSL 0:d92f9d21154c 13780 return BAD_TICKET_KEY_CB_SZ;
wolfSSL 0:d92f9d21154c 13781 }
wolfSSL 0:d92f9d21154c 13782
wolfSSL 0:d92f9d21154c 13783 /* sanity checks on encrypt callback */
wolfSSL 0:d92f9d21154c 13784
wolfSSL 0:d92f9d21154c 13785 /* internal ticket can't be the same if encrypted */
wolfSSL 0:d92f9d21154c 13786 if (XMEMCMP(et->enc_ticket, &it, sizeof(InternalTicket)) == 0) {
wolfSSL 0:d92f9d21154c 13787 WOLFSSL_MSG("User ticket encrypt didn't encrypt");
wolfSSL 0:d92f9d21154c 13788 return BAD_TICKET_ENCRYPT;
wolfSSL 0:d92f9d21154c 13789 }
wolfSSL 0:d92f9d21154c 13790
wolfSSL 0:d92f9d21154c 13791 XMEMSET(zeros, 0, sizeof(zeros));
wolfSSL 0:d92f9d21154c 13792
wolfSSL 0:d92f9d21154c 13793 /* name */
wolfSSL 0:d92f9d21154c 13794 if (XMEMCMP(et->key_name, zeros, WOLFSSL_TICKET_NAME_SZ) == 0) {
wolfSSL 0:d92f9d21154c 13795 WOLFSSL_MSG("User ticket encrypt didn't set name");
wolfSSL 0:d92f9d21154c 13796 return BAD_TICKET_ENCRYPT;
wolfSSL 0:d92f9d21154c 13797 }
wolfSSL 0:d92f9d21154c 13798
wolfSSL 0:d92f9d21154c 13799 /* iv */
wolfSSL 0:d92f9d21154c 13800 if (XMEMCMP(et->iv, zeros, WOLFSSL_TICKET_IV_SZ) == 0) {
wolfSSL 0:d92f9d21154c 13801 WOLFSSL_MSG("User ticket encrypt didn't set iv");
wolfSSL 0:d92f9d21154c 13802 return BAD_TICKET_ENCRYPT;
wolfSSL 0:d92f9d21154c 13803 }
wolfSSL 0:d92f9d21154c 13804
wolfSSL 0:d92f9d21154c 13805 /* mac */
wolfSSL 0:d92f9d21154c 13806 if (XMEMCMP(et->mac, zeros, WOLFSSL_TICKET_MAC_SZ) == 0) {
wolfSSL 0:d92f9d21154c 13807 WOLFSSL_MSG("User ticket encrypt didn't set mac");
wolfSSL 0:d92f9d21154c 13808 return BAD_TICKET_ENCRYPT;
wolfSSL 0:d92f9d21154c 13809 }
wolfSSL 0:d92f9d21154c 13810
wolfSSL 0:d92f9d21154c 13811 /* set size */
wolfSSL 0:d92f9d21154c 13812 c16toa((word16)encLen, et->enc_len);
wolfSSL 0:d92f9d21154c 13813 ssl->session.ticketLen = (word16)(encLen + WOLFSSL_TICKET_FIXED_SZ);
wolfSSL 0:d92f9d21154c 13814 if (encLen < WOLFSSL_TICKET_ENC_SZ) {
wolfSSL 0:d92f9d21154c 13815 /* move mac up since whole enc buffer not used */
wolfSSL 0:d92f9d21154c 13816 XMEMMOVE(et->enc_ticket +encLen, et->mac,WOLFSSL_TICKET_MAC_SZ);
wolfSSL 0:d92f9d21154c 13817 }
wolfSSL 0:d92f9d21154c 13818 }
wolfSSL 0:d92f9d21154c 13819
wolfSSL 0:d92f9d21154c 13820 return ret;
wolfSSL 0:d92f9d21154c 13821 }
wolfSSL 0:d92f9d21154c 13822
wolfSSL 0:d92f9d21154c 13823
wolfSSL 0:d92f9d21154c 13824 /* Parse ticket sent by client, returns callback return value */
wolfSSL 0:d92f9d21154c 13825 int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len)
wolfSSL 0:d92f9d21154c 13826 {
wolfSSL 0:d92f9d21154c 13827 ExternalTicket* et;
wolfSSL 0:d92f9d21154c 13828 InternalTicket* it;
wolfSSL 0:d92f9d21154c 13829 int ret;
wolfSSL 0:d92f9d21154c 13830 int outLen;
wolfSSL 0:d92f9d21154c 13831 word16 inLen;
wolfSSL 0:d92f9d21154c 13832
wolfSSL 0:d92f9d21154c 13833 if (len > SESSION_TICKET_LEN ||
wolfSSL 0:d92f9d21154c 13834 len < (word32)(sizeof(InternalTicket) + WOLFSSL_TICKET_FIXED_SZ)) {
wolfSSL 0:d92f9d21154c 13835 return BAD_TICKET_MSG_SZ;
wolfSSL 0:d92f9d21154c 13836 }
wolfSSL 0:d92f9d21154c 13837
wolfSSL 0:d92f9d21154c 13838 et = (ExternalTicket*)input;
wolfSSL 0:d92f9d21154c 13839 it = (InternalTicket*)et->enc_ticket;
wolfSSL 0:d92f9d21154c 13840
wolfSSL 0:d92f9d21154c 13841 /* decrypt */
wolfSSL 0:d92f9d21154c 13842 ato16(et->enc_len, &inLen);
wolfSSL 0:d92f9d21154c 13843 if (inLen > (word16)(len - WOLFSSL_TICKET_FIXED_SZ)) {
wolfSSL 0:d92f9d21154c 13844 return BAD_TICKET_MSG_SZ;
wolfSSL 0:d92f9d21154c 13845 }
wolfSSL 0:d92f9d21154c 13846 outLen = inLen; /* may be reduced by user padding */
wolfSSL 0:d92f9d21154c 13847 ret = ssl->ctx->ticketEncCb(ssl, et->key_name, et->iv,
wolfSSL 0:d92f9d21154c 13848 et->enc_ticket + inLen, 0,
wolfSSL 0:d92f9d21154c 13849 et->enc_ticket, inLen, &outLen,
wolfSSL 0:d92f9d21154c 13850 ssl->ctx->ticketEncCtx);
wolfSSL 0:d92f9d21154c 13851 if (ret == WOLFSSL_TICKET_RET_FATAL || ret < 0) return ret;
wolfSSL 0:d92f9d21154c 13852 if (outLen > inLen || outLen < (int)sizeof(InternalTicket)) {
wolfSSL 0:d92f9d21154c 13853 WOLFSSL_MSG("Bad user ticket decrypt len");
wolfSSL 0:d92f9d21154c 13854 return BAD_TICKET_KEY_CB_SZ;
wolfSSL 0:d92f9d21154c 13855 }
wolfSSL 0:d92f9d21154c 13856
wolfSSL 0:d92f9d21154c 13857 /* get master secret */
wolfSSL 0:d92f9d21154c 13858 if (ret == WOLFSSL_TICKET_RET_OK || ret == WOLFSSL_TICKET_RET_CREATE)
wolfSSL 0:d92f9d21154c 13859 XMEMCPY(ssl->arrays->masterSecret, it->msecret, SECRET_LEN);
wolfSSL 0:d92f9d21154c 13860
wolfSSL 0:d92f9d21154c 13861 return ret;
wolfSSL 0:d92f9d21154c 13862 }
wolfSSL 0:d92f9d21154c 13863
wolfSSL 0:d92f9d21154c 13864
wolfSSL 0:d92f9d21154c 13865 /* send Session Ticket */
wolfSSL 0:d92f9d21154c 13866 int SendTicket(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 13867 {
wolfSSL 0:d92f9d21154c 13868 byte* output;
wolfSSL 0:d92f9d21154c 13869 int ret;
wolfSSL 0:d92f9d21154c 13870 int sendSz;
wolfSSL 0:d92f9d21154c 13871 word32 length = SESSION_HINT_SZ + LENGTH_SZ;
wolfSSL 0:d92f9d21154c 13872 word32 idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 13873
wolfSSL 0:d92f9d21154c 13874 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 13875 if (ssl->options.dtls) {
wolfSSL 0:d92f9d21154c 13876 length += DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 13877 idx += DTLS_RECORD_EXTRA;
wolfSSL 0:d92f9d21154c 13878 }
wolfSSL 0:d92f9d21154c 13879 #endif
wolfSSL 0:d92f9d21154c 13880
wolfSSL 0:d92f9d21154c 13881 if (ssl->options.createTicket) {
wolfSSL 0:d92f9d21154c 13882 ret = CreateTicket(ssl);
wolfSSL 0:d92f9d21154c 13883 if (ret != 0) return ret;
wolfSSL 0:d92f9d21154c 13884 }
wolfSSL 0:d92f9d21154c 13885
wolfSSL 0:d92f9d21154c 13886 length += ssl->session.ticketLen;
wolfSSL 0:d92f9d21154c 13887 sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ;
wolfSSL 0:d92f9d21154c 13888
wolfSSL 0:d92f9d21154c 13889 /* check for available size */
wolfSSL 0:d92f9d21154c 13890 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 13891 return ret;
wolfSSL 0:d92f9d21154c 13892
wolfSSL 0:d92f9d21154c 13893 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 13894 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 13895 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 13896
wolfSSL 0:d92f9d21154c 13897 AddHeaders(output, length, session_ticket, ssl);
wolfSSL 0:d92f9d21154c 13898
wolfSSL 0:d92f9d21154c 13899 /* hint */
wolfSSL 0:d92f9d21154c 13900 c32toa(ssl->ctx->ticketHint, output + idx);
wolfSSL 0:d92f9d21154c 13901 idx += SESSION_HINT_SZ;
wolfSSL 0:d92f9d21154c 13902
wolfSSL 0:d92f9d21154c 13903 /* length */
wolfSSL 0:d92f9d21154c 13904 c16toa(ssl->session.ticketLen, output + idx);
wolfSSL 0:d92f9d21154c 13905 idx += LENGTH_SZ;
wolfSSL 0:d92f9d21154c 13906
wolfSSL 0:d92f9d21154c 13907 /* ticket */
wolfSSL 0:d92f9d21154c 13908 XMEMCPY(output + idx, ssl->session.ticket, ssl->session.ticketLen);
wolfSSL 0:d92f9d21154c 13909 /* idx += ssl->session.ticketLen; */
wolfSSL 0:d92f9d21154c 13910
wolfSSL 0:d92f9d21154c 13911 ret = HashOutput(ssl, output, sendSz, 0);
wolfSSL 0:d92f9d21154c 13912 if (ret != 0) return ret;
wolfSSL 0:d92f9d21154c 13913 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 13914
wolfSSL 0:d92f9d21154c 13915 return SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 13916 }
wolfSSL 0:d92f9d21154c 13917
wolfSSL 0:d92f9d21154c 13918 #endif /* HAVE_SESSION_TICKET */
wolfSSL 0:d92f9d21154c 13919
wolfSSL 0:d92f9d21154c 13920
wolfSSL 0:d92f9d21154c 13921 #ifdef WOLFSSL_DTLS
wolfSSL 0:d92f9d21154c 13922 int SendHelloVerifyRequest(WOLFSSL* ssl)
wolfSSL 0:d92f9d21154c 13923 {
wolfSSL 0:d92f9d21154c 13924 byte* output;
wolfSSL 0:d92f9d21154c 13925 byte cookieSz = COOKIE_SZ;
wolfSSL 0:d92f9d21154c 13926 int length = VERSION_SZ + ENUM_LEN + cookieSz;
wolfSSL 0:d92f9d21154c 13927 int idx = DTLS_RECORD_HEADER_SZ + DTLS_HANDSHAKE_HEADER_SZ;
wolfSSL 0:d92f9d21154c 13928 int sendSz = length + idx;
wolfSSL 0:d92f9d21154c 13929 int ret;
wolfSSL 0:d92f9d21154c 13930
wolfSSL 0:d92f9d21154c 13931 /* check for available size */
wolfSSL 0:d92f9d21154c 13932 if ((ret = CheckAvailableSize(ssl, sendSz)) != 0)
wolfSSL 0:d92f9d21154c 13933 return ret;
wolfSSL 0:d92f9d21154c 13934
wolfSSL 0:d92f9d21154c 13935 /* get ouput buffer */
wolfSSL 0:d92f9d21154c 13936 output = ssl->buffers.outputBuffer.buffer +
wolfSSL 0:d92f9d21154c 13937 ssl->buffers.outputBuffer.length;
wolfSSL 0:d92f9d21154c 13938
wolfSSL 0:d92f9d21154c 13939 AddHeaders(output, length, hello_verify_request, ssl);
wolfSSL 0:d92f9d21154c 13940
wolfSSL 0:d92f9d21154c 13941 output[idx++] = ssl->chVersion.major;
wolfSSL 0:d92f9d21154c 13942 output[idx++] = ssl->chVersion.minor;
wolfSSL 0:d92f9d21154c 13943
wolfSSL 0:d92f9d21154c 13944 output[idx++] = cookieSz;
wolfSSL 0:d92f9d21154c 13945 if (ssl->ctx->CBIOCookie == NULL) {
wolfSSL 0:d92f9d21154c 13946 WOLFSSL_MSG("Your Cookie callback is null, please set");
wolfSSL 0:d92f9d21154c 13947 return COOKIE_ERROR;
wolfSSL 0:d92f9d21154c 13948 }
wolfSSL 0:d92f9d21154c 13949 if ((ret = ssl->ctx->CBIOCookie(ssl, output + idx, cookieSz,
wolfSSL 0:d92f9d21154c 13950 ssl->IOCB_CookieCtx)) < 0)
wolfSSL 0:d92f9d21154c 13951 return ret;
wolfSSL 0:d92f9d21154c 13952
wolfSSL 0:d92f9d21154c 13953 ret = HashOutput(ssl, output, sendSz, 0);
wolfSSL 0:d92f9d21154c 13954 if (ret != 0)
wolfSSL 0:d92f9d21154c 13955 return ret;
wolfSSL 0:d92f9d21154c 13956
wolfSSL 0:d92f9d21154c 13957 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 13958 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 13959 AddPacketName("HelloVerifyRequest", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 13960 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 13961 AddPacketInfo("HelloVerifyRequest", &ssl->timeoutInfo, output,
wolfSSL 0:d92f9d21154c 13962 sendSz, ssl->heap);
wolfSSL 0:d92f9d21154c 13963 #endif
wolfSSL 0:d92f9d21154c 13964 ssl->options.serverState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
wolfSSL 0:d92f9d21154c 13965
wolfSSL 0:d92f9d21154c 13966 ssl->buffers.outputBuffer.length += sendSz;
wolfSSL 0:d92f9d21154c 13967
wolfSSL 0:d92f9d21154c 13968 return SendBuffered(ssl);
wolfSSL 0:d92f9d21154c 13969 }
wolfSSL 0:d92f9d21154c 13970 #endif
wolfSSL 0:d92f9d21154c 13971
wolfSSL 0:d92f9d21154c 13972 static int DoClientKeyExchange(WOLFSSL* ssl, byte* input, word32* inOutIdx,
wolfSSL 0:d92f9d21154c 13973 word32 size)
wolfSSL 0:d92f9d21154c 13974 {
wolfSSL 0:d92f9d21154c 13975 int ret = 0;
wolfSSL 0:d92f9d21154c 13976 word32 length = 0;
wolfSSL 0:d92f9d21154c 13977 byte* out = NULL;
wolfSSL 0:d92f9d21154c 13978 word32 begin = *inOutIdx;
wolfSSL 0:d92f9d21154c 13979
wolfSSL 0:d92f9d21154c 13980 (void)length; /* shut up compiler warnings */
wolfSSL 0:d92f9d21154c 13981 (void)out;
wolfSSL 0:d92f9d21154c 13982 (void)input;
wolfSSL 0:d92f9d21154c 13983 (void)size;
wolfSSL 0:d92f9d21154c 13984 (void)begin;
wolfSSL 0:d92f9d21154c 13985
wolfSSL 0:d92f9d21154c 13986 if (ssl->options.side != WOLFSSL_SERVER_END) {
wolfSSL 0:d92f9d21154c 13987 WOLFSSL_MSG("Client received client keyexchange, attack?");
wolfSSL 0:d92f9d21154c 13988 WOLFSSL_ERROR(ssl->error = SIDE_ERROR);
wolfSSL 0:d92f9d21154c 13989 return SSL_FATAL_ERROR;
wolfSSL 0:d92f9d21154c 13990 }
wolfSSL 0:d92f9d21154c 13991
wolfSSL 0:d92f9d21154c 13992 if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) {
wolfSSL 0:d92f9d21154c 13993 WOLFSSL_MSG("Client sending keyexchange at wrong time");
wolfSSL 0:d92f9d21154c 13994 SendAlert(ssl, alert_fatal, unexpected_message);
wolfSSL 0:d92f9d21154c 13995 return OUT_OF_ORDER_E;
wolfSSL 0:d92f9d21154c 13996 }
wolfSSL 0:d92f9d21154c 13997
wolfSSL 0:d92f9d21154c 13998 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 13999 if (ssl->options.verifyPeer && ssl->options.failNoCert)
wolfSSL 0:d92f9d21154c 14000 if (!ssl->options.havePeerCert) {
wolfSSL 0:d92f9d21154c 14001 WOLFSSL_MSG("client didn't present peer cert");
wolfSSL 0:d92f9d21154c 14002 return NO_PEER_CERT;
wolfSSL 0:d92f9d21154c 14003 }
wolfSSL 0:d92f9d21154c 14004 #endif
wolfSSL 0:d92f9d21154c 14005
wolfSSL 0:d92f9d21154c 14006 #ifdef WOLFSSL_CALLBACKS
wolfSSL 0:d92f9d21154c 14007 if (ssl->hsInfoOn)
wolfSSL 0:d92f9d21154c 14008 AddPacketName("ClientKeyExchange", &ssl->handShakeInfo);
wolfSSL 0:d92f9d21154c 14009 if (ssl->toInfoOn)
wolfSSL 0:d92f9d21154c 14010 AddLateName("ClientKeyExchange", &ssl->timeoutInfo);
wolfSSL 0:d92f9d21154c 14011 #endif
wolfSSL 0:d92f9d21154c 14012
wolfSSL 0:d92f9d21154c 14013 switch (ssl->specs.kea) {
wolfSSL 0:d92f9d21154c 14014 #ifndef NO_RSA
wolfSSL 0:d92f9d21154c 14015 case rsa_kea:
wolfSSL 0:d92f9d21154c 14016 {
wolfSSL 0:d92f9d21154c 14017 word32 idx = 0;
wolfSSL 0:d92f9d21154c 14018 RsaKey key;
wolfSSL 0:d92f9d21154c 14019 byte doUserRsa = 0;
wolfSSL 0:d92f9d21154c 14020
wolfSSL 0:d92f9d21154c 14021 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 14022 if (ssl->ctx->RsaDecCb)
wolfSSL 0:d92f9d21154c 14023 doUserRsa = 1;
wolfSSL 0:d92f9d21154c 14024 #endif
wolfSSL 0:d92f9d21154c 14025
wolfSSL 0:d92f9d21154c 14026 ret = wc_InitRsaKey(&key, ssl->heap);
wolfSSL 0:d92f9d21154c 14027 if (ret != 0) return ret;
wolfSSL 0:d92f9d21154c 14028
wolfSSL 0:d92f9d21154c 14029 if (ssl->buffers.key.buffer)
wolfSSL 0:d92f9d21154c 14030 ret = wc_RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx,
wolfSSL 0:d92f9d21154c 14031 &key, ssl->buffers.key.length);
wolfSSL 0:d92f9d21154c 14032 else
wolfSSL 0:d92f9d21154c 14033 return NO_PRIVATE_KEY;
wolfSSL 0:d92f9d21154c 14034
wolfSSL 0:d92f9d21154c 14035 if (ret == 0) {
wolfSSL 0:d92f9d21154c 14036 length = wc_RsaEncryptSize(&key);
wolfSSL 0:d92f9d21154c 14037 ssl->arrays->preMasterSz = SECRET_LEN;
wolfSSL 0:d92f9d21154c 14038
wolfSSL 0:d92f9d21154c 14039 if (ssl->options.tls) {
wolfSSL 0:d92f9d21154c 14040 word16 check;
wolfSSL 0:d92f9d21154c 14041
wolfSSL 0:d92f9d21154c 14042 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 14043 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 14044
wolfSSL 0:d92f9d21154c 14045 ato16(input + *inOutIdx, &check);
wolfSSL 0:d92f9d21154c 14046 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 14047
wolfSSL 0:d92f9d21154c 14048 if ((word32) check != length) {
wolfSSL 0:d92f9d21154c 14049 WOLFSSL_MSG("RSA explicit size doesn't match");
wolfSSL 0:d92f9d21154c 14050 wc_FreeRsaKey(&key);
wolfSSL 0:d92f9d21154c 14051 return RSA_PRIVATE_ERROR;
wolfSSL 0:d92f9d21154c 14052 }
wolfSSL 0:d92f9d21154c 14053 }
wolfSSL 0:d92f9d21154c 14054
wolfSSL 0:d92f9d21154c 14055 if ((*inOutIdx - begin) + length > size) {
wolfSSL 0:d92f9d21154c 14056 WOLFSSL_MSG("RSA message too big");
wolfSSL 0:d92f9d21154c 14057 wc_FreeRsaKey(&key);
wolfSSL 0:d92f9d21154c 14058 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 14059 }
wolfSSL 0:d92f9d21154c 14060
wolfSSL 0:d92f9d21154c 14061 if (doUserRsa) {
wolfSSL 0:d92f9d21154c 14062 #ifdef HAVE_PK_CALLBACKS
wolfSSL 0:d92f9d21154c 14063 ret = ssl->ctx->RsaDecCb(ssl,
wolfSSL 0:d92f9d21154c 14064 input + *inOutIdx, length, &out,
wolfSSL 0:d92f9d21154c 14065 ssl->buffers.key.buffer,
wolfSSL 0:d92f9d21154c 14066 ssl->buffers.key.length,
wolfSSL 0:d92f9d21154c 14067 ssl->RsaDecCtx);
wolfSSL 0:d92f9d21154c 14068 #endif
wolfSSL 0:d92f9d21154c 14069 }
wolfSSL 0:d92f9d21154c 14070 else {
wolfSSL 0:d92f9d21154c 14071 ret = wc_RsaPrivateDecryptInline(input + *inOutIdx, length,
wolfSSL 0:d92f9d21154c 14072 &out, &key);
wolfSSL 0:d92f9d21154c 14073 }
wolfSSL 0:d92f9d21154c 14074
wolfSSL 0:d92f9d21154c 14075 *inOutIdx += length;
wolfSSL 0:d92f9d21154c 14076
wolfSSL 0:d92f9d21154c 14077 if (ret == SECRET_LEN) {
wolfSSL 0:d92f9d21154c 14078 XMEMCPY(ssl->arrays->preMasterSecret, out, SECRET_LEN);
wolfSSL 0:d92f9d21154c 14079 if (ssl->arrays->preMasterSecret[0] !=
wolfSSL 0:d92f9d21154c 14080 ssl->chVersion.major
wolfSSL 0:d92f9d21154c 14081 || ssl->arrays->preMasterSecret[1] !=
wolfSSL 0:d92f9d21154c 14082 ssl->chVersion.minor)
wolfSSL 0:d92f9d21154c 14083 ret = PMS_VERSION_ERROR;
wolfSSL 0:d92f9d21154c 14084 else
wolfSSL 0:d92f9d21154c 14085 ret = MakeMasterSecret(ssl);
wolfSSL 0:d92f9d21154c 14086 }
wolfSSL 0:d92f9d21154c 14087 else {
wolfSSL 0:d92f9d21154c 14088 ret = RSA_PRIVATE_ERROR;
wolfSSL 0:d92f9d21154c 14089 }
wolfSSL 0:d92f9d21154c 14090 }
wolfSSL 0:d92f9d21154c 14091
wolfSSL 0:d92f9d21154c 14092 wc_FreeRsaKey(&key);
wolfSSL 0:d92f9d21154c 14093 }
wolfSSL 0:d92f9d21154c 14094 break;
wolfSSL 0:d92f9d21154c 14095 #endif
wolfSSL 0:d92f9d21154c 14096 #ifndef NO_PSK
wolfSSL 0:d92f9d21154c 14097 case psk_kea:
wolfSSL 0:d92f9d21154c 14098 {
wolfSSL 0:d92f9d21154c 14099 byte* pms = ssl->arrays->preMasterSecret;
wolfSSL 0:d92f9d21154c 14100 word16 ci_sz;
wolfSSL 0:d92f9d21154c 14101
wolfSSL 0:d92f9d21154c 14102 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 14103 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 14104
wolfSSL 0:d92f9d21154c 14105 ato16(input + *inOutIdx, &ci_sz);
wolfSSL 0:d92f9d21154c 14106 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 14107
wolfSSL 0:d92f9d21154c 14108 if (ci_sz > MAX_PSK_ID_LEN)
wolfSSL 0:d92f9d21154c 14109 return CLIENT_ID_ERROR;
wolfSSL 0:d92f9d21154c 14110
wolfSSL 0:d92f9d21154c 14111 if ((*inOutIdx - begin) + ci_sz > size)
wolfSSL 0:d92f9d21154c 14112 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 14113
wolfSSL 0:d92f9d21154c 14114 XMEMCPY(ssl->arrays->client_identity, input + *inOutIdx, ci_sz);
wolfSSL 0:d92f9d21154c 14115 *inOutIdx += ci_sz;
wolfSSL 0:d92f9d21154c 14116
wolfSSL 0:d92f9d21154c 14117 ssl->arrays->client_identity[min(ci_sz, MAX_PSK_ID_LEN-1)] = 0;
wolfSSL 0:d92f9d21154c 14118 ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
wolfSSL 0:d92f9d21154c 14119 ssl->arrays->client_identity, ssl->arrays->psk_key,
wolfSSL 0:d92f9d21154c 14120 MAX_PSK_KEY_LEN);
wolfSSL 0:d92f9d21154c 14121
wolfSSL 0:d92f9d21154c 14122 if (ssl->arrays->psk_keySz == 0 ||
wolfSSL 0:d92f9d21154c 14123 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
wolfSSL 0:d92f9d21154c 14124 return PSK_KEY_ERROR;
wolfSSL 0:d92f9d21154c 14125
wolfSSL 0:d92f9d21154c 14126 /* make psk pre master secret */
wolfSSL 0:d92f9d21154c 14127 /* length of key + length 0s + length of key + key */
wolfSSL 0:d92f9d21154c 14128 c16toa((word16) ssl->arrays->psk_keySz, pms);
wolfSSL 0:d92f9d21154c 14129 pms += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 14130
wolfSSL 0:d92f9d21154c 14131 XMEMSET(pms, 0, ssl->arrays->psk_keySz);
wolfSSL 0:d92f9d21154c 14132 pms += ssl->arrays->psk_keySz;
wolfSSL 0:d92f9d21154c 14133
wolfSSL 0:d92f9d21154c 14134 c16toa((word16) ssl->arrays->psk_keySz, pms);
wolfSSL 0:d92f9d21154c 14135 pms += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 14136
wolfSSL 0:d92f9d21154c 14137 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
wolfSSL 0:d92f9d21154c 14138 ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4;
wolfSSL 0:d92f9d21154c 14139
wolfSSL 0:d92f9d21154c 14140 ret = MakeMasterSecret(ssl);
wolfSSL 0:d92f9d21154c 14141
wolfSSL 0:d92f9d21154c 14142 /* No further need for PSK */
wolfSSL 0:d92f9d21154c 14143 ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
wolfSSL 0:d92f9d21154c 14144 ssl->arrays->psk_keySz = 0;
wolfSSL 0:d92f9d21154c 14145 }
wolfSSL 0:d92f9d21154c 14146 break;
wolfSSL 0:d92f9d21154c 14147 #endif /* NO_PSK */
wolfSSL 0:d92f9d21154c 14148 #ifdef HAVE_NTRU
wolfSSL 0:d92f9d21154c 14149 case ntru_kea:
wolfSSL 0:d92f9d21154c 14150 {
wolfSSL 0:d92f9d21154c 14151 word16 cipherLen;
wolfSSL 0:d92f9d21154c 14152 word16 plainLen = sizeof(ssl->arrays->preMasterSecret);
wolfSSL 0:d92f9d21154c 14153
wolfSSL 0:d92f9d21154c 14154 if (!ssl->buffers.key.buffer)
wolfSSL 0:d92f9d21154c 14155 return NO_PRIVATE_KEY;
wolfSSL 0:d92f9d21154c 14156
wolfSSL 0:d92f9d21154c 14157 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 14158 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 14159
wolfSSL 0:d92f9d21154c 14160 ato16(input + *inOutIdx, &cipherLen);
wolfSSL 0:d92f9d21154c 14161 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 14162
wolfSSL 0:d92f9d21154c 14163 if (cipherLen > MAX_NTRU_ENCRYPT_SZ)
wolfSSL 0:d92f9d21154c 14164 return NTRU_KEY_ERROR;
wolfSSL 0:d92f9d21154c 14165
wolfSSL 0:d92f9d21154c 14166 if ((*inOutIdx - begin) + cipherLen > size)
wolfSSL 0:d92f9d21154c 14167 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 14168
wolfSSL 0:d92f9d21154c 14169 if (NTRU_OK != ntru_crypto_ntru_decrypt(
wolfSSL 0:d92f9d21154c 14170 (word16) ssl->buffers.key.length,
wolfSSL 0:d92f9d21154c 14171 ssl->buffers.key.buffer, cipherLen,
wolfSSL 0:d92f9d21154c 14172 input + *inOutIdx, &plainLen,
wolfSSL 0:d92f9d21154c 14173 ssl->arrays->preMasterSecret))
wolfSSL 0:d92f9d21154c 14174 return NTRU_DECRYPT_ERROR;
wolfSSL 0:d92f9d21154c 14175
wolfSSL 0:d92f9d21154c 14176 if (plainLen != SECRET_LEN)
wolfSSL 0:d92f9d21154c 14177 return NTRU_DECRYPT_ERROR;
wolfSSL 0:d92f9d21154c 14178
wolfSSL 0:d92f9d21154c 14179 *inOutIdx += cipherLen;
wolfSSL 0:d92f9d21154c 14180
wolfSSL 0:d92f9d21154c 14181 ssl->arrays->preMasterSz = plainLen;
wolfSSL 0:d92f9d21154c 14182 ret = MakeMasterSecret(ssl);
wolfSSL 0:d92f9d21154c 14183 }
wolfSSL 0:d92f9d21154c 14184 break;
wolfSSL 0:d92f9d21154c 14185 #endif /* HAVE_NTRU */
wolfSSL 0:d92f9d21154c 14186 #ifdef HAVE_ECC
wolfSSL 0:d92f9d21154c 14187 case ecc_diffie_hellman_kea:
wolfSSL 0:d92f9d21154c 14188 {
wolfSSL 0:d92f9d21154c 14189 if ((*inOutIdx - begin) + OPAQUE8_LEN > size)
wolfSSL 0:d92f9d21154c 14190 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 14191
wolfSSL 0:d92f9d21154c 14192 length = input[(*inOutIdx)++];
wolfSSL 0:d92f9d21154c 14193
wolfSSL 0:d92f9d21154c 14194 if ((*inOutIdx - begin) + length > size)
wolfSSL 0:d92f9d21154c 14195 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 14196
wolfSSL 0:d92f9d21154c 14197 if (ssl->peerEccKey == NULL) {
wolfSSL 0:d92f9d21154c 14198 /* alloc/init on demand */
wolfSSL 0:d92f9d21154c 14199 ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key),
wolfSSL 0:d92f9d21154c 14200 ssl->ctx->heap, DYNAMIC_TYPE_ECC);
wolfSSL 0:d92f9d21154c 14201 if (ssl->peerEccKey == NULL) {
wolfSSL 0:d92f9d21154c 14202 WOLFSSL_MSG("PeerEccKey Memory error");
wolfSSL 0:d92f9d21154c 14203 return MEMORY_E;
wolfSSL 0:d92f9d21154c 14204 }
wolfSSL 0:d92f9d21154c 14205 wc_ecc_init(ssl->peerEccKey);
wolfSSL 0:d92f9d21154c 14206 } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */
wolfSSL 0:d92f9d21154c 14207 wc_ecc_free(ssl->peerEccKey);
wolfSSL 0:d92f9d21154c 14208 ssl->peerEccKeyPresent = 0;
wolfSSL 0:d92f9d21154c 14209 wc_ecc_init(ssl->peerEccKey);
wolfSSL 0:d92f9d21154c 14210 }
wolfSSL 0:d92f9d21154c 14211
wolfSSL 0:d92f9d21154c 14212 if (wc_ecc_import_x963(input + *inOutIdx, length, ssl->peerEccKey))
wolfSSL 0:d92f9d21154c 14213 return ECC_PEERKEY_ERROR;
wolfSSL 0:d92f9d21154c 14214
wolfSSL 0:d92f9d21154c 14215 *inOutIdx += length;
wolfSSL 0:d92f9d21154c 14216 ssl->peerEccKeyPresent = 1;
wolfSSL 0:d92f9d21154c 14217
wolfSSL 0:d92f9d21154c 14218 length = sizeof(ssl->arrays->preMasterSecret);
wolfSSL 0:d92f9d21154c 14219
wolfSSL 0:d92f9d21154c 14220 if (ssl->specs.static_ecdh) {
wolfSSL 0:d92f9d21154c 14221 ecc_key staticKey;
wolfSSL 0:d92f9d21154c 14222 word32 i = 0;
wolfSSL 0:d92f9d21154c 14223
wolfSSL 0:d92f9d21154c 14224 wc_ecc_init(&staticKey);
wolfSSL 0:d92f9d21154c 14225 ret = wc_EccPrivateKeyDecode(ssl->buffers.key.buffer, &i,
wolfSSL 0:d92f9d21154c 14226 &staticKey, ssl->buffers.key.length);
wolfSSL 0:d92f9d21154c 14227
wolfSSL 0:d92f9d21154c 14228 if (ret == 0)
wolfSSL 0:d92f9d21154c 14229 ret = wc_ecc_shared_secret(&staticKey, ssl->peerEccKey,
wolfSSL 0:d92f9d21154c 14230 ssl->arrays->preMasterSecret, &length);
wolfSSL 0:d92f9d21154c 14231
wolfSSL 0:d92f9d21154c 14232 wc_ecc_free(&staticKey);
wolfSSL 0:d92f9d21154c 14233 }
wolfSSL 0:d92f9d21154c 14234 else {
wolfSSL 0:d92f9d21154c 14235 if (ssl->eccTempKeyPresent == 0) {
wolfSSL 0:d92f9d21154c 14236 WOLFSSL_MSG("Ecc ephemeral key not made correctly");
wolfSSL 0:d92f9d21154c 14237 ret = ECC_MAKEKEY_ERROR;
wolfSSL 0:d92f9d21154c 14238 } else {
wolfSSL 0:d92f9d21154c 14239 ret = wc_ecc_shared_secret(ssl->eccTempKey,ssl->peerEccKey,
wolfSSL 0:d92f9d21154c 14240 ssl->arrays->preMasterSecret, &length);
wolfSSL 0:d92f9d21154c 14241 }
wolfSSL 0:d92f9d21154c 14242 }
wolfSSL 0:d92f9d21154c 14243
wolfSSL 0:d92f9d21154c 14244 if (ret != 0)
wolfSSL 0:d92f9d21154c 14245 return ECC_SHARED_ERROR;
wolfSSL 0:d92f9d21154c 14246
wolfSSL 0:d92f9d21154c 14247 ssl->arrays->preMasterSz = length;
wolfSSL 0:d92f9d21154c 14248 ret = MakeMasterSecret(ssl);
wolfSSL 0:d92f9d21154c 14249 }
wolfSSL 0:d92f9d21154c 14250 break;
wolfSSL 0:d92f9d21154c 14251 #endif /* HAVE_ECC */
wolfSSL 0:d92f9d21154c 14252 #ifndef NO_DH
wolfSSL 0:d92f9d21154c 14253 case diffie_hellman_kea:
wolfSSL 0:d92f9d21154c 14254 {
wolfSSL 0:d92f9d21154c 14255 word16 clientPubSz;
wolfSSL 0:d92f9d21154c 14256 DhKey dhKey;
wolfSSL 0:d92f9d21154c 14257
wolfSSL 0:d92f9d21154c 14258 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 14259 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 14260
wolfSSL 0:d92f9d21154c 14261 ato16(input + *inOutIdx, &clientPubSz);
wolfSSL 0:d92f9d21154c 14262 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 14263
wolfSSL 0:d92f9d21154c 14264 if ((*inOutIdx - begin) + clientPubSz > size)
wolfSSL 0:d92f9d21154c 14265 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 14266
wolfSSL 0:d92f9d21154c 14267 wc_InitDhKey(&dhKey);
wolfSSL 0:d92f9d21154c 14268 ret = wc_DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
wolfSSL 0:d92f9d21154c 14269 ssl->buffers.serverDH_P.length,
wolfSSL 0:d92f9d21154c 14270 ssl->buffers.serverDH_G.buffer,
wolfSSL 0:d92f9d21154c 14271 ssl->buffers.serverDH_G.length);
wolfSSL 0:d92f9d21154c 14272 if (ret == 0)
wolfSSL 0:d92f9d21154c 14273 ret = wc_DhAgree(&dhKey, ssl->arrays->preMasterSecret,
wolfSSL 0:d92f9d21154c 14274 &ssl->arrays->preMasterSz,
wolfSSL 0:d92f9d21154c 14275 ssl->buffers.serverDH_Priv.buffer,
wolfSSL 0:d92f9d21154c 14276 ssl->buffers.serverDH_Priv.length,
wolfSSL 0:d92f9d21154c 14277 input + *inOutIdx, clientPubSz);
wolfSSL 0:d92f9d21154c 14278 wc_FreeDhKey(&dhKey);
wolfSSL 0:d92f9d21154c 14279
wolfSSL 0:d92f9d21154c 14280 *inOutIdx += clientPubSz;
wolfSSL 0:d92f9d21154c 14281
wolfSSL 0:d92f9d21154c 14282 if (ret == 0)
wolfSSL 0:d92f9d21154c 14283 ret = MakeMasterSecret(ssl);
wolfSSL 0:d92f9d21154c 14284 }
wolfSSL 0:d92f9d21154c 14285 break;
wolfSSL 0:d92f9d21154c 14286 #endif /* NO_DH */
wolfSSL 0:d92f9d21154c 14287 #if !defined(NO_DH) && !defined(NO_PSK)
wolfSSL 0:d92f9d21154c 14288 case dhe_psk_kea:
wolfSSL 0:d92f9d21154c 14289 {
wolfSSL 0:d92f9d21154c 14290 byte* pms = ssl->arrays->preMasterSecret;
wolfSSL 0:d92f9d21154c 14291 word16 clientSz;
wolfSSL 0:d92f9d21154c 14292 DhKey dhKey;
wolfSSL 0:d92f9d21154c 14293
wolfSSL 0:d92f9d21154c 14294 /* Read in the PSK hint */
wolfSSL 0:d92f9d21154c 14295 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 14296 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 14297
wolfSSL 0:d92f9d21154c 14298 ato16(input + *inOutIdx, &clientSz);
wolfSSL 0:d92f9d21154c 14299 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 14300 if (clientSz > MAX_PSK_ID_LEN)
wolfSSL 0:d92f9d21154c 14301 return CLIENT_ID_ERROR;
wolfSSL 0:d92f9d21154c 14302
wolfSSL 0:d92f9d21154c 14303 if ((*inOutIdx - begin) + clientSz > size)
wolfSSL 0:d92f9d21154c 14304 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 14305
wolfSSL 0:d92f9d21154c 14306 XMEMCPY(ssl->arrays->client_identity,
wolfSSL 0:d92f9d21154c 14307 input + *inOutIdx, clientSz);
wolfSSL 0:d92f9d21154c 14308 *inOutIdx += clientSz;
wolfSSL 0:d92f9d21154c 14309 ssl->arrays->client_identity[min(clientSz, MAX_PSK_ID_LEN-1)] =
wolfSSL 0:d92f9d21154c 14310 0;
wolfSSL 0:d92f9d21154c 14311
wolfSSL 0:d92f9d21154c 14312 /* Read in the DHE business */
wolfSSL 0:d92f9d21154c 14313 if ((*inOutIdx - begin) + OPAQUE16_LEN > size)
wolfSSL 0:d92f9d21154c 14314 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 14315
wolfSSL 0:d92f9d21154c 14316 ato16(input + *inOutIdx, &clientSz);
wolfSSL 0:d92f9d21154c 14317 *inOutIdx += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 14318
wolfSSL 0:d92f9d21154c 14319 if ((*inOutIdx - begin) + clientSz > size)
wolfSSL 0:d92f9d21154c 14320 return BUFFER_ERROR;
wolfSSL 0:d92f9d21154c 14321
wolfSSL 0:d92f9d21154c 14322 wc_InitDhKey(&dhKey);
wolfSSL 0:d92f9d21154c 14323 ret = wc_DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer,
wolfSSL 0:d92f9d21154c 14324 ssl->buffers.serverDH_P.length,
wolfSSL 0:d92f9d21154c 14325 ssl->buffers.serverDH_G.buffer,
wolfSSL 0:d92f9d21154c 14326 ssl->buffers.serverDH_G.length);
wolfSSL 0:d92f9d21154c 14327 if (ret == 0)
wolfSSL 0:d92f9d21154c 14328 ret = wc_DhAgree(&dhKey, pms + OPAQUE16_LEN,
wolfSSL 0:d92f9d21154c 14329 &ssl->arrays->preMasterSz,
wolfSSL 0:d92f9d21154c 14330 ssl->buffers.serverDH_Priv.buffer,
wolfSSL 0:d92f9d21154c 14331 ssl->buffers.serverDH_Priv.length,
wolfSSL 0:d92f9d21154c 14332 input + *inOutIdx, clientSz);
wolfSSL 0:d92f9d21154c 14333 wc_FreeDhKey(&dhKey);
wolfSSL 0:d92f9d21154c 14334
wolfSSL 0:d92f9d21154c 14335 *inOutIdx += clientSz;
wolfSSL 0:d92f9d21154c 14336 c16toa((word16)ssl->arrays->preMasterSz, pms);
wolfSSL 0:d92f9d21154c 14337 ssl->arrays->preMasterSz += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 14338 pms += ssl->arrays->preMasterSz;
wolfSSL 0:d92f9d21154c 14339
wolfSSL 0:d92f9d21154c 14340 /* Use the PSK hint to look up the PSK and add it to the
wolfSSL 0:d92f9d21154c 14341 * preMasterSecret here. */
wolfSSL 0:d92f9d21154c 14342 ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
wolfSSL 0:d92f9d21154c 14343 ssl->arrays->client_identity, ssl->arrays->psk_key,
wolfSSL 0:d92f9d21154c 14344 MAX_PSK_KEY_LEN);
wolfSSL 0:d92f9d21154c 14345
wolfSSL 0:d92f9d21154c 14346 if (ssl->arrays->psk_keySz == 0 ||
wolfSSL 0:d92f9d21154c 14347 ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
wolfSSL 0:d92f9d21154c 14348 return PSK_KEY_ERROR;
wolfSSL 0:d92f9d21154c 14349
wolfSSL 0:d92f9d21154c 14350 c16toa((word16) ssl->arrays->psk_keySz, pms);
wolfSSL 0:d92f9d21154c 14351 pms += OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 14352
wolfSSL 0:d92f9d21154c 14353 XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz);
wolfSSL 0:d92f9d21154c 14354 ssl->arrays->preMasterSz +=
wolfSSL 0:d92f9d21154c 14355 ssl->arrays->psk_keySz + OPAQUE16_LEN;
wolfSSL 0:d92f9d21154c 14356 if (ret == 0)
wolfSSL 0:d92f9d21154c 14357 ret = MakeMasterSecret(ssl);
wolfSSL 0:d92f9d21154c 14358
wolfSSL 0:d92f9d21154c 14359 /* No further need for PSK */
wolfSSL 0:d92f9d21154c 14360 ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz);
wolfSSL 0:d92f9d21154c 14361 ssl->arrays->psk_keySz = 0;
wolfSSL 0:d92f9d21154c 14362 }
wolfSSL 0:d92f9d21154c 14363 break;
wolfSSL 0:d92f9d21154c 14364 #endif /* !NO_DH && !NO_PSK */
wolfSSL 0:d92f9d21154c 14365 default:
wolfSSL 0:d92f9d21154c 14366 {
wolfSSL 0:d92f9d21154c 14367 WOLFSSL_MSG("Bad kea type");
wolfSSL 0:d92f9d21154c 14368 ret = BAD_KEA_TYPE_E;
wolfSSL 0:d92f9d21154c 14369 }
wolfSSL 0:d92f9d21154c 14370 break;
wolfSSL 0:d92f9d21154c 14371 }
wolfSSL 0:d92f9d21154c 14372
wolfSSL 0:d92f9d21154c 14373 /* No further need for PMS */
wolfSSL 0:d92f9d21154c 14374 ForceZero(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
wolfSSL 0:d92f9d21154c 14375 ssl->arrays->preMasterSz = 0;
wolfSSL 0:d92f9d21154c 14376
wolfSSL 0:d92f9d21154c 14377 if (ret == 0) {
wolfSSL 0:d92f9d21154c 14378 ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
wolfSSL 0:d92f9d21154c 14379 #ifndef NO_CERTS
wolfSSL 0:d92f9d21154c 14380 if (ssl->options.verifyPeer)
wolfSSL 0:d92f9d21154c 14381 ret = BuildCertHashes(ssl, &ssl->hsHashes->certHashes);
wolfSSL 0:d92f9d21154c 14382 #endif
wolfSSL 0:d92f9d21154c 14383 }
wolfSSL 0:d92f9d21154c 14384
wolfSSL 0:d92f9d21154c 14385 return ret;
wolfSSL 0:d92f9d21154c 14386 }
wolfSSL 0:d92f9d21154c 14387
wolfSSL 0:d92f9d21154c 14388 #endif /* NO_WOLFSSL_SERVER */
wolfSSL 0:d92f9d21154c 14389