1 /*
2 * tls.c
3 * Release $Name: MATRIXSSL-3-3-0-OPEN $
4 *
5 * TLS (SSLv3.1+) specific code
6 * http://www.faqs.org/rfcs/rfc2246.html
7 * Primarily dealing with secret generation, message authentication codes
8 * and handshake hashing.
9 */
10 /*
11 * Copyright (c) AuthenTec, Inc. 2011-2012
12 * Copyright (c) PeerSec Networks, 2002-2011
13 * All Rights Reserved
14 *
15 * The latest version of this code is available at http://www.matrixssl.org
16 *
17 * This software is open source; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This General Public License does NOT permit incorporating this software
23 * into proprietary programs. If you are unable to comply with the GPL, a
24 * commercial license for this software may be purchased from AuthenTec at
25 * http://www.authentec.com/Products/EmbeddedSecurity/SecurityToolkits.aspx
26 *
27 * This program is distributed in WITHOUT ANY WARRANTY; without even the
28 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
29 * See the GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 * http://www.gnu.org/copyleft/gpl.html
35 */
36 /******************************************************************************/
37
38 #include "matrixsslApi.h"
39
40 /******************************************************************************/
41 #ifdef USE_TLS
42 /******************************************************************************/
43
44 #define LABEL_SIZE 13
45 #define LABEL_MASTERSEC "master secret"
46 #define LABEL_KEY_BLOCK "key expansion"
47
48 #define FINISHED_LABEL_SIZE 15
49 #define LABEL_CLIENT "client finished"
50 #define LABEL_SERVER "server finished"
51
52 static int32 prf(unsigned char *sec, uint32 secLen, unsigned char *seed,
53 uint32 seedLen, unsigned char *out, uint32 outLen);
54
55
56 /******************************************************************************/
57 /*
58 * Generates all key material.
59 */
tlsDeriveKeys(ssl_t * ssl)60 int32 tlsDeriveKeys(ssl_t *ssl)
61 {
62 unsigned char msSeed[SSL_HS_RANDOM_SIZE * 2 + LABEL_SIZE];
63 uint32 reqKeyLen;
64 /*
65 If this session is resumed, we want to reuse the master secret to
66 regenerate the key block with the new random values.
67 */
68 if (ssl->flags & SSL_FLAGS_RESUMED) {
69 goto skipPremaster;
70 }
71 /*
72 master_secret = PRF(pre_master_secret, "master secret",
73 client_random + server_random);
74 */
75 memcpy(msSeed, LABEL_MASTERSEC, LABEL_SIZE);
76 memcpy(msSeed + LABEL_SIZE, ssl->sec.clientRandom,
77 SSL_HS_RANDOM_SIZE);
78 memcpy(msSeed + LABEL_SIZE + SSL_HS_RANDOM_SIZE,
79 ssl->sec.serverRandom, SSL_HS_RANDOM_SIZE);
80 prf(ssl->sec.premaster, ssl->sec.premasterSize, msSeed,
81 (SSL_HS_RANDOM_SIZE * 2) + LABEL_SIZE, ssl->sec.masterSecret,
82 SSL_HS_MASTER_SIZE);
83
84 /*
85 premaster is now allocated for DH reasons. Can free here
86 */
87 psFree(ssl->sec.premaster);
88 ssl->sec.premaster = NULL;
89 ssl->sec.premasterSize = 0;
90
91 skipPremaster:
92 memcpy(msSeed, LABEL_KEY_BLOCK, LABEL_SIZE);
93 memcpy(msSeed + LABEL_SIZE, ssl->sec.serverRandom,
94 SSL_HS_RANDOM_SIZE);
95 memcpy(msSeed + LABEL_SIZE + SSL_HS_RANDOM_SIZE,
96 ssl->sec.clientRandom, SSL_HS_RANDOM_SIZE);
97 /*
98 We must generate enough key material to fill the various keys
99 */
100 reqKeyLen = 2 * ssl->cipher->macSize +
101 2 * ssl->cipher->keySize +
102 2 * ssl->cipher->ivSize;
103
104 prf(ssl->sec.masterSecret, SSL_HS_MASTER_SIZE, msSeed,
105 (SSL_HS_RANDOM_SIZE * 2) + LABEL_SIZE, ssl->sec.keyBlock,
106 reqKeyLen);
107 if (ssl->flags & SSL_FLAGS_SERVER) {
108 ssl->sec.rMACptr = ssl->sec.keyBlock;
109 ssl->sec.wMACptr = ssl->sec.rMACptr + ssl->cipher->macSize;
110 ssl->sec.rKeyptr = ssl->sec.wMACptr + ssl->cipher->macSize;
111 ssl->sec.wKeyptr = ssl->sec.rKeyptr + ssl->cipher->keySize;
112 ssl->sec.rIVptr = ssl->sec.wKeyptr + ssl->cipher->keySize;
113 ssl->sec.wIVptr = ssl->sec.rIVptr + ssl->cipher->ivSize;
114 } else {
115 ssl->sec.wMACptr = ssl->sec.keyBlock;
116 ssl->sec.rMACptr = ssl->sec.wMACptr + ssl->cipher->macSize;
117 ssl->sec.wKeyptr = ssl->sec.rMACptr + ssl->cipher->macSize;
118 ssl->sec.rKeyptr = ssl->sec.wKeyptr + ssl->cipher->keySize;
119 ssl->sec.wIVptr = ssl->sec.rKeyptr + ssl->cipher->keySize;
120 ssl->sec.rIVptr = ssl->sec.wIVptr + ssl->cipher->ivSize;
121 }
122
123 return SSL_HS_MASTER_SIZE;
124 }
125
126 #ifdef USE_SHA_MAC
127 /******************************************************************************/
128 /*
129 TLS sha1 HMAC generate/verify
130 */
tlsHMACSha1(ssl_t * ssl,int32 mode,unsigned char type,unsigned char * data,uint32 len,unsigned char * mac)131 int32 tlsHMACSha1(ssl_t *ssl, int32 mode, unsigned char type,
132 unsigned char *data, uint32 len, unsigned char *mac)
133 {
134 psHmacContext_t ctx;
135 unsigned char *key, *seq;
136 unsigned char majVer, minVer, tmp[5];
137 int32 i;
138
139 majVer = ssl->majVer;
140 minVer = ssl->minVer;
141
142 if (mode == HMAC_CREATE) {
143 key = ssl->sec.writeMAC;
144 seq = ssl->sec.seq;
145 } else { /* HMAC_VERIFY */
146 key = ssl->sec.readMAC;
147 seq = ssl->sec.remSeq;
148 }
149
150 psHmacSha1Init(&ctx, key, SHA1_HASH_SIZE);
151 psHmacSha1Update(&ctx, seq, 8);
152 for (i = 7; i >= 0; i--) {
153 seq[i]++;
154 if (seq[i] != 0) {
155 break;
156 }
157 }
158
159 tmp[0] = type;
160 tmp[1] = majVer;
161 tmp[2] = minVer;
162 tmp[3] = (len & 0xFF00) >> 8;
163 tmp[4] = len & 0xFF;
164 psHmacSha1Update(&ctx, tmp, 5);
165 psHmacSha1Update(&ctx, data, len);
166 return psHmacSha1Final(&ctx, mac);
167 }
168
169
170 #endif /* USE_SHA_MAC */
171
172 #ifdef USE_MD5_MAC
173 /******************************************************************************/
174 /*
175 TLS MD5 HMAC generate/verify
176 */
tlsHMACMd5(ssl_t * ssl,int32 mode,unsigned char type,unsigned char * data,uint32 len,unsigned char * mac)177 int32 tlsHMACMd5(ssl_t *ssl, int32 mode, unsigned char type,
178 unsigned char *data, uint32 len, unsigned char *mac)
179 {
180 psHmacContext_t ctx;
181 unsigned char *key, *seq;
182 unsigned char majVer, minVer, tmp[5];
183 int32 i;
184
185 majVer = ssl->majVer;
186 minVer = ssl->minVer;
187
188 if (mode == HMAC_CREATE) {
189 key = ssl->sec.writeMAC;
190 seq = ssl->sec.seq;
191 } else { /* HMAC_VERIFY */
192 key = ssl->sec.readMAC;
193 seq = ssl->sec.remSeq;
194 }
195
196 psHmacMd5Init(&ctx, key, MD5_HASH_SIZE);
197 psHmacMd5Update(&ctx, seq, 8);
198 for (i = 7; i >= 0; i--) {
199 seq[i]++;
200 if (seq[i] != 0) {
201 break;
202 }
203 }
204
205 tmp[0] = type;
206 tmp[1] = majVer;
207 tmp[2] = minVer;
208 tmp[3] = (len & 0xFF00) >> 8;
209 tmp[4] = len & 0xFF;
210 psHmacMd5Update(&ctx, tmp, 5);
211 psHmacMd5Update(&ctx, data, len);
212 return psHmacMd5Final(&ctx, mac);
213 }
214 #endif /* USE_MD5_MAC */
215
216 /******************************************************************************/
217 /*
218 TLS handshake has computation
219 */
tlsGenerateFinishedHash(ssl_t * ssl,psDigestContext_t * md5,psDigestContext_t * sha1,psDigestContext_t * sha256,unsigned char * masterSecret,unsigned char * out,int32 sender)220 int32 tlsGenerateFinishedHash(ssl_t *ssl, psDigestContext_t *md5,
221 psDigestContext_t *sha1, psDigestContext_t *sha256,
222 unsigned char *masterSecret, unsigned char *out, int32 sender)
223 {
224 unsigned char tmp[FINISHED_LABEL_SIZE + MD5_HASH_SIZE + SHA1_HASH_SIZE];
225
226 if (sender >= 0) {
227 memcpy(tmp, (sender & SSL_FLAGS_SERVER) ? LABEL_SERVER : LABEL_CLIENT,
228 FINISHED_LABEL_SIZE);
229 psMd5Final(md5, tmp + FINISHED_LABEL_SIZE);
230 psSha1Final(sha1, tmp + FINISHED_LABEL_SIZE + MD5_HASH_SIZE);
231 return prf(masterSecret, SSL_HS_MASTER_SIZE, tmp, sizeof(tmp),
232 out, TLS_HS_FINISHED_SIZE);
233 } else {
234 /*
235 The handshake snapshot for client authentication is simply the
236 appended MD5 and SHA1 hashes
237 */
238 psMd5Final(md5, out);
239 psSha1Final(sha1, out + MD5_HASH_SIZE);
240 return MD5_HASH_SIZE + SHA1_HASH_SIZE;
241 }
242 return PS_FAILURE; /* Should not reach this */
243 }
244
245 /******************************************************************************/
246 /*
247 MD5 portions of the prf
248 */
pMd5(unsigned char * key,uint32 keyLen,unsigned char * text,uint32 textLen,unsigned char * out,uint32 outLen)249 static int32 pMd5(unsigned char *key, uint32 keyLen,
250 unsigned char *text, uint32 textLen,
251 unsigned char *out, uint32 outLen)
252 {
253 psHmacContext_t ctx;
254 unsigned char a[MD5_HASH_SIZE];
255 unsigned char mac[MD5_HASH_SIZE];
256 unsigned char hmacKey[MD5_HASH_SIZE];
257 int32 i, keyIter = 1;
258 uint32 hmacKeyLen;
259
260 while ((uint32)(MD5_HASH_SIZE * keyIter) < outLen) {
261 keyIter++;
262 }
263 psHmacMd5(key, keyLen, text, textLen, a, hmacKey, &hmacKeyLen);
264 if (hmacKeyLen != keyLen) {
265 /*
266 Support for keys larger than 64 bytes. Must take the hash of
267 the original key in these cases which is indicated by different
268 outgoing values from the passed in key and keyLen values
269 */
270 psAssert(keyLen > 64);
271 key = hmacKey;
272 keyLen = hmacKeyLen;
273 }
274 for (i = 0; i < keyIter; i++) {
275 psHmacMd5Init(&ctx, key, keyLen);
276 psHmacMd5Update(&ctx, a, MD5_HASH_SIZE);
277 psHmacMd5Update(&ctx, text, textLen);
278 psHmacMd5Final(&ctx, mac);
279 if (i == keyIter - 1) {
280 memcpy(out + (MD5_HASH_SIZE*i), mac, outLen - (MD5_HASH_SIZE*i));
281 } else {
282 memcpy(out + (MD5_HASH_SIZE * i), mac, MD5_HASH_SIZE);
283 psHmacMd5(key, keyLen, a, MD5_HASH_SIZE, a, hmacKey, &hmacKeyLen);
284 }
285 }
286 return 0;
287 }
288
289 /******************************************************************************/
290 /*
291 SHA1 portion of the prf
292 */
pSha1(unsigned char * key,uint32 keyLen,unsigned char * text,uint32 textLen,unsigned char * out,uint32 outLen)293 static int32 pSha1(unsigned char *key, uint32 keyLen,
294 unsigned char *text, uint32 textLen,
295 unsigned char *out, uint32 outLen)
296 {
297 psHmacContext_t ctx;
298 unsigned char a[SHA1_HASH_SIZE];
299 unsigned char mac[SHA1_HASH_SIZE];
300 unsigned char hmacKey[SHA1_HASH_SIZE];
301 int32 i, keyIter = 1;
302 uint32 hmacKeyLen;
303
304 while ((uint32)(SHA1_HASH_SIZE * keyIter) < outLen) {
305 keyIter++;
306 }
307 psHmacSha1(key, keyLen, text, textLen, a, hmacKey, &hmacKeyLen);
308 if (hmacKeyLen != keyLen) {
309 /*
310 Support for keys larger than 64 bytes. Must take the hash of
311 the original key in these cases which is indicated by different
312 outgoing values from the passed in key and keyLen values
313 */
314 psAssert(keyLen > 64);
315 key = hmacKey;
316 keyLen = hmacKeyLen;
317 }
318 for (i = 0; i < keyIter; i++) {
319 psHmacSha1Init(&ctx, key, keyLen);
320 psHmacSha1Update(&ctx, a, SHA1_HASH_SIZE);
321 psHmacSha1Update(&ctx, text, textLen);
322 psHmacSha1Final(&ctx, mac);
323 if (i == keyIter - 1) {
324 memcpy(out + (SHA1_HASH_SIZE * i), mac,
325 outLen - (SHA1_HASH_SIZE * i));
326 } else {
327 memcpy(out + (SHA1_HASH_SIZE * i), mac, SHA1_HASH_SIZE);
328 psHmacSha1(key, keyLen, a, SHA1_HASH_SIZE, a, hmacKey,
329 &hmacKeyLen);
330 }
331 }
332 return 0;
333 }
334
335
336 /******************************************************************************/
337 /*
338 Psuedo-random function. TLS uses this for key generation and hashing
339 */
prf(unsigned char * sec,uint32 secLen,unsigned char * seed,uint32 seedLen,unsigned char * out,uint32 outLen)340 static int32 prf(unsigned char *sec, uint32 secLen, unsigned char *seed,
341 uint32 seedLen, unsigned char *out, uint32 outLen)
342 {
343 unsigned char *s1, *s2;
344 unsigned char md5out[SSL_MAX_KEY_BLOCK_SIZE];
345 unsigned char sha1out[SSL_MAX_KEY_BLOCK_SIZE];
346 uint32 sLen, i;
347
348 psAssert(outLen <= SSL_MAX_KEY_BLOCK_SIZE);
349
350 sLen = (secLen / 2) + (secLen % 2);
351 s1 = sec;
352 s2 = (sec + sLen) - (secLen % 2);
353 pMd5(s1, sLen, seed, seedLen, md5out, outLen);
354 pSha1(s2, sLen, seed, seedLen, sha1out, outLen);
355 for (i = 0; i < outLen; i++) {
356 out[i] = md5out[i] ^ sha1out[i];
357 }
358 return outLen;
359 }
360
361
362 /******************************************************************************/
363 #endif /* USE_TLS */
364
365 #ifdef USE_CLIENT_SIDE_SSL
366 /******************************************************************************/
367 /*
368 Allocate a tlsExtenstion_t structure
369 */
matrixSslNewHelloExtension(tlsExtension_t ** extension)370 int32 matrixSslNewHelloExtension(tlsExtension_t **extension)
371 {
372 psPool_t *pool = NULL;
373 tlsExtension_t *ext;
374
375
376 ext = psMalloc(pool, sizeof(tlsExtension_t));
377 if (ext == NULL) {
378 return PS_MEM_FAIL;
379 }
380 memset(ext, 0x0, sizeof(tlsExtension_t));
381 ext->pool = pool;
382
383 *extension = ext;
384 return PS_SUCCESS;
385 }
386
387 /******************************************************************************/
388 /*
389 Free a tlsExtenstion_t structure and any extensions that have been loaded
390 */
matrixSslDeleteHelloExtension(tlsExtension_t * extension)391 void matrixSslDeleteHelloExtension(tlsExtension_t *extension)
392 {
393 tlsExtension_t *next, *ext;
394
395 if (extension == NULL) {
396 return;
397 }
398 ext = extension;
399 /*
400 Free first one
401 */
402 if (ext->extData) {
403 psFree(ext->extData);
404 }
405 next = ext->next;
406 psFree(ext);
407 /*
408 Free others
409 */
410 while (next) {
411 ext = next;
412 next = ext->next;
413 if (ext->extData) {
414 psFree(ext->extData);
415 }
416 psFree(ext);
417 }
418
419 return;
420 }
421
422 /*****************************************************************************/
423 /*
424 Add an outgoing CLIENT_HELLO extension to a tlsExtension_t structure
425 that was previously allocated with matrixSslNewHelloExtension
426 */
matrixSslLoadHelloExtension(tlsExtension_t * ext,unsigned char * extension,uint32 length,uint32 extType)427 int32 matrixSslLoadHelloExtension(tlsExtension_t *ext,
428 unsigned char *extension, uint32 length, uint32 extType)
429 {
430 tlsExtension_t *current, *new;
431
432 if (ext == NULL || (length > 0 && extension == NULL)) {
433 return PS_ARG_FAIL;
434 }
435 /*
436 Find first empty spot in ext. This is determined by extLen since even
437 an empty extension will have a length of 1 for the 0
438 */
439 current = ext;
440 while (current->extLen != 0) {
441 if (current->next != NULL) {
442 current = current->next;
443 continue;
444 }
445 new = psMalloc(ext->pool, sizeof(tlsExtension_t));
446 if (new == NULL) {
447 return PS_MEM_FAIL;
448 }
449 memset(new, 0, sizeof(tlsExtension_t));
450 new->pool = ext->pool;
451 current->next = new;
452 current = new;
453 }
454 /*
455 Supports an empty extension which is really a one byte 00:
456 ff 01 00 01 00 (two byte type, two byte len, one byte 00)
457
458 This will either be passed in as a NULL 'extension' with a 0 length - OR -
459 A pointer to a one byte 0x0 and a length of 1. In either case, the
460 structure will identify the ext with a length of 1 and a NULL data ptr
461 */
462 current->extType = extType;
463 if (length > 0) {
464 current->extLen = length;
465 if (length == 1 && extension[0] == '\0') {
466 current->extLen = 1;
467 } else {
468 current->extData = psMalloc(ext->pool, length);
469 if (current->extData == NULL) {
470 return PS_MEM_FAIL;
471 }
472 memcpy(current->extData, extension, length);
473 }
474 } else if (length == 0) {
475 current->extLen = 1;
476 }
477
478 return PS_SUCCESS;
479 }
480 #endif /* USE_CLIENT_SIDE_SSL */
481
482
483
484
485 /******************************************************************************/
486
487