cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

Committer:
ashleymills
Date:
Fri Apr 26 16:54:58 2013 +0000
Revision:
0:e979170e02e7
Basic operation of SSL with PSK working for cellular.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:e979170e02e7 1 /* tls.c
ashleymills 0:e979170e02e7 2 *
ashleymills 0:e979170e02e7 3 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
ashleymills 0:e979170e02e7 4 *
ashleymills 0:e979170e02e7 5 * This file is part of CyaSSL.
ashleymills 0:e979170e02e7 6 *
ashleymills 0:e979170e02e7 7 * CyaSSL is free software; you can redistribute it and/or modify
ashleymills 0:e979170e02e7 8 * it under the terms of the GNU General Public License as published by
ashleymills 0:e979170e02e7 9 * the Free Software Foundation; either version 2 of the License, or
ashleymills 0:e979170e02e7 10 * (at your option) any later version.
ashleymills 0:e979170e02e7 11 *
ashleymills 0:e979170e02e7 12 * CyaSSL is distributed in the hope that it will be useful,
ashleymills 0:e979170e02e7 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ashleymills 0:e979170e02e7 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ashleymills 0:e979170e02e7 15 * GNU General Public License for more details.
ashleymills 0:e979170e02e7 16 *
ashleymills 0:e979170e02e7 17 * You should have received a copy of the GNU General Public License
ashleymills 0:e979170e02e7 18 * along with this program; if not, write to the Free Software
ashleymills 0:e979170e02e7 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
ashleymills 0:e979170e02e7 20 */
ashleymills 0:e979170e02e7 21
ashleymills 0:e979170e02e7 22 #ifdef HAVE_CONFIG_H
ashleymills 0:e979170e02e7 23 #include <config.h>
ashleymills 0:e979170e02e7 24 #endif
ashleymills 0:e979170e02e7 25
ashleymills 0:e979170e02e7 26 #include <cyassl/ssl.h>
ashleymills 0:e979170e02e7 27 #include <cyassl/internal.h>
ashleymills 0:e979170e02e7 28 #include <cyassl/error.h>
ashleymills 0:e979170e02e7 29 #include <cyassl/ctaocrypt/hmac.h>
ashleymills 0:e979170e02e7 30
ashleymills 0:e979170e02e7 31
ashleymills 0:e979170e02e7 32
ashleymills 0:e979170e02e7 33 #ifndef NO_TLS
ashleymills 0:e979170e02e7 34
ashleymills 0:e979170e02e7 35
ashleymills 0:e979170e02e7 36 #ifndef min
ashleymills 0:e979170e02e7 37
ashleymills 0:e979170e02e7 38 static INLINE word32 min(word32 a, word32 b)
ashleymills 0:e979170e02e7 39 {
ashleymills 0:e979170e02e7 40 return a > b ? b : a;
ashleymills 0:e979170e02e7 41 }
ashleymills 0:e979170e02e7 42
ashleymills 0:e979170e02e7 43 #endif /* min */
ashleymills 0:e979170e02e7 44
ashleymills 0:e979170e02e7 45
ashleymills 0:e979170e02e7 46 #ifdef CYASSL_SHA384
ashleymills 0:e979170e02e7 47 #define PHASH_MAX_DIGEST_SIZE SHA384_DIGEST_SIZE
ashleymills 0:e979170e02e7 48 #else
ashleymills 0:e979170e02e7 49 #define PHASH_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
ashleymills 0:e979170e02e7 50 #endif
ashleymills 0:e979170e02e7 51
ashleymills 0:e979170e02e7 52 /* compute p_hash for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1 PRF */
ashleymills 0:e979170e02e7 53 static void p_hash(byte* result, word32 resLen, const byte* secret,
ashleymills 0:e979170e02e7 54 word32 secLen, const byte* seed, word32 seedLen, int hash)
ashleymills 0:e979170e02e7 55 {
ashleymills 0:e979170e02e7 56 word32 len = SHA_DIGEST_SIZE;
ashleymills 0:e979170e02e7 57 word32 times;
ashleymills 0:e979170e02e7 58 word32 lastLen;
ashleymills 0:e979170e02e7 59 word32 lastTime;
ashleymills 0:e979170e02e7 60 word32 i;
ashleymills 0:e979170e02e7 61 word32 idx = 0;
ashleymills 0:e979170e02e7 62 byte previous[PHASH_MAX_DIGEST_SIZE]; /* max size */
ashleymills 0:e979170e02e7 63 byte current[PHASH_MAX_DIGEST_SIZE]; /* max size */
ashleymills 0:e979170e02e7 64
ashleymills 0:e979170e02e7 65 Hmac hmac;
ashleymills 0:e979170e02e7 66
ashleymills 0:e979170e02e7 67 switch (hash) {
ashleymills 0:e979170e02e7 68 #ifndef NO_MD5
ashleymills 0:e979170e02e7 69 case md5_mac:
ashleymills 0:e979170e02e7 70 {
ashleymills 0:e979170e02e7 71 len = MD5_DIGEST_SIZE;
ashleymills 0:e979170e02e7 72 hash = MD5;
ashleymills 0:e979170e02e7 73 }
ashleymills 0:e979170e02e7 74 break;
ashleymills 0:e979170e02e7 75 #endif
ashleymills 0:e979170e02e7 76 #ifndef NO_SHA256
ashleymills 0:e979170e02e7 77 case sha256_mac:
ashleymills 0:e979170e02e7 78 {
ashleymills 0:e979170e02e7 79 len = SHA256_DIGEST_SIZE;
ashleymills 0:e979170e02e7 80 hash = SHA256;
ashleymills 0:e979170e02e7 81 }
ashleymills 0:e979170e02e7 82 break;
ashleymills 0:e979170e02e7 83 #endif
ashleymills 0:e979170e02e7 84 #ifdef CYASSL_SHA384
ashleymills 0:e979170e02e7 85 case sha384_mac:
ashleymills 0:e979170e02e7 86 {
ashleymills 0:e979170e02e7 87 len = SHA384_DIGEST_SIZE;
ashleymills 0:e979170e02e7 88 hash = SHA384;
ashleymills 0:e979170e02e7 89 }
ashleymills 0:e979170e02e7 90 break;
ashleymills 0:e979170e02e7 91 #endif
ashleymills 0:e979170e02e7 92 case sha_mac:
ashleymills 0:e979170e02e7 93 default:
ashleymills 0:e979170e02e7 94 {
ashleymills 0:e979170e02e7 95 len = SHA_DIGEST_SIZE;
ashleymills 0:e979170e02e7 96 hash = SHA;
ashleymills 0:e979170e02e7 97 }
ashleymills 0:e979170e02e7 98 break;
ashleymills 0:e979170e02e7 99 }
ashleymills 0:e979170e02e7 100
ashleymills 0:e979170e02e7 101 times = resLen / len;
ashleymills 0:e979170e02e7 102 lastLen = resLen % len;
ashleymills 0:e979170e02e7 103 if (lastLen) times += 1;
ashleymills 0:e979170e02e7 104 lastTime = times - 1;
ashleymills 0:e979170e02e7 105
ashleymills 0:e979170e02e7 106 HmacSetKey(&hmac, hash, secret, secLen);
ashleymills 0:e979170e02e7 107 HmacUpdate(&hmac, seed, seedLen); /* A0 = seed */
ashleymills 0:e979170e02e7 108 HmacFinal(&hmac, previous); /* A1 */
ashleymills 0:e979170e02e7 109
ashleymills 0:e979170e02e7 110 for (i = 0; i < times; i++) {
ashleymills 0:e979170e02e7 111 HmacUpdate(&hmac, previous, len);
ashleymills 0:e979170e02e7 112 HmacUpdate(&hmac, seed, seedLen);
ashleymills 0:e979170e02e7 113 HmacFinal(&hmac, current);
ashleymills 0:e979170e02e7 114
ashleymills 0:e979170e02e7 115 if ( (i == lastTime) && lastLen)
ashleymills 0:e979170e02e7 116 XMEMCPY(&result[idx], current, min(lastLen, sizeof(current)));
ashleymills 0:e979170e02e7 117 else {
ashleymills 0:e979170e02e7 118 XMEMCPY(&result[idx], current, len);
ashleymills 0:e979170e02e7 119 idx += len;
ashleymills 0:e979170e02e7 120 HmacUpdate(&hmac, previous, len);
ashleymills 0:e979170e02e7 121 HmacFinal(&hmac, previous);
ashleymills 0:e979170e02e7 122 }
ashleymills 0:e979170e02e7 123 }
ashleymills 0:e979170e02e7 124 }
ashleymills 0:e979170e02e7 125
ashleymills 0:e979170e02e7 126
ashleymills 0:e979170e02e7 127
ashleymills 0:e979170e02e7 128 #ifndef NO_MD5
ashleymills 0:e979170e02e7 129
ashleymills 0:e979170e02e7 130 /* calculate XOR for TLSv1 PRF */
ashleymills 0:e979170e02e7 131 static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha)
ashleymills 0:e979170e02e7 132 {
ashleymills 0:e979170e02e7 133 word32 i;
ashleymills 0:e979170e02e7 134
ashleymills 0:e979170e02e7 135 for (i = 0; i < digLen; i++)
ashleymills 0:e979170e02e7 136 digest[i] = md5[i] ^ sha[i];
ashleymills 0:e979170e02e7 137 }
ashleymills 0:e979170e02e7 138
ashleymills 0:e979170e02e7 139
ashleymills 0:e979170e02e7 140 /* compute TLSv1 PRF (pseudo random function using HMAC) */
ashleymills 0:e979170e02e7 141 static void doPRF(byte* digest, word32 digLen, const byte* secret,word32 secLen,
ashleymills 0:e979170e02e7 142 const byte* label, word32 labLen, const byte* seed, word32 seedLen)
ashleymills 0:e979170e02e7 143 {
ashleymills 0:e979170e02e7 144 word32 half = (secLen + 1) / 2;
ashleymills 0:e979170e02e7 145
ashleymills 0:e979170e02e7 146 byte md5_half[MAX_PRF_HALF]; /* half is real size */
ashleymills 0:e979170e02e7 147 byte sha_half[MAX_PRF_HALF]; /* half is real size */
ashleymills 0:e979170e02e7 148 byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */
ashleymills 0:e979170e02e7 149 byte md5_result[MAX_PRF_DIG]; /* digLen is real size */
ashleymills 0:e979170e02e7 150 byte sha_result[MAX_PRF_DIG]; /* digLen is real size */
ashleymills 0:e979170e02e7 151
ashleymills 0:e979170e02e7 152 if (half > MAX_PRF_HALF)
ashleymills 0:e979170e02e7 153 return;
ashleymills 0:e979170e02e7 154 if (labLen + seedLen > MAX_PRF_LABSEED)
ashleymills 0:e979170e02e7 155 return;
ashleymills 0:e979170e02e7 156 if (digLen > MAX_PRF_DIG)
ashleymills 0:e979170e02e7 157 return;
ashleymills 0:e979170e02e7 158
ashleymills 0:e979170e02e7 159 XMEMCPY(md5_half, secret, half);
ashleymills 0:e979170e02e7 160 XMEMCPY(sha_half, secret + half - secLen % 2, half);
ashleymills 0:e979170e02e7 161
ashleymills 0:e979170e02e7 162 XMEMCPY(labelSeed, label, labLen);
ashleymills 0:e979170e02e7 163 XMEMCPY(labelSeed + labLen, seed, seedLen);
ashleymills 0:e979170e02e7 164
ashleymills 0:e979170e02e7 165 p_hash(md5_result, digLen, md5_half, half, labelSeed, labLen + seedLen,
ashleymills 0:e979170e02e7 166 md5_mac);
ashleymills 0:e979170e02e7 167 p_hash(sha_result, digLen, sha_half, half, labelSeed, labLen + seedLen,
ashleymills 0:e979170e02e7 168 sha_mac);
ashleymills 0:e979170e02e7 169 get_xor(digest, digLen, md5_result, sha_result);
ashleymills 0:e979170e02e7 170 }
ashleymills 0:e979170e02e7 171
ashleymills 0:e979170e02e7 172 #endif
ashleymills 0:e979170e02e7 173
ashleymills 0:e979170e02e7 174
ashleymills 0:e979170e02e7 175 /* Wrapper to call straight thru to p_hash in TSL 1.2 cases to remove stack
ashleymills 0:e979170e02e7 176 use */
ashleymills 0:e979170e02e7 177 static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
ashleymills 0:e979170e02e7 178 const byte* label, word32 labLen, const byte* seed, word32 seedLen,
ashleymills 0:e979170e02e7 179 int useAtLeastSha256, int hash_type)
ashleymills 0:e979170e02e7 180 {
ashleymills 0:e979170e02e7 181 if (useAtLeastSha256) {
ashleymills 0:e979170e02e7 182 byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */
ashleymills 0:e979170e02e7 183
ashleymills 0:e979170e02e7 184 if (labLen + seedLen > MAX_PRF_LABSEED)
ashleymills 0:e979170e02e7 185 return;
ashleymills 0:e979170e02e7 186
ashleymills 0:e979170e02e7 187 XMEMCPY(labelSeed, label, labLen);
ashleymills 0:e979170e02e7 188 XMEMCPY(labelSeed + labLen, seed, seedLen);
ashleymills 0:e979170e02e7 189
ashleymills 0:e979170e02e7 190 /* If a cipher suite wants an algorithm better than sha256, it
ashleymills 0:e979170e02e7 191 * should use better. */
ashleymills 0:e979170e02e7 192 if (hash_type < sha256_mac)
ashleymills 0:e979170e02e7 193 hash_type = sha256_mac;
ashleymills 0:e979170e02e7 194 p_hash(digest, digLen, secret, secLen, labelSeed, labLen + seedLen,
ashleymills 0:e979170e02e7 195 hash_type);
ashleymills 0:e979170e02e7 196 }
ashleymills 0:e979170e02e7 197 #ifndef NO_MD5
ashleymills 0:e979170e02e7 198 else
ashleymills 0:e979170e02e7 199 doPRF(digest, digLen, secret, secLen, label, labLen, seed, seedLen);
ashleymills 0:e979170e02e7 200 #endif
ashleymills 0:e979170e02e7 201 }
ashleymills 0:e979170e02e7 202
ashleymills 0:e979170e02e7 203
ashleymills 0:e979170e02e7 204 #ifdef CYASSL_SHA384
ashleymills 0:e979170e02e7 205 #define HSHASH_SZ SHA384_DIGEST_SIZE
ashleymills 0:e979170e02e7 206 #else
ashleymills 0:e979170e02e7 207 #define HSHASH_SZ FINISHED_SZ
ashleymills 0:e979170e02e7 208 #endif
ashleymills 0:e979170e02e7 209
ashleymills 0:e979170e02e7 210
ashleymills 0:e979170e02e7 211 void BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
ashleymills 0:e979170e02e7 212 {
ashleymills 0:e979170e02e7 213 const byte* side;
ashleymills 0:e979170e02e7 214 byte handshake_hash[HSHASH_SZ];
ashleymills 0:e979170e02e7 215 word32 hashSz = FINISHED_SZ;
ashleymills 0:e979170e02e7 216
ashleymills 0:e979170e02e7 217 #ifndef NO_MD5
ashleymills 0:e979170e02e7 218 Md5Final(&ssl->hashMd5, handshake_hash);
ashleymills 0:e979170e02e7 219 ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]);
ashleymills 0:e979170e02e7 220 #endif
ashleymills 0:e979170e02e7 221
ashleymills 0:e979170e02e7 222 if (IsAtLeastTLSv1_2(ssl)) {
ashleymills 0:e979170e02e7 223 #ifndef NO_SHA256
ashleymills 0:e979170e02e7 224 if (ssl->specs.mac_algorithm <= sha256_mac) {
ashleymills 0:e979170e02e7 225 Sha256Final(&ssl->hashSha256, handshake_hash);
ashleymills 0:e979170e02e7 226 hashSz = SHA256_DIGEST_SIZE;
ashleymills 0:e979170e02e7 227 }
ashleymills 0:e979170e02e7 228 #endif
ashleymills 0:e979170e02e7 229 #ifdef CYASSL_SHA384
ashleymills 0:e979170e02e7 230 if (ssl->specs.mac_algorithm == sha384_mac) {
ashleymills 0:e979170e02e7 231 Sha384Final(&ssl->hashSha384, handshake_hash);
ashleymills 0:e979170e02e7 232 hashSz = SHA384_DIGEST_SIZE;
ashleymills 0:e979170e02e7 233 }
ashleymills 0:e979170e02e7 234 #endif
ashleymills 0:e979170e02e7 235 }
ashleymills 0:e979170e02e7 236
ashleymills 0:e979170e02e7 237 if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0)
ashleymills 0:e979170e02e7 238 side = tls_client;
ashleymills 0:e979170e02e7 239 else
ashleymills 0:e979170e02e7 240 side = tls_server;
ashleymills 0:e979170e02e7 241
ashleymills 0:e979170e02e7 242 #ifndef NO_MD5
ashleymills 0:e979170e02e7 243 PRF(hashes->md5, TLS_FINISHED_SZ, ssl->arrays->masterSecret, SECRET_LEN,
ashleymills 0:e979170e02e7 244 side, FINISHED_LABEL_SZ, handshake_hash, hashSz, IsAtLeastTLSv1_2(ssl),
ashleymills 0:e979170e02e7 245 ssl->specs.mac_algorithm);
ashleymills 0:e979170e02e7 246 #else
ashleymills 0:e979170e02e7 247 PRF(hashes->hash, TLS_FINISHED_SZ, ssl->arrays->masterSecret, SECRET_LEN,
ashleymills 0:e979170e02e7 248 side, FINISHED_LABEL_SZ, handshake_hash, hashSz, IsAtLeastTLSv1_2(ssl),
ashleymills 0:e979170e02e7 249 ssl->specs.mac_algorithm);
ashleymills 0:e979170e02e7 250 #endif
ashleymills 0:e979170e02e7 251 }
ashleymills 0:e979170e02e7 252
ashleymills 0:e979170e02e7 253
ashleymills 0:e979170e02e7 254 #ifndef NO_OLD_TLS
ashleymills 0:e979170e02e7 255
ashleymills 0:e979170e02e7 256 ProtocolVersion MakeTLSv1(void)
ashleymills 0:e979170e02e7 257 {
ashleymills 0:e979170e02e7 258 ProtocolVersion pv;
ashleymills 0:e979170e02e7 259 pv.major = SSLv3_MAJOR;
ashleymills 0:e979170e02e7 260 pv.minor = TLSv1_MINOR;
ashleymills 0:e979170e02e7 261
ashleymills 0:e979170e02e7 262 return pv;
ashleymills 0:e979170e02e7 263 }
ashleymills 0:e979170e02e7 264
ashleymills 0:e979170e02e7 265
ashleymills 0:e979170e02e7 266 ProtocolVersion MakeTLSv1_1(void)
ashleymills 0:e979170e02e7 267 {
ashleymills 0:e979170e02e7 268 ProtocolVersion pv;
ashleymills 0:e979170e02e7 269 pv.major = SSLv3_MAJOR;
ashleymills 0:e979170e02e7 270 pv.minor = TLSv1_1_MINOR;
ashleymills 0:e979170e02e7 271
ashleymills 0:e979170e02e7 272 return pv;
ashleymills 0:e979170e02e7 273 }
ashleymills 0:e979170e02e7 274
ashleymills 0:e979170e02e7 275 #endif
ashleymills 0:e979170e02e7 276
ashleymills 0:e979170e02e7 277
ashleymills 0:e979170e02e7 278 ProtocolVersion MakeTLSv1_2(void)
ashleymills 0:e979170e02e7 279 {
ashleymills 0:e979170e02e7 280 ProtocolVersion pv;
ashleymills 0:e979170e02e7 281 pv.major = SSLv3_MAJOR;
ashleymills 0:e979170e02e7 282 pv.minor = TLSv1_2_MINOR;
ashleymills 0:e979170e02e7 283
ashleymills 0:e979170e02e7 284 return pv;
ashleymills 0:e979170e02e7 285 }
ashleymills 0:e979170e02e7 286
ashleymills 0:e979170e02e7 287
ashleymills 0:e979170e02e7 288 static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret";
ashleymills 0:e979170e02e7 289 static const byte key_label [KEY_LABEL_SZ + 1] = "key expansion";
ashleymills 0:e979170e02e7 290
ashleymills 0:e979170e02e7 291
ashleymills 0:e979170e02e7 292 int DeriveTlsKeys(CYASSL* ssl)
ashleymills 0:e979170e02e7 293 {
ashleymills 0:e979170e02e7 294 int length = 2 * ssl->specs.hash_size +
ashleymills 0:e979170e02e7 295 2 * ssl->specs.key_size +
ashleymills 0:e979170e02e7 296 2 * ssl->specs.iv_size;
ashleymills 0:e979170e02e7 297 byte seed[SEED_LEN];
ashleymills 0:e979170e02e7 298 byte key_data[MAX_PRF_DIG];
ashleymills 0:e979170e02e7 299
ashleymills 0:e979170e02e7 300 XMEMCPY(seed, ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:e979170e02e7 301 XMEMCPY(&seed[RAN_LEN], ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:e979170e02e7 302
ashleymills 0:e979170e02e7 303 PRF(key_data, length, ssl->arrays->masterSecret, SECRET_LEN, key_label,
ashleymills 0:e979170e02e7 304 KEY_LABEL_SZ, seed, SEED_LEN, IsAtLeastTLSv1_2(ssl),
ashleymills 0:e979170e02e7 305 ssl->specs.mac_algorithm);
ashleymills 0:e979170e02e7 306
ashleymills 0:e979170e02e7 307 return StoreKeys(ssl, key_data);
ashleymills 0:e979170e02e7 308 }
ashleymills 0:e979170e02e7 309
ashleymills 0:e979170e02e7 310
ashleymills 0:e979170e02e7 311 int MakeTlsMasterSecret(CYASSL* ssl)
ashleymills 0:e979170e02e7 312 {
ashleymills 0:e979170e02e7 313 byte seed[SEED_LEN];
ashleymills 0:e979170e02e7 314
ashleymills 0:e979170e02e7 315 XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN);
ashleymills 0:e979170e02e7 316 XMEMCPY(&seed[RAN_LEN], ssl->arrays->serverRandom, RAN_LEN);
ashleymills 0:e979170e02e7 317
ashleymills 0:e979170e02e7 318 PRF(ssl->arrays->masterSecret, SECRET_LEN,
ashleymills 0:e979170e02e7 319 ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
ashleymills 0:e979170e02e7 320 master_label, MASTER_LABEL_SZ,
ashleymills 0:e979170e02e7 321 seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm);
ashleymills 0:e979170e02e7 322
ashleymills 0:e979170e02e7 323 #ifdef SHOW_SECRETS
ashleymills 0:e979170e02e7 324 {
ashleymills 0:e979170e02e7 325 int i;
ashleymills 0:e979170e02e7 326 printf("master secret: ");
ashleymills 0:e979170e02e7 327 for (i = 0; i < SECRET_LEN; i++)
ashleymills 0:e979170e02e7 328 printf("%02x", ssl->arrays->masterSecret[i]);
ashleymills 0:e979170e02e7 329 printf("\n");
ashleymills 0:e979170e02e7 330 }
ashleymills 0:e979170e02e7 331 #endif
ashleymills 0:e979170e02e7 332
ashleymills 0:e979170e02e7 333 return DeriveTlsKeys(ssl);
ashleymills 0:e979170e02e7 334 }
ashleymills 0:e979170e02e7 335
ashleymills 0:e979170e02e7 336
ashleymills 0:e979170e02e7 337 /*** next for static INLINE s copied from cyassl_int.c ***/
ashleymills 0:e979170e02e7 338
ashleymills 0:e979170e02e7 339 /* convert 16 bit integer to opaque */
ashleymills 0:e979170e02e7 340 INLINE static void c16toa(word16 u16, byte* c)
ashleymills 0:e979170e02e7 341 {
ashleymills 0:e979170e02e7 342 c[0] = (u16 >> 8) & 0xff;
ashleymills 0:e979170e02e7 343 c[1] = u16 & 0xff;
ashleymills 0:e979170e02e7 344 }
ashleymills 0:e979170e02e7 345
ashleymills 0:e979170e02e7 346
ashleymills 0:e979170e02e7 347 /* convert 32 bit integer to opaque */
ashleymills 0:e979170e02e7 348 static INLINE void c32toa(word32 u32, byte* c)
ashleymills 0:e979170e02e7 349 {
ashleymills 0:e979170e02e7 350 c[0] = (u32 >> 24) & 0xff;
ashleymills 0:e979170e02e7 351 c[1] = (u32 >> 16) & 0xff;
ashleymills 0:e979170e02e7 352 c[2] = (u32 >> 8) & 0xff;
ashleymills 0:e979170e02e7 353 c[3] = u32 & 0xff;
ashleymills 0:e979170e02e7 354 }
ashleymills 0:e979170e02e7 355
ashleymills 0:e979170e02e7 356
ashleymills 0:e979170e02e7 357 static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
ashleymills 0:e979170e02e7 358 {
ashleymills 0:e979170e02e7 359 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 360 if (ssl->options.dtls) {
ashleymills 0:e979170e02e7 361 if (verify)
ashleymills 0:e979170e02e7 362 return ssl->keys.dtls_peer_sequence_number; /* explicit from peer */
ashleymills 0:e979170e02e7 363 else
ashleymills 0:e979170e02e7 364 return ssl->keys.dtls_sequence_number - 1; /* already incremented */
ashleymills 0:e979170e02e7 365 }
ashleymills 0:e979170e02e7 366 #endif
ashleymills 0:e979170e02e7 367 if (verify)
ashleymills 0:e979170e02e7 368 return ssl->keys.peer_sequence_number++;
ashleymills 0:e979170e02e7 369 else
ashleymills 0:e979170e02e7 370 return ssl->keys.sequence_number++;
ashleymills 0:e979170e02e7 371 }
ashleymills 0:e979170e02e7 372
ashleymills 0:e979170e02e7 373
ashleymills 0:e979170e02e7 374 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 375
ashleymills 0:e979170e02e7 376 static INLINE word32 GetEpoch(CYASSL* ssl, int verify)
ashleymills 0:e979170e02e7 377 {
ashleymills 0:e979170e02e7 378 if (verify)
ashleymills 0:e979170e02e7 379 return ssl->keys.dtls_peer_epoch;
ashleymills 0:e979170e02e7 380 else
ashleymills 0:e979170e02e7 381 return ssl->keys.dtls_epoch;
ashleymills 0:e979170e02e7 382 }
ashleymills 0:e979170e02e7 383
ashleymills 0:e979170e02e7 384 #endif /* CYASSL_DTLS */
ashleymills 0:e979170e02e7 385
ashleymills 0:e979170e02e7 386
ashleymills 0:e979170e02e7 387 static INLINE const byte* GetMacSecret(CYASSL* ssl, int verify)
ashleymills 0:e979170e02e7 388 {
ashleymills 0:e979170e02e7 389 if ( (ssl->options.side == CLIENT_END && !verify) ||
ashleymills 0:e979170e02e7 390 (ssl->options.side == SERVER_END && verify) )
ashleymills 0:e979170e02e7 391 return ssl->keys.client_write_MAC_secret;
ashleymills 0:e979170e02e7 392 else
ashleymills 0:e979170e02e7 393 return ssl->keys.server_write_MAC_secret;
ashleymills 0:e979170e02e7 394 }
ashleymills 0:e979170e02e7 395
ashleymills 0:e979170e02e7 396 /*** end copy ***/
ashleymills 0:e979170e02e7 397
ashleymills 0:e979170e02e7 398
ashleymills 0:e979170e02e7 399 /* TLS type HMAC */
ashleymills 0:e979170e02e7 400 void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz,
ashleymills 0:e979170e02e7 401 int content, int verify)
ashleymills 0:e979170e02e7 402 {
ashleymills 0:e979170e02e7 403 Hmac hmac;
ashleymills 0:e979170e02e7 404 byte seq[SEQ_SZ];
ashleymills 0:e979170e02e7 405 byte length[LENGTH_SZ];
ashleymills 0:e979170e02e7 406 byte inner[ENUM_LEN + VERSION_SZ + LENGTH_SZ]; /* type + version +len */
ashleymills 0:e979170e02e7 407 int type;
ashleymills 0:e979170e02e7 408
ashleymills 0:e979170e02e7 409 XMEMSET(seq, 0, SEQ_SZ);
ashleymills 0:e979170e02e7 410 c16toa((word16)sz, length);
ashleymills 0:e979170e02e7 411 #ifdef CYASSL_DTLS
ashleymills 0:e979170e02e7 412 if (ssl->options.dtls)
ashleymills 0:e979170e02e7 413 c16toa((word16)GetEpoch(ssl, verify), seq);
ashleymills 0:e979170e02e7 414 #endif
ashleymills 0:e979170e02e7 415 c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]);
ashleymills 0:e979170e02e7 416
ashleymills 0:e979170e02e7 417 switch (ssl->specs.mac_algorithm) {
ashleymills 0:e979170e02e7 418 #ifndef NO_MD5
ashleymills 0:e979170e02e7 419 case md5_mac:
ashleymills 0:e979170e02e7 420 {
ashleymills 0:e979170e02e7 421 type = MD5;
ashleymills 0:e979170e02e7 422 }
ashleymills 0:e979170e02e7 423 break;
ashleymills 0:e979170e02e7 424 #endif
ashleymills 0:e979170e02e7 425 #ifndef NO_SHA256
ashleymills 0:e979170e02e7 426 case sha256_mac:
ashleymills 0:e979170e02e7 427 {
ashleymills 0:e979170e02e7 428 type = SHA256;
ashleymills 0:e979170e02e7 429 }
ashleymills 0:e979170e02e7 430 break;
ashleymills 0:e979170e02e7 431 #endif
ashleymills 0:e979170e02e7 432 case sha_mac:
ashleymills 0:e979170e02e7 433 default:
ashleymills 0:e979170e02e7 434 {
ashleymills 0:e979170e02e7 435 type = SHA;
ashleymills 0:e979170e02e7 436 }
ashleymills 0:e979170e02e7 437 break;
ashleymills 0:e979170e02e7 438 }
ashleymills 0:e979170e02e7 439 HmacSetKey(&hmac, type, GetMacSecret(ssl, verify), ssl->specs.hash_size);
ashleymills 0:e979170e02e7 440
ashleymills 0:e979170e02e7 441 HmacUpdate(&hmac, seq, SEQ_SZ); /* seq_num */
ashleymills 0:e979170e02e7 442 inner[0] = (byte)content; /* type */
ashleymills 0:e979170e02e7 443 inner[ENUM_LEN] = ssl->version.major;
ashleymills 0:e979170e02e7 444 inner[ENUM_LEN + ENUM_LEN] = ssl->version.minor; /* version */
ashleymills 0:e979170e02e7 445 XMEMCPY(&inner[ENUM_LEN + VERSION_SZ], length, LENGTH_SZ); /* length */
ashleymills 0:e979170e02e7 446 HmacUpdate(&hmac, inner, sizeof(inner));
ashleymills 0:e979170e02e7 447 HmacUpdate(&hmac, in, sz); /* content */
ashleymills 0:e979170e02e7 448 HmacFinal(&hmac, digest);
ashleymills 0:e979170e02e7 449 }
ashleymills 0:e979170e02e7 450
ashleymills 0:e979170e02e7 451
ashleymills 0:e979170e02e7 452 #ifndef NO_CYASSL_CLIENT
ashleymills 0:e979170e02e7 453
ashleymills 0:e979170e02e7 454 #ifndef NO_OLD_TLS
ashleymills 0:e979170e02e7 455
ashleymills 0:e979170e02e7 456 CYASSL_METHOD* CyaTLSv1_client_method(void)
ashleymills 0:e979170e02e7 457 {
ashleymills 0:e979170e02e7 458 CYASSL_METHOD* method =
ashleymills 0:e979170e02e7 459 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:e979170e02e7 460 DYNAMIC_TYPE_METHOD);
ashleymills 0:e979170e02e7 461 if (method)
ashleymills 0:e979170e02e7 462 InitSSL_Method(method, MakeTLSv1());
ashleymills 0:e979170e02e7 463 return method;
ashleymills 0:e979170e02e7 464 }
ashleymills 0:e979170e02e7 465
ashleymills 0:e979170e02e7 466
ashleymills 0:e979170e02e7 467 CYASSL_METHOD* CyaTLSv1_1_client_method(void)
ashleymills 0:e979170e02e7 468 {
ashleymills 0:e979170e02e7 469 CYASSL_METHOD* method =
ashleymills 0:e979170e02e7 470 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:e979170e02e7 471 DYNAMIC_TYPE_METHOD);
ashleymills 0:e979170e02e7 472 if (method)
ashleymills 0:e979170e02e7 473 InitSSL_Method(method, MakeTLSv1_1());
ashleymills 0:e979170e02e7 474 return method;
ashleymills 0:e979170e02e7 475 }
ashleymills 0:e979170e02e7 476
ashleymills 0:e979170e02e7 477 #endif /* !NO_OLD_TLS */
ashleymills 0:e979170e02e7 478
ashleymills 0:e979170e02e7 479 #ifndef NO_SHA256 /* can't use without SHA256 */
ashleymills 0:e979170e02e7 480
ashleymills 0:e979170e02e7 481 CYASSL_METHOD* CyaTLSv1_2_client_method(void)
ashleymills 0:e979170e02e7 482 {
ashleymills 0:e979170e02e7 483 CYASSL_METHOD* method =
ashleymills 0:e979170e02e7 484 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:e979170e02e7 485 DYNAMIC_TYPE_METHOD);
ashleymills 0:e979170e02e7 486 if (method)
ashleymills 0:e979170e02e7 487 InitSSL_Method(method, MakeTLSv1_2());
ashleymills 0:e979170e02e7 488 return method;
ashleymills 0:e979170e02e7 489 }
ashleymills 0:e979170e02e7 490
ashleymills 0:e979170e02e7 491 #endif
ashleymills 0:e979170e02e7 492
ashleymills 0:e979170e02e7 493
ashleymills 0:e979170e02e7 494 CYASSL_METHOD* CyaSSLv23_client_method(void)
ashleymills 0:e979170e02e7 495 {
ashleymills 0:e979170e02e7 496 CYASSL_METHOD* method =
ashleymills 0:e979170e02e7 497 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:e979170e02e7 498 DYNAMIC_TYPE_METHOD);
ashleymills 0:e979170e02e7 499 if (method) {
ashleymills 0:e979170e02e7 500 #ifndef NO_SHA256 /* 1.2 requires SHA256 */
ashleymills 0:e979170e02e7 501 InitSSL_Method(method, MakeTLSv1_2());
ashleymills 0:e979170e02e7 502 #else
ashleymills 0:e979170e02e7 503 InitSSL_Method(method, MakeTLSv1_1());
ashleymills 0:e979170e02e7 504 #endif
ashleymills 0:e979170e02e7 505 #ifndef NO_OLD_TLS
ashleymills 0:e979170e02e7 506 method->downgrade = 1;
ashleymills 0:e979170e02e7 507 #endif
ashleymills 0:e979170e02e7 508 }
ashleymills 0:e979170e02e7 509 return method;
ashleymills 0:e979170e02e7 510 }
ashleymills 0:e979170e02e7 511
ashleymills 0:e979170e02e7 512
ashleymills 0:e979170e02e7 513 #endif /* NO_CYASSL_CLIENT */
ashleymills 0:e979170e02e7 514
ashleymills 0:e979170e02e7 515
ashleymills 0:e979170e02e7 516
ashleymills 0:e979170e02e7 517 #ifndef NO_CYASSL_SERVER
ashleymills 0:e979170e02e7 518
ashleymills 0:e979170e02e7 519 #ifndef NO_OLD_TLS
ashleymills 0:e979170e02e7 520
ashleymills 0:e979170e02e7 521 CYASSL_METHOD* CyaTLSv1_server_method(void)
ashleymills 0:e979170e02e7 522 {
ashleymills 0:e979170e02e7 523 CYASSL_METHOD* method =
ashleymills 0:e979170e02e7 524 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:e979170e02e7 525 DYNAMIC_TYPE_METHOD);
ashleymills 0:e979170e02e7 526 if (method) {
ashleymills 0:e979170e02e7 527 InitSSL_Method(method, MakeTLSv1());
ashleymills 0:e979170e02e7 528 method->side = SERVER_END;
ashleymills 0:e979170e02e7 529 }
ashleymills 0:e979170e02e7 530 return method;
ashleymills 0:e979170e02e7 531 }
ashleymills 0:e979170e02e7 532
ashleymills 0:e979170e02e7 533
ashleymills 0:e979170e02e7 534 CYASSL_METHOD* CyaTLSv1_1_server_method(void)
ashleymills 0:e979170e02e7 535 {
ashleymills 0:e979170e02e7 536 CYASSL_METHOD* method =
ashleymills 0:e979170e02e7 537 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:e979170e02e7 538 DYNAMIC_TYPE_METHOD);
ashleymills 0:e979170e02e7 539 if (method) {
ashleymills 0:e979170e02e7 540 InitSSL_Method(method, MakeTLSv1_1());
ashleymills 0:e979170e02e7 541 method->side = SERVER_END;
ashleymills 0:e979170e02e7 542 }
ashleymills 0:e979170e02e7 543 return method;
ashleymills 0:e979170e02e7 544 }
ashleymills 0:e979170e02e7 545
ashleymills 0:e979170e02e7 546 #endif /* !NO_OLD_TLS */
ashleymills 0:e979170e02e7 547
ashleymills 0:e979170e02e7 548 #ifndef NO_SHA256 /* can't use without SHA256 */
ashleymills 0:e979170e02e7 549
ashleymills 0:e979170e02e7 550 CYASSL_METHOD* CyaTLSv1_2_server_method(void)
ashleymills 0:e979170e02e7 551 {
ashleymills 0:e979170e02e7 552 CYASSL_METHOD* method =
ashleymills 0:e979170e02e7 553 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:e979170e02e7 554 DYNAMIC_TYPE_METHOD);
ashleymills 0:e979170e02e7 555 if (method) {
ashleymills 0:e979170e02e7 556 InitSSL_Method(method, MakeTLSv1_2());
ashleymills 0:e979170e02e7 557 method->side = SERVER_END;
ashleymills 0:e979170e02e7 558 }
ashleymills 0:e979170e02e7 559 return method;
ashleymills 0:e979170e02e7 560 }
ashleymills 0:e979170e02e7 561
ashleymills 0:e979170e02e7 562 #endif
ashleymills 0:e979170e02e7 563
ashleymills 0:e979170e02e7 564
ashleymills 0:e979170e02e7 565 CYASSL_METHOD* CyaSSLv23_server_method(void)
ashleymills 0:e979170e02e7 566 {
ashleymills 0:e979170e02e7 567 CYASSL_METHOD* method =
ashleymills 0:e979170e02e7 568 (CYASSL_METHOD*) XMALLOC(sizeof(CYASSL_METHOD), 0,
ashleymills 0:e979170e02e7 569 DYNAMIC_TYPE_METHOD);
ashleymills 0:e979170e02e7 570 if (method) {
ashleymills 0:e979170e02e7 571 #ifndef NO_SHA256 /* 1.2 requires SHA256 */
ashleymills 0:e979170e02e7 572 InitSSL_Method(method, MakeTLSv1_2());
ashleymills 0:e979170e02e7 573 #else
ashleymills 0:e979170e02e7 574 InitSSL_Method(method, MakeTLSv1_1());
ashleymills 0:e979170e02e7 575 #endif
ashleymills 0:e979170e02e7 576 method->side = SERVER_END;
ashleymills 0:e979170e02e7 577 #ifndef NO_OLD_TLS
ashleymills 0:e979170e02e7 578 method->downgrade = 1;
ashleymills 0:e979170e02e7 579 #endif /* !NO_OLD_TLS */
ashleymills 0:e979170e02e7 580 }
ashleymills 0:e979170e02e7 581 return method;
ashleymills 0:e979170e02e7 582 }
ashleymills 0:e979170e02e7 583
ashleymills 0:e979170e02e7 584
ashleymills 0:e979170e02e7 585
ashleymills 0:e979170e02e7 586 #endif /* NO_CYASSL_SERVER */
ashleymills 0:e979170e02e7 587
ashleymills 0:e979170e02e7 588 #else /* NO_TLS */
ashleymills 0:e979170e02e7 589
ashleymills 0:e979170e02e7 590 /* catch CyaSSL programming errors */
ashleymills 0:e979170e02e7 591 void BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender)
ashleymills 0:e979170e02e7 592 {
ashleymills 0:e979170e02e7 593
ashleymills 0:e979170e02e7 594 }
ashleymills 0:e979170e02e7 595
ashleymills 0:e979170e02e7 596
ashleymills 0:e979170e02e7 597 int DeriveTlsKeys(CYASSL* ssl)
ashleymills 0:e979170e02e7 598 {
ashleymills 0:e979170e02e7 599 return NOT_COMPILED_IN;
ashleymills 0:e979170e02e7 600 }
ashleymills 0:e979170e02e7 601
ashleymills 0:e979170e02e7 602
ashleymills 0:e979170e02e7 603 int MakeTlsMasterSecret(CYASSL* ssl)
ashleymills 0:e979170e02e7 604 {
ashleymills 0:e979170e02e7 605 return NOT_COMPILED_IN;
ashleymills 0:e979170e02e7 606 }
ashleymills 0:e979170e02e7 607
ashleymills 0:e979170e02e7 608 #endif /* NO_TLS */
ashleymills 0:e979170e02e7 609