cya_u
Fork of CyaSSL-forEncrypt by
tls.c@2:d0516dc143b1, 2017-05-10 (annotated)
- Committer:
- vbahl2
- Date:
- Wed May 10 18:20:47 2017 +0000
- Revision:
- 2:d0516dc143b1
- Parent:
- 0:5045d2638c29
updated
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
toddouska | 0:5045d2638c29 | 1 | /* tls.c |
toddouska | 0:5045d2638c29 | 2 | * |
toddouska | 0:5045d2638c29 | 3 | * Copyright (C) 2006-2009 Sawtooth Consulting Ltd. |
toddouska | 0:5045d2638c29 | 4 | * |
toddouska | 0:5045d2638c29 | 5 | * This file is part of CyaSSL. |
toddouska | 0:5045d2638c29 | 6 | * |
toddouska | 0:5045d2638c29 | 7 | * CyaSSL is free software; you can redistribute it and/or modify |
toddouska | 0:5045d2638c29 | 8 | * it under the terms of the GNU General Public License as published by |
toddouska | 0:5045d2638c29 | 9 | * the Free Software Foundation; either version 2 of the License, or |
toddouska | 0:5045d2638c29 | 10 | * (at your option) any later version. |
toddouska | 0:5045d2638c29 | 11 | * |
toddouska | 0:5045d2638c29 | 12 | * CyaSSL is distributed in the hope that it will be useful, |
toddouska | 0:5045d2638c29 | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
toddouska | 0:5045d2638c29 | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
toddouska | 0:5045d2638c29 | 15 | * GNU General Public License for more details. |
toddouska | 0:5045d2638c29 | 16 | * |
toddouska | 0:5045d2638c29 | 17 | * You should have received a copy of the GNU General Public License |
toddouska | 0:5045d2638c29 | 18 | * along with this program; if not, write to the Free Software |
toddouska | 0:5045d2638c29 | 19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
toddouska | 0:5045d2638c29 | 20 | */ |
toddouska | 0:5045d2638c29 | 21 | |
toddouska | 0:5045d2638c29 | 22 | |
toddouska | 0:5045d2638c29 | 23 | #include "ssl.h" |
toddouska | 0:5045d2638c29 | 24 | #include "cyassl_int.h" |
toddouska | 0:5045d2638c29 | 25 | #include "cyassl_error.h" |
toddouska | 0:5045d2638c29 | 26 | #include "ctc_hmac.h" |
toddouska | 0:5045d2638c29 | 27 | |
toddouska | 0:5045d2638c29 | 28 | |
toddouska | 0:5045d2638c29 | 29 | |
toddouska | 0:5045d2638c29 | 30 | #ifndef NO_TLS |
toddouska | 0:5045d2638c29 | 31 | |
toddouska | 0:5045d2638c29 | 32 | |
toddouska | 0:5045d2638c29 | 33 | #ifndef min |
toddouska | 0:5045d2638c29 | 34 | |
toddouska | 0:5045d2638c29 | 35 | static INLINE word32 min(word32 a, word32 b) |
toddouska | 0:5045d2638c29 | 36 | { |
toddouska | 0:5045d2638c29 | 37 | return a > b ? b : a; |
toddouska | 0:5045d2638c29 | 38 | } |
toddouska | 0:5045d2638c29 | 39 | |
toddouska | 0:5045d2638c29 | 40 | #endif /* min */ |
toddouska | 0:5045d2638c29 | 41 | |
toddouska | 0:5045d2638c29 | 42 | |
toddouska | 0:5045d2638c29 | 43 | /* calculate XOR for TLSv1 PRF */ |
toddouska | 0:5045d2638c29 | 44 | static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha) |
toddouska | 0:5045d2638c29 | 45 | { |
toddouska | 0:5045d2638c29 | 46 | word32 i; |
toddouska | 0:5045d2638c29 | 47 | |
toddouska | 0:5045d2638c29 | 48 | for (i = 0; i < digLen; i++) |
toddouska | 0:5045d2638c29 | 49 | digest[i] = md5[i] ^ sha[i]; |
toddouska | 0:5045d2638c29 | 50 | } |
toddouska | 0:5045d2638c29 | 51 | |
toddouska | 0:5045d2638c29 | 52 | |
toddouska | 0:5045d2638c29 | 53 | |
toddouska | 0:5045d2638c29 | 54 | /* compute p_hash for MD5, SHA-1, or SHA-256 for TLSv1 PRF */ |
toddouska | 0:5045d2638c29 | 55 | void p_hash(byte* result, word32 resLen, const byte* secret, word32 secLen, |
toddouska | 0:5045d2638c29 | 56 | const byte* seed, word32 seedLen, int hash) |
toddouska | 0:5045d2638c29 | 57 | { |
toddouska | 0:5045d2638c29 | 58 | word32 len = hash == md5_mac ? MD5_DIGEST_SIZE : hash == sha_mac ? |
toddouska | 0:5045d2638c29 | 59 | SHA_DIGEST_SIZE : SHA256_DIGEST_SIZE; |
toddouska | 0:5045d2638c29 | 60 | word32 times = resLen / len; |
toddouska | 0:5045d2638c29 | 61 | word32 lastLen = resLen % len; |
toddouska | 0:5045d2638c29 | 62 | word32 lastTime; |
toddouska | 0:5045d2638c29 | 63 | word32 i; |
toddouska | 0:5045d2638c29 | 64 | word32 idx = 0; |
toddouska | 0:5045d2638c29 | 65 | byte previous[SHA256_DIGEST_SIZE]; /* max size */ |
toddouska | 0:5045d2638c29 | 66 | byte current[SHA256_DIGEST_SIZE]; /* max size */ |
toddouska | 0:5045d2638c29 | 67 | |
toddouska | 0:5045d2638c29 | 68 | Hmac hmac; |
toddouska | 0:5045d2638c29 | 69 | |
toddouska | 0:5045d2638c29 | 70 | if (lastLen) times += 1; |
toddouska | 0:5045d2638c29 | 71 | lastTime = times - 1; |
toddouska | 0:5045d2638c29 | 72 | |
toddouska | 0:5045d2638c29 | 73 | HmacSetKey(&hmac, hash == md5_mac ? MD5 : hash == sha_mac ? SHA : SHA256, |
toddouska | 0:5045d2638c29 | 74 | secret, secLen); |
toddouska | 0:5045d2638c29 | 75 | HmacUpdate(&hmac, seed, seedLen); /* A0 = seed */ |
toddouska | 0:5045d2638c29 | 76 | HmacFinal(&hmac, previous); /* A1 */ |
toddouska | 0:5045d2638c29 | 77 | |
toddouska | 0:5045d2638c29 | 78 | for (i = 0; i < times; i++) { |
toddouska | 0:5045d2638c29 | 79 | HmacUpdate(&hmac, previous, len); |
toddouska | 0:5045d2638c29 | 80 | HmacUpdate(&hmac, seed, seedLen); |
toddouska | 0:5045d2638c29 | 81 | HmacFinal(&hmac, current); |
toddouska | 0:5045d2638c29 | 82 | |
toddouska | 0:5045d2638c29 | 83 | if ( (i == lastTime) && lastLen) |
toddouska | 0:5045d2638c29 | 84 | XMEMCPY(&result[idx], current, lastLen); |
toddouska | 0:5045d2638c29 | 85 | else { |
toddouska | 0:5045d2638c29 | 86 | XMEMCPY(&result[idx], current, len); |
toddouska | 0:5045d2638c29 | 87 | idx += len; |
toddouska | 0:5045d2638c29 | 88 | HmacUpdate(&hmac, previous, len); |
toddouska | 0:5045d2638c29 | 89 | HmacFinal(&hmac, previous); |
toddouska | 0:5045d2638c29 | 90 | } |
toddouska | 0:5045d2638c29 | 91 | } |
toddouska | 0:5045d2638c29 | 92 | } |
toddouska | 0:5045d2638c29 | 93 | |
toddouska | 0:5045d2638c29 | 94 | |
toddouska | 0:5045d2638c29 | 95 | |
toddouska | 0:5045d2638c29 | 96 | /* compute TLSv1 PRF (pseudo random function using HMAC) */ |
toddouska | 0:5045d2638c29 | 97 | static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen, |
toddouska | 0:5045d2638c29 | 98 | const byte* label, word32 labLen, const byte* seed, word32 seedLen, |
toddouska | 0:5045d2638c29 | 99 | int useSha256) |
toddouska | 0:5045d2638c29 | 100 | { |
toddouska | 0:5045d2638c29 | 101 | word32 half = (secLen + 1) / 2; |
toddouska | 0:5045d2638c29 | 102 | |
toddouska | 0:5045d2638c29 | 103 | byte md5_half[MAX_PRF_HALF]; /* half is real size */ |
toddouska | 0:5045d2638c29 | 104 | byte sha_half[MAX_PRF_HALF]; /* half is real size */ |
toddouska | 0:5045d2638c29 | 105 | byte labelSeed[MAX_PRF_LABSEED]; /* labLen + seedLen is real size */ |
toddouska | 0:5045d2638c29 | 106 | byte md5_result[MAX_PRF_DIG]; /* digLen is real size */ |
toddouska | 0:5045d2638c29 | 107 | byte sha_result[MAX_PRF_DIG]; /* digLen is real size */ |
toddouska | 0:5045d2638c29 | 108 | |
toddouska | 0:5045d2638c29 | 109 | if (half > MAX_PRF_HALF) |
toddouska | 0:5045d2638c29 | 110 | return; |
toddouska | 0:5045d2638c29 | 111 | if (labLen + seedLen > MAX_PRF_LABSEED) |
toddouska | 0:5045d2638c29 | 112 | return; |
toddouska | 0:5045d2638c29 | 113 | if (digLen > MAX_PRF_DIG) |
toddouska | 0:5045d2638c29 | 114 | return; |
toddouska | 0:5045d2638c29 | 115 | |
toddouska | 0:5045d2638c29 | 116 | XMEMCPY(md5_half, secret, half); |
toddouska | 0:5045d2638c29 | 117 | XMEMCPY(sha_half, secret + half - secLen % 2, half); |
toddouska | 0:5045d2638c29 | 118 | |
toddouska | 0:5045d2638c29 | 119 | XMEMCPY(labelSeed, label, labLen); |
toddouska | 0:5045d2638c29 | 120 | XMEMCPY(labelSeed + labLen, seed, seedLen); |
toddouska | 0:5045d2638c29 | 121 | |
toddouska | 0:5045d2638c29 | 122 | if (useSha256) { |
toddouska | 0:5045d2638c29 | 123 | p_hash(digest, digLen, secret, secLen, labelSeed, labLen + seedLen, |
toddouska | 0:5045d2638c29 | 124 | sha256_mac); |
toddouska | 0:5045d2638c29 | 125 | return; |
toddouska | 0:5045d2638c29 | 126 | } |
toddouska | 0:5045d2638c29 | 127 | |
toddouska | 0:5045d2638c29 | 128 | p_hash(md5_result, digLen, md5_half, half, labelSeed, labLen + seedLen, |
toddouska | 0:5045d2638c29 | 129 | md5_mac); |
toddouska | 0:5045d2638c29 | 130 | p_hash(sha_result, digLen, sha_half, half, labelSeed, labLen + seedLen, |
toddouska | 0:5045d2638c29 | 131 | sha_mac); |
toddouska | 0:5045d2638c29 | 132 | get_xor(digest, digLen, md5_result, sha_result); |
toddouska | 0:5045d2638c29 | 133 | } |
toddouska | 0:5045d2638c29 | 134 | |
toddouska | 0:5045d2638c29 | 135 | |
toddouska | 0:5045d2638c29 | 136 | void BuildTlsFinished(SSL* ssl, Hashes* hashes, const byte* sender) |
toddouska | 0:5045d2638c29 | 137 | { |
toddouska | 0:5045d2638c29 | 138 | const byte* side; |
toddouska | 0:5045d2638c29 | 139 | byte handshake_hash[FINISHED_SZ]; |
toddouska | 0:5045d2638c29 | 140 | |
toddouska | 0:5045d2638c29 | 141 | Md5Final(&ssl->hashMd5, handshake_hash); |
toddouska | 0:5045d2638c29 | 142 | ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]); |
toddouska | 0:5045d2638c29 | 143 | |
toddouska | 0:5045d2638c29 | 144 | if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0) |
toddouska | 0:5045d2638c29 | 145 | side = tls_client; |
toddouska | 0:5045d2638c29 | 146 | else |
toddouska | 0:5045d2638c29 | 147 | side = tls_server; |
toddouska | 0:5045d2638c29 | 148 | |
toddouska | 0:5045d2638c29 | 149 | PRF(hashes->md5, TLS_FINISHED_SZ, ssl->arrays.masterSecret, SECRET_LEN, |
toddouska | 0:5045d2638c29 | 150 | side, FINISHED_LABEL_SZ, handshake_hash, FINISHED_SZ, |
toddouska | 0:5045d2638c29 | 151 | IsAtLeastTLSv1_2(ssl)); |
toddouska | 0:5045d2638c29 | 152 | } |
toddouska | 0:5045d2638c29 | 153 | |
toddouska | 0:5045d2638c29 | 154 | |
toddouska | 0:5045d2638c29 | 155 | ProtocolVersion MakeTLSv1(void) |
toddouska | 0:5045d2638c29 | 156 | { |
toddouska | 0:5045d2638c29 | 157 | ProtocolVersion pv; |
toddouska | 0:5045d2638c29 | 158 | pv.major = SSLv3_MAJOR; |
toddouska | 0:5045d2638c29 | 159 | pv.minor = TLSv1_MINOR; |
toddouska | 0:5045d2638c29 | 160 | |
toddouska | 0:5045d2638c29 | 161 | return pv; |
toddouska | 0:5045d2638c29 | 162 | } |
toddouska | 0:5045d2638c29 | 163 | |
toddouska | 0:5045d2638c29 | 164 | |
toddouska | 0:5045d2638c29 | 165 | ProtocolVersion MakeTLSv1_1(void) |
toddouska | 0:5045d2638c29 | 166 | { |
toddouska | 0:5045d2638c29 | 167 | ProtocolVersion pv; |
toddouska | 0:5045d2638c29 | 168 | pv.major = SSLv3_MAJOR; |
toddouska | 0:5045d2638c29 | 169 | pv.minor = TLSv1_1_MINOR; |
toddouska | 0:5045d2638c29 | 170 | |
toddouska | 0:5045d2638c29 | 171 | return pv; |
toddouska | 0:5045d2638c29 | 172 | } |
toddouska | 0:5045d2638c29 | 173 | |
toddouska | 0:5045d2638c29 | 174 | |
toddouska | 0:5045d2638c29 | 175 | ProtocolVersion MakeTLSv1_2(void) |
toddouska | 0:5045d2638c29 | 176 | { |
toddouska | 0:5045d2638c29 | 177 | ProtocolVersion pv; |
toddouska | 0:5045d2638c29 | 178 | pv.major = SSLv3_MAJOR; |
toddouska | 0:5045d2638c29 | 179 | pv.minor = TLSv1_2_MINOR; |
toddouska | 0:5045d2638c29 | 180 | |
toddouska | 0:5045d2638c29 | 181 | return pv; |
toddouska | 0:5045d2638c29 | 182 | } |
toddouska | 0:5045d2638c29 | 183 | |
toddouska | 0:5045d2638c29 | 184 | |
toddouska | 0:5045d2638c29 | 185 | static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret"; |
toddouska | 0:5045d2638c29 | 186 | static const byte key_label [KEY_LABEL_SZ + 1] = "key expansion"; |
toddouska | 0:5045d2638c29 | 187 | |
toddouska | 0:5045d2638c29 | 188 | |
toddouska | 0:5045d2638c29 | 189 | int DeriveTlsKeys(SSL* ssl) |
toddouska | 0:5045d2638c29 | 190 | { |
toddouska | 0:5045d2638c29 | 191 | int length = 2 * ssl->specs.hash_size + |
toddouska | 0:5045d2638c29 | 192 | 2 * ssl->specs.key_size + |
toddouska | 0:5045d2638c29 | 193 | 2 * ssl->specs.iv_size; |
toddouska | 0:5045d2638c29 | 194 | byte seed[SEED_LEN]; |
toddouska | 0:5045d2638c29 | 195 | byte key_data[MAX_PRF_DIG]; |
toddouska | 0:5045d2638c29 | 196 | |
toddouska | 0:5045d2638c29 | 197 | XMEMCPY(seed, ssl->arrays.serverRandom, RAN_LEN); |
toddouska | 0:5045d2638c29 | 198 | XMEMCPY(&seed[RAN_LEN], ssl->arrays.clientRandom, RAN_LEN); |
toddouska | 0:5045d2638c29 | 199 | |
toddouska | 0:5045d2638c29 | 200 | PRF(key_data, length, ssl->arrays.masterSecret, SECRET_LEN, key_label, |
toddouska | 0:5045d2638c29 | 201 | KEY_LABEL_SZ, seed, SEED_LEN, IsAtLeastTLSv1_2(ssl)); |
toddouska | 0:5045d2638c29 | 202 | |
toddouska | 0:5045d2638c29 | 203 | return StoreKeys(ssl, key_data); |
toddouska | 0:5045d2638c29 | 204 | } |
toddouska | 0:5045d2638c29 | 205 | |
toddouska | 0:5045d2638c29 | 206 | |
toddouska | 0:5045d2638c29 | 207 | int MakeTlsMasterSecret(SSL* ssl) |
toddouska | 0:5045d2638c29 | 208 | { |
toddouska | 0:5045d2638c29 | 209 | byte seed[SEED_LEN]; |
toddouska | 0:5045d2638c29 | 210 | |
toddouska | 0:5045d2638c29 | 211 | XMEMCPY(seed, ssl->arrays.clientRandom, RAN_LEN); |
toddouska | 0:5045d2638c29 | 212 | XMEMCPY(&seed[RAN_LEN], ssl->arrays.serverRandom, RAN_LEN); |
toddouska | 0:5045d2638c29 | 213 | |
toddouska | 0:5045d2638c29 | 214 | PRF(ssl->arrays.masterSecret, SECRET_LEN, |
toddouska | 0:5045d2638c29 | 215 | ssl->arrays.preMasterSecret, ssl->arrays.preMasterSz, |
toddouska | 0:5045d2638c29 | 216 | master_label, MASTER_LABEL_SZ, |
toddouska | 0:5045d2638c29 | 217 | seed, SEED_LEN, IsAtLeastTLSv1_2(ssl)); |
toddouska | 0:5045d2638c29 | 218 | |
toddouska | 0:5045d2638c29 | 219 | #ifdef SHOW_SECRETS |
toddouska | 0:5045d2638c29 | 220 | { |
toddouska | 0:5045d2638c29 | 221 | int i; |
toddouska | 0:5045d2638c29 | 222 | printf("master secret: "); |
toddouska | 0:5045d2638c29 | 223 | for (i = 0; i < SECRET_LEN; i++) |
toddouska | 0:5045d2638c29 | 224 | printf("%02x", ssl->arrays.masterSecret[i]); |
toddouska | 0:5045d2638c29 | 225 | printf("\n"); |
toddouska | 0:5045d2638c29 | 226 | } |
toddouska | 0:5045d2638c29 | 227 | #endif |
toddouska | 0:5045d2638c29 | 228 | |
toddouska | 0:5045d2638c29 | 229 | return DeriveTlsKeys(ssl); |
toddouska | 0:5045d2638c29 | 230 | } |
toddouska | 0:5045d2638c29 | 231 | |
toddouska | 0:5045d2638c29 | 232 | |
toddouska | 0:5045d2638c29 | 233 | /*** next for static INLINE s copied from cyassl_int.c ***/ |
toddouska | 0:5045d2638c29 | 234 | |
toddouska | 0:5045d2638c29 | 235 | /* convert 16 bit integer to opaque */ |
toddouska | 0:5045d2638c29 | 236 | static void INLINE c16toa(word16 u16, byte* c) |
toddouska | 0:5045d2638c29 | 237 | { |
toddouska | 0:5045d2638c29 | 238 | c[0] = (u16 >> 8) & 0xff; |
toddouska | 0:5045d2638c29 | 239 | c[1] = u16 & 0xff; |
toddouska | 0:5045d2638c29 | 240 | } |
toddouska | 0:5045d2638c29 | 241 | |
toddouska | 0:5045d2638c29 | 242 | |
toddouska | 0:5045d2638c29 | 243 | /* convert 32 bit integer to opaque */ |
toddouska | 0:5045d2638c29 | 244 | static INLINE void c32toa(word32 u32, byte* c) |
toddouska | 0:5045d2638c29 | 245 | { |
toddouska | 0:5045d2638c29 | 246 | c[0] = (u32 >> 24) & 0xff; |
toddouska | 0:5045d2638c29 | 247 | c[1] = (u32 >> 16) & 0xff; |
toddouska | 0:5045d2638c29 | 248 | c[2] = (u32 >> 8) & 0xff; |
toddouska | 0:5045d2638c29 | 249 | c[3] = u32 & 0xff; |
toddouska | 0:5045d2638c29 | 250 | } |
toddouska | 0:5045d2638c29 | 251 | |
toddouska | 0:5045d2638c29 | 252 | |
toddouska | 0:5045d2638c29 | 253 | static INLINE word32 GetSEQIncrement(SSL* ssl, int verify) |
toddouska | 0:5045d2638c29 | 254 | { |
toddouska | 0:5045d2638c29 | 255 | #ifdef CYASSL_DTLS |
toddouska | 0:5045d2638c29 | 256 | if (ssl->options.dtls) { |
toddouska | 0:5045d2638c29 | 257 | if (verify) |
toddouska | 0:5045d2638c29 | 258 | return ssl->keys.dtls_peer_sequence_number; /* explicit from peer */ |
toddouska | 0:5045d2638c29 | 259 | else |
toddouska | 0:5045d2638c29 | 260 | return ssl->keys.dtls_sequence_number - 1; /* already incremented */ |
toddouska | 0:5045d2638c29 | 261 | } |
toddouska | 0:5045d2638c29 | 262 | #endif |
toddouska | 0:5045d2638c29 | 263 | if (verify) |
toddouska | 0:5045d2638c29 | 264 | return ssl->keys.peer_sequence_number++; |
toddouska | 0:5045d2638c29 | 265 | else |
toddouska | 0:5045d2638c29 | 266 | return ssl->keys.sequence_number++; |
toddouska | 0:5045d2638c29 | 267 | } |
toddouska | 0:5045d2638c29 | 268 | |
toddouska | 0:5045d2638c29 | 269 | |
toddouska | 0:5045d2638c29 | 270 | #ifdef CYASSL_DTLS |
toddouska | 0:5045d2638c29 | 271 | |
toddouska | 0:5045d2638c29 | 272 | static INLINE word32 GetEpoch(SSL* ssl, int verify) |
toddouska | 0:5045d2638c29 | 273 | { |
toddouska | 0:5045d2638c29 | 274 | if (verify) |
toddouska | 0:5045d2638c29 | 275 | return ssl->keys.dtls_peer_epoch; |
toddouska | 0:5045d2638c29 | 276 | else |
toddouska | 0:5045d2638c29 | 277 | return ssl->keys.dtls_epoch; |
toddouska | 0:5045d2638c29 | 278 | } |
toddouska | 0:5045d2638c29 | 279 | |
toddouska | 0:5045d2638c29 | 280 | #endif /* CYASSL_DTLS */ |
toddouska | 0:5045d2638c29 | 281 | |
toddouska | 0:5045d2638c29 | 282 | |
toddouska | 0:5045d2638c29 | 283 | static INLINE const byte* GetMacSecret(SSL* ssl, int verify) |
toddouska | 0:5045d2638c29 | 284 | { |
toddouska | 0:5045d2638c29 | 285 | if ( (ssl->options.side == CLIENT_END && !verify) || |
toddouska | 0:5045d2638c29 | 286 | (ssl->options.side == SERVER_END && verify) ) |
toddouska | 0:5045d2638c29 | 287 | return ssl->keys.client_write_MAC_secret; |
toddouska | 0:5045d2638c29 | 288 | else |
toddouska | 0:5045d2638c29 | 289 | return ssl->keys.server_write_MAC_secret; |
toddouska | 0:5045d2638c29 | 290 | } |
toddouska | 0:5045d2638c29 | 291 | |
toddouska | 0:5045d2638c29 | 292 | /*** end copy ***/ |
toddouska | 0:5045d2638c29 | 293 | |
toddouska | 0:5045d2638c29 | 294 | |
toddouska | 0:5045d2638c29 | 295 | /* TLS type HAMC */ |
toddouska | 0:5045d2638c29 | 296 | void TLS_hmac(SSL* ssl, byte* digest, const byte* buffer, word32 sz, |
toddouska | 0:5045d2638c29 | 297 | int content, int verify) |
toddouska | 0:5045d2638c29 | 298 | { |
toddouska | 0:5045d2638c29 | 299 | Hmac hmac; |
toddouska | 0:5045d2638c29 | 300 | byte seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 }; |
toddouska | 0:5045d2638c29 | 301 | byte length[LENGTH_SZ]; |
toddouska | 0:5045d2638c29 | 302 | byte inner[ENUM_LEN + VERSION_SZ + LENGTH_SZ]; /* type + version +len */ |
toddouska | 0:5045d2638c29 | 303 | int type; |
toddouska | 0:5045d2638c29 | 304 | |
toddouska | 0:5045d2638c29 | 305 | c16toa((word16)sz, length); |
toddouska | 0:5045d2638c29 | 306 | #ifdef CYASSL_DTLS |
toddouska | 0:5045d2638c29 | 307 | if (ssl->options.dtls) |
toddouska | 0:5045d2638c29 | 308 | c16toa(GetEpoch(ssl, verify), seq); |
toddouska | 0:5045d2638c29 | 309 | #endif |
toddouska | 0:5045d2638c29 | 310 | c32toa(GetSEQIncrement(ssl, verify), &seq[sizeof(word32)]); |
toddouska | 0:5045d2638c29 | 311 | |
toddouska | 0:5045d2638c29 | 312 | if (ssl->specs.mac_algorithm == md5_mac) |
toddouska | 0:5045d2638c29 | 313 | type = MD5; |
toddouska | 0:5045d2638c29 | 314 | else |
toddouska | 0:5045d2638c29 | 315 | type = SHA; |
toddouska | 0:5045d2638c29 | 316 | HmacSetKey(&hmac, type, GetMacSecret(ssl, verify), ssl->specs.hash_size); |
toddouska | 0:5045d2638c29 | 317 | |
toddouska | 0:5045d2638c29 | 318 | HmacUpdate(&hmac, seq, SEQ_SZ); /* seq_num */ |
toddouska | 0:5045d2638c29 | 319 | inner[0] = content; /* type */ |
toddouska | 0:5045d2638c29 | 320 | inner[ENUM_LEN] = ssl->version.major; |
toddouska | 0:5045d2638c29 | 321 | inner[ENUM_LEN + ENUM_LEN] = ssl->version.minor; /* version */ |
toddouska | 0:5045d2638c29 | 322 | XMEMCPY(&inner[ENUM_LEN + VERSION_SZ], length, LENGTH_SZ); /* length */ |
toddouska | 0:5045d2638c29 | 323 | HmacUpdate(&hmac, inner, sizeof(inner)); |
toddouska | 0:5045d2638c29 | 324 | HmacUpdate(&hmac, buffer, sz); /* content */ |
toddouska | 0:5045d2638c29 | 325 | HmacFinal(&hmac, digest); |
toddouska | 0:5045d2638c29 | 326 | } |
toddouska | 0:5045d2638c29 | 327 | |
toddouska | 0:5045d2638c29 | 328 | |
toddouska | 0:5045d2638c29 | 329 | #ifndef NO_CYASSL_CLIENT |
toddouska | 0:5045d2638c29 | 330 | |
toddouska | 0:5045d2638c29 | 331 | SSL_METHOD* TLSv1_client_method(void) |
toddouska | 0:5045d2638c29 | 332 | { |
toddouska | 0:5045d2638c29 | 333 | SSL_METHOD* method = (SSL_METHOD*) XMALLOC(sizeof(SSL_METHOD), 0, |
toddouska | 0:5045d2638c29 | 334 | DYNAMIC_TYPE_METHOD); |
toddouska | 0:5045d2638c29 | 335 | if (method) |
toddouska | 0:5045d2638c29 | 336 | InitSSL_Method(method, MakeTLSv1()); |
toddouska | 0:5045d2638c29 | 337 | return method; |
toddouska | 0:5045d2638c29 | 338 | } |
toddouska | 0:5045d2638c29 | 339 | |
toddouska | 0:5045d2638c29 | 340 | |
toddouska | 0:5045d2638c29 | 341 | SSL_METHOD* TLSv1_1_client_method(void) |
toddouska | 0:5045d2638c29 | 342 | { |
toddouska | 0:5045d2638c29 | 343 | SSL_METHOD* method = (SSL_METHOD*) XMALLOC(sizeof(SSL_METHOD), 0, |
toddouska | 0:5045d2638c29 | 344 | DYNAMIC_TYPE_METHOD); |
toddouska | 0:5045d2638c29 | 345 | if (method) |
toddouska | 0:5045d2638c29 | 346 | InitSSL_Method(method, MakeTLSv1_1()); |
toddouska | 0:5045d2638c29 | 347 | return method; |
toddouska | 0:5045d2638c29 | 348 | } |
toddouska | 0:5045d2638c29 | 349 | |
toddouska | 0:5045d2638c29 | 350 | |
toddouska | 0:5045d2638c29 | 351 | SSL_METHOD* TLSv1_2_client_method(void) |
toddouska | 0:5045d2638c29 | 352 | { |
toddouska | 0:5045d2638c29 | 353 | SSL_METHOD* method = (SSL_METHOD*) XMALLOC(sizeof(SSL_METHOD), 0, |
toddouska | 0:5045d2638c29 | 354 | DYNAMIC_TYPE_METHOD); |
toddouska | 0:5045d2638c29 | 355 | if (method) |
toddouska | 0:5045d2638c29 | 356 | InitSSL_Method(method, MakeTLSv1_2()); |
toddouska | 0:5045d2638c29 | 357 | return method; |
toddouska | 0:5045d2638c29 | 358 | } |
toddouska | 0:5045d2638c29 | 359 | |
toddouska | 0:5045d2638c29 | 360 | |
toddouska | 0:5045d2638c29 | 361 | /* TODO: add downgrade */ |
toddouska | 0:5045d2638c29 | 362 | SSL_METHOD* SSLv23_client_method(void) |
toddouska | 0:5045d2638c29 | 363 | { |
toddouska | 0:5045d2638c29 | 364 | SSL_METHOD* method = (SSL_METHOD*) XMALLOC(sizeof(SSL_METHOD), 0, |
toddouska | 0:5045d2638c29 | 365 | DYNAMIC_TYPE_METHOD); |
toddouska | 0:5045d2638c29 | 366 | if (method) |
toddouska | 0:5045d2638c29 | 367 | InitSSL_Method(method, MakeTLSv1()); |
toddouska | 0:5045d2638c29 | 368 | return method; |
toddouska | 0:5045d2638c29 | 369 | } |
toddouska | 0:5045d2638c29 | 370 | |
toddouska | 0:5045d2638c29 | 371 | |
toddouska | 0:5045d2638c29 | 372 | #endif /* NO_CYASSL_CLIENT */ |
toddouska | 0:5045d2638c29 | 373 | |
toddouska | 0:5045d2638c29 | 374 | |
toddouska | 0:5045d2638c29 | 375 | |
toddouska | 0:5045d2638c29 | 376 | #ifndef NO_CYASSL_SERVER |
toddouska | 0:5045d2638c29 | 377 | |
toddouska | 0:5045d2638c29 | 378 | SSL_METHOD* TLSv1_server_method(void) |
toddouska | 0:5045d2638c29 | 379 | { |
toddouska | 0:5045d2638c29 | 380 | SSL_METHOD* method = (SSL_METHOD*) XMALLOC(sizeof(SSL_METHOD), 0, |
toddouska | 0:5045d2638c29 | 381 | DYNAMIC_TYPE_METHOD); |
toddouska | 0:5045d2638c29 | 382 | if (method) { |
toddouska | 0:5045d2638c29 | 383 | InitSSL_Method(method, MakeTLSv1()); |
toddouska | 0:5045d2638c29 | 384 | method->side = SERVER_END; |
toddouska | 0:5045d2638c29 | 385 | } |
toddouska | 0:5045d2638c29 | 386 | return method; |
toddouska | 0:5045d2638c29 | 387 | } |
toddouska | 0:5045d2638c29 | 388 | |
toddouska | 0:5045d2638c29 | 389 | |
toddouska | 0:5045d2638c29 | 390 | SSL_METHOD* TLSv1_1_server_method(void) |
toddouska | 0:5045d2638c29 | 391 | { |
toddouska | 0:5045d2638c29 | 392 | SSL_METHOD* method = (SSL_METHOD*) XMALLOC(sizeof(SSL_METHOD), 0, |
toddouska | 0:5045d2638c29 | 393 | DYNAMIC_TYPE_METHOD); |
toddouska | 0:5045d2638c29 | 394 | if (method) { |
toddouska | 0:5045d2638c29 | 395 | InitSSL_Method(method, MakeTLSv1_1()); |
toddouska | 0:5045d2638c29 | 396 | method->side = SERVER_END; |
toddouska | 0:5045d2638c29 | 397 | } |
toddouska | 0:5045d2638c29 | 398 | return method; |
toddouska | 0:5045d2638c29 | 399 | } |
toddouska | 0:5045d2638c29 | 400 | |
toddouska | 0:5045d2638c29 | 401 | |
toddouska | 0:5045d2638c29 | 402 | SSL_METHOD* TLSv1_2_server_method(void) |
toddouska | 0:5045d2638c29 | 403 | { |
toddouska | 0:5045d2638c29 | 404 | SSL_METHOD* method = (SSL_METHOD*) XMALLOC(sizeof(SSL_METHOD), 0, |
toddouska | 0:5045d2638c29 | 405 | DYNAMIC_TYPE_METHOD); |
toddouska | 0:5045d2638c29 | 406 | if (method) { |
toddouska | 0:5045d2638c29 | 407 | InitSSL_Method(method, MakeTLSv1_2()); |
toddouska | 0:5045d2638c29 | 408 | method->side = SERVER_END; |
toddouska | 0:5045d2638c29 | 409 | } |
toddouska | 0:5045d2638c29 | 410 | return method; |
toddouska | 0:5045d2638c29 | 411 | } |
toddouska | 0:5045d2638c29 | 412 | |
toddouska | 0:5045d2638c29 | 413 | |
toddouska | 0:5045d2638c29 | 414 | SSL_METHOD *SSLv23_server_method(void) |
toddouska | 0:5045d2638c29 | 415 | { |
toddouska | 0:5045d2638c29 | 416 | SSL_METHOD* method = (SSL_METHOD*) XMALLOC(sizeof(SSL_METHOD), 0, |
toddouska | 0:5045d2638c29 | 417 | DYNAMIC_TYPE_METHOD); |
toddouska | 0:5045d2638c29 | 418 | if (method) { |
toddouska | 0:5045d2638c29 | 419 | InitSSL_Method(method, MakeTLSv1()); |
toddouska | 0:5045d2638c29 | 420 | method->side = SERVER_END; |
toddouska | 0:5045d2638c29 | 421 | method->downgrade = 1; |
toddouska | 0:5045d2638c29 | 422 | } |
toddouska | 0:5045d2638c29 | 423 | return method; |
toddouska | 0:5045d2638c29 | 424 | } |
toddouska | 0:5045d2638c29 | 425 | |
toddouska | 0:5045d2638c29 | 426 | |
toddouska | 0:5045d2638c29 | 427 | |
toddouska | 0:5045d2638c29 | 428 | #endif /* NO_CYASSL_SERVER */ |
toddouska | 0:5045d2638c29 | 429 | |
toddouska | 0:5045d2638c29 | 430 | #else /* NO_TLS */ |
toddouska | 0:5045d2638c29 | 431 | |
toddouska | 0:5045d2638c29 | 432 | /* catch CyaSSL programming errors */ |
toddouska | 0:5045d2638c29 | 433 | void BuildTlsFinished(SSL* ssl, Hashes* hashes, const byte* sender) |
toddouska | 0:5045d2638c29 | 434 | { |
toddouska | 0:5045d2638c29 | 435 | |
toddouska | 0:5045d2638c29 | 436 | } |
toddouska | 0:5045d2638c29 | 437 | |
toddouska | 0:5045d2638c29 | 438 | |
toddouska | 0:5045d2638c29 | 439 | int DeriveTlsKeys(SSL* ssl) |
toddouska | 0:5045d2638c29 | 440 | { |
toddouska | 0:5045d2638c29 | 441 | return -1; |
toddouska | 0:5045d2638c29 | 442 | } |
toddouska | 0:5045d2638c29 | 443 | |
toddouska | 0:5045d2638c29 | 444 | |
toddouska | 0:5045d2638c29 | 445 | int MakeTlsMasterSecret(SSL* ssl) |
toddouska | 0:5045d2638c29 | 446 | { |
toddouska | 0:5045d2638c29 | 447 | return -1; |
toddouska | 0:5045d2638c29 | 448 | } |
toddouska | 0:5045d2638c29 | 449 | |
toddouska | 0:5045d2638c29 | 450 | #endif /* NO_TLS */ |
toddouska | 0:5045d2638c29 | 451 |