]> git.saurik.com Git - apple/security.git/blob - libsecurity_ssl/lib/tls1Callouts.c
ca06db05a83c10094924b8261a06101b6c668070
[apple/security.git] / libsecurity_ssl / lib / tls1Callouts.c
1 /*
2 * Copyright (c) 2002,2005-2007,2010-2012 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * tls1Callouts.c - TLSv1-specific routines for SslTlsCallouts.
26 */
27
28 #include "tls_ssl.h"
29 #include "sslMemory.h"
30 #include "sslUtils.h"
31 #include "sslDigests.h"
32 #include "sslAlertMessage.h"
33 #include "sslCrypto.h"
34 #include "sslDebug.h"
35 #include <assert.h>
36 #include <strings.h>
37
38 #define TLS_ENC_DEBUG 0
39 #if TLS_ENC_DEBUG
40 #define tlsDebug(format, args...) printf(format , ## args)
41 static void tlsDump(const char *name, void *b, unsigned len)
42 {
43 unsigned char *cp = (unsigned char *)b;
44 unsigned i, dex;
45
46 printf("%s\n", name);
47 for(dex=0; dex<len; dex++) {
48 i = cp[dex];
49 printf("%02X ", i);
50 if((dex % 16) == 15) {
51 printf("\n");
52 }
53 }
54 printf("\n");
55 }
56
57 #else
58 #define tlsDebug(s, ...)
59 #define tlsDump(name, b, len)
60 #endif /* TLS_ENC_DEBUG */
61
62 #pragma mark -
63 #pragma mark PRF label strings
64 /*
65 * Note we could optimize away a bunch of mallocs and frees if we, like openSSL,
66 * just mallocd buffers for inputs to SSLInternal_PRF() on the stack,
67 * with "known" max values for all of the inputs.
68 *
69 * At least we hard-code string lengths here instead of calling strlen at runtime...
70 */
71 #define PLS_MASTER_SECRET "master secret"
72 #define PLS_MASTER_SECRET_LEN 13
73 #define PLS_KEY_EXPAND "key expansion"
74 #define PLS_KEY_EXPAND_LEN 13
75 #define PLS_CLIENT_FINISH "client finished"
76 #define PLS_CLIENT_FINISH_LEN 15
77 #define PLS_SERVER_FINISH "server finished"
78 #define PLS_SERVER_FINISH_LEN 15
79 #define PLS_EXPORT_CLIENT_WRITE "client write key"
80 #define PLS_EXPORT_CLIENT_WRITE_LEN 16
81 #define PLS_EXPORT_SERVER_WRITE "server write key"
82 #define PLS_EXPORT_SERVER_WRITE_LEN 16
83 #define PLS_EXPORT_IV_BLOCK "IV block"
84 #define PLS_EXPORT_IV_BLOCK_LEN 8
85
86 #pragma mark -
87 #pragma mark private functions
88
89 /*
90 * P_Hash function defined in RFC2246, section 5.
91 */
92 static OSStatus tlsPHash(
93 SSLContext *ctx,
94 const HMACReference *hmac, // &TlsHmacSHA1, TlsHmacMD5
95 const uint8_t *secret,
96 size_t secretLen,
97 const uint8_t *seed,
98 size_t seedLen,
99 uint8_t *out, // mallocd by caller, size >= outLen
100 size_t outLen) // desired output size
101 {
102 unsigned char aSubI[TLS_HMAC_MAX_SIZE]; /* A(i) */
103 unsigned char digest[TLS_HMAC_MAX_SIZE];
104 HMACContextRef hmacCtx;
105 OSStatus serr;
106 size_t digestLen = hmac->macSize;
107
108 serr = hmac->alloc(hmac, ctx, secret, secretLen, &hmacCtx);
109 if(serr) {
110 return serr;
111 }
112
113 /* A(0) = seed */
114 /* A(1) := HMAC_hash(secret, seed) */
115 serr = hmac->hmac(hmacCtx, seed, seedLen, aSubI, &digestLen);
116 if(serr) {
117 goto fail;
118 }
119 assert(digestLen = hmac->macSize);
120
121 /* starting at loopNum 1... */
122 for (;;) {
123 /*
124 * This loop's chunk = HMAC_hash(secret, A(loopNum) + seed))
125 */
126 serr = hmac->init(hmacCtx);
127 if(serr) {
128 break;
129 }
130 serr = hmac->update(hmacCtx, aSubI, digestLen);
131 if(serr) {
132 break;
133 }
134 serr = hmac->update(hmacCtx, seed, seedLen);
135 if(serr) {
136 break;
137 }
138 serr = hmac->final(hmacCtx, digest, &digestLen);
139 if(serr) {
140 break;
141 }
142 assert(digestLen = hmac->macSize);
143
144 if(outLen <= digestLen) {
145 /* last time, possible partial digest */
146 memmove(out, digest, outLen);
147 break;
148 }
149
150 memmove(out, digest, digestLen);
151 out += digestLen;
152 outLen -= digestLen;
153
154 /*
155 * A(i) = HMAC_hash(secret, A(i-1))
156 * Note there is a possible optimization involving obtaining this
157 * hmac by cloning the state of hmacCtx above after updating with
158 * aSubI, and getting the final version of that here. However CDSA
159 * does not support cloning of a MAC context (only for digest contexts).
160 */
161 serr = hmac->hmac(hmacCtx, aSubI, digestLen,
162 aSubI, &digestLen);
163 if(serr) {
164 break;
165 }
166 assert(digestLen = hmac->macSize);
167 }
168 fail:
169 hmac->free(hmacCtx);
170 memset(aSubI, 0, TLS_HMAC_MAX_SIZE);
171 memset(digest, 0, TLS_HMAC_MAX_SIZE);
172 return serr;
173 }
174
175 /*
176 * The TLS pseudorandom function, defined in RFC2246, section 5.
177 * This takes as its input a secret block, a label, and a seed, and produces
178 * a caller-specified length of pseudorandom data.
179 *
180 * Optimization TBD: make label optional, avoid malloc and two copies if it's
181 * not there, so callers can take advantage of fixed-size seeds.
182 */
183 OSStatus SSLInternal_PRF(
184 SSLContext *ctx,
185 const void *vsecret,
186 size_t secretLen,
187 const void *label, // optional, NULL implies that seed contains
188 // the label
189 size_t labelLen,
190 const void *seed,
191 size_t seedLen,
192 void *vout, // mallocd by caller, length >= outLen
193 size_t outLen)
194 {
195 OSStatus serr = errSSLInternal;
196 const unsigned char *S1, *S2; // the two seeds
197 size_t sLen; // effective length of each seed
198 unsigned char *labelSeed = NULL; // label + seed, passed to tlsPHash
199 size_t labelSeedLen;
200 unsigned char *tmpOut = NULL; // output of P_SHA1
201 size_t i;
202 const unsigned char *secret = (const unsigned char *)vsecret;
203
204 if(label != NULL) {
205 /* concatenate label and seed */
206 labelSeedLen = labelLen + seedLen;
207 labelSeed = (unsigned char *)sslMalloc(labelSeedLen);
208 if(labelSeed == NULL) {
209 return memFullErr;
210 }
211 memmove(labelSeed, label, labelLen);
212 memmove(labelSeed + labelLen, seed, seedLen);
213 }
214 else {
215 /* fast track - just use seed as is */
216 labelSeed = (unsigned char *)seed;
217 labelSeedLen = seedLen;
218 }
219
220 unsigned char *out = (unsigned char *)vout;
221 if(sslVersionIsLikeTls12(ctx)) {
222 const HMACReference *mac = &TlsHmacSHA256;
223 if (ctx->selectedCipherSpec.macAlgorithm->hmac->alg == HA_SHA384) {
224 mac = ctx->selectedCipherSpec.macAlgorithm->hmac;
225 }
226 serr = tlsPHash(ctx, mac, secret, secretLen, labelSeed, labelSeedLen,
227 out, outLen);
228 if(serr) {
229 goto fail;
230 }
231 } else {
232 /* two seeds for tlsPHash */
233 sLen = secretLen / 2; // for partitioning
234 S1 = secret;
235 S2 = &secret[sLen];
236 sLen += (secretLen & 1); // secret length odd, increment effective size
237
238 /* temporary output for SHA1, to be XORd with MD5 */
239 tmpOut = (unsigned char *)sslMalloc(outLen);
240 if(tmpOut == NULL) {
241 serr = memFullErr;
242 goto fail;
243 }
244
245 serr = tlsPHash(ctx, &TlsHmacMD5, S1, sLen, labelSeed, labelSeedLen,
246 out, outLen);
247 if(serr) {
248 goto fail;
249 }
250 serr = tlsPHash(ctx, &TlsHmacSHA1, S2, sLen, labelSeed, labelSeedLen,
251 tmpOut, outLen);
252 if(serr) {
253 goto fail;
254 }
255
256 /* XOR together to get final result */
257 for(i=0; i<outLen; i++) {
258 out[i] ^= tmpOut[i];
259 }
260 }
261
262 serr = noErr;
263 fail:
264 if((labelSeed != NULL) && (label != NULL)) {
265 sslFree(labelSeed);
266 }
267 if(tmpOut != NULL) {
268 sslFree(tmpOut);
269 }
270 return serr;
271 }
272
273 /* not needed; encrypt/encode is the same for both protocols as long as
274 * we don't use the "variable length padding" feature. */
275 #if 0
276 static OSStatus tls1WriteRecord(
277 SSLRecord rec,
278 SSLContext *ctx)
279 {
280 assert(0);
281 return unimpErr;
282 }
283 #endif
284
285 static OSStatus tls1DecryptRecord(
286 UInt8 type,
287 SSLBuffer *payload,
288 SSLContext *ctx)
289 {
290 OSStatus err;
291 SSLBuffer content;
292 bool decryption_failed_or_bad_record_mac = false;
293
294 if ((ctx->readCipher.symCipher->blockSize > 0) &&
295 ((payload->length % ctx->readCipher.symCipher->blockSize) != 0)) {
296 SSLFatalSessionAlert(SSL_AlertRecordOverflow, ctx);
297 return errSSLRecordOverflow;
298 }
299
300 /* Decrypt in place */
301 if ((err = ctx->readCipher.symCipher->decrypt(payload->data,
302 payload->data, payload->length,
303 &ctx->readCipher,
304 ctx)) != 0)
305 {
306 /* note: we no longer send a SSL_AlertDecryptError here;
307 * all subsequent failures result in SSL_AlertBadRecordMac
308 * being sent at the end of the function, to avoid leaking
309 * differences between padding and decryption failures. */
310 decryption_failed_or_bad_record_mac = true;
311 }
312
313 /* Locate content within decrypted payload */
314
315 /* TLS 1.1 and DTLS 1.0 block ciphers */
316 if((ctx->negProtocolVersion>=TLS_Version_1_1) && (ctx->readCipher.symCipher->blockSize>0))
317 {
318 content.data = payload->data + ctx->readCipher.symCipher->blockSize;
319 content.length = payload->length - (ctx->readCipher.macRef->hash->digestSize + ctx->readCipher.symCipher->blockSize);
320 } else {
321 content.data = payload->data;
322 content.length = payload->length - ctx->readCipher.macRef->hash->digestSize;
323 }
324
325 if (ctx->readCipher.symCipher->blockSize > 0) {
326 /* for TLSv1, padding can be anywhere from 0 to 255 bytes */
327 UInt8 padSize = payload->data[payload->length - 1];
328 UInt8 *padChars;
329
330 /* verify that all padding bytes are equal - WARNING - OpenSSL code
331 * has a special case here dealing with some kind of bug related to
332 * even size packets...beware... */
333 if(padSize > payload->length) {
334 /* This is TLS 1.1 compliant - Do it for all protocols versions */
335 sslErrorLog("tls1DecryptRecord: bad padding length (%d)\n",
336 (unsigned)payload->data[payload->length - 1]);
337 decryption_failed_or_bad_record_mac = true;
338 }
339 padChars = payload->data + payload->length - padSize;
340 while(padChars < (payload->data + payload->length)) {
341 if(*padChars++ != padSize) {
342 /* This is TLS 1.1 compliant - Do it for all protocols versions */
343 sslErrorLog("tls1DecryptRecord: bad padding value\n");
344 decryption_failed_or_bad_record_mac = true;
345 }
346 }
347 /* Remove block size padding and its one-byte length */
348 content.length -= (1 + padSize);
349 }
350
351 /* Verify MAC on payload */
352 if (ctx->readCipher.macRef->hash->digestSize > 0)
353 /* Optimize away MAC for null case */
354 if ((err = SSLVerifyMac(type, &content,
355 content.data + content.length, ctx)) != 0)
356 {
357 decryption_failed_or_bad_record_mac = true;
358 }
359
360 if (decryption_failed_or_bad_record_mac) {
361 SSLFatalSessionAlert(SSL_AlertBadRecordMac, ctx);
362 return errSSLDecryptionFail;
363 }
364
365 *payload = content; /* Modify payload buffer to indicate content length */
366
367 return noErr;
368 }
369
370 /* initialize a per-CipherContext HashHmacContext for use in MACing each record */
371 static OSStatus tls1InitMac (
372 CipherContext *cipherCtx, // macRef, macSecret valid on entry
373 // macCtx valid on return
374 SSLContext *ctx)
375 {
376 const HMACReference *hmac;
377 OSStatus serr;
378
379 assert(cipherCtx->macRef != NULL);
380 hmac = cipherCtx->macRef->hmac;
381 assert(hmac != NULL);
382
383 if(cipherCtx->macCtx.hmacCtx != NULL) {
384 hmac->free(cipherCtx->macCtx.hmacCtx);
385 cipherCtx->macCtx.hmacCtx = NULL;
386 }
387 serr = hmac->alloc(hmac, ctx, cipherCtx->macSecret,
388 cipherCtx->macRef->hmac->macSize, &cipherCtx->macCtx.hmacCtx);
389
390 /* mac secret now stored in macCtx.hmacCtx, delete it from cipherCtx */
391 memset(cipherCtx->macSecret, 0, sizeof(cipherCtx->macSecret));
392 return serr;
393 }
394
395 static OSStatus tls1FreeMac (
396 CipherContext *cipherCtx)
397 {
398 /* this can be called on a completely zeroed out CipherContext... */
399 if(cipherCtx->macRef == NULL) {
400 return noErr;
401 }
402 assert(cipherCtx->macRef->hmac != NULL);
403
404 if(cipherCtx->macCtx.hmacCtx != NULL) {
405 cipherCtx->macRef->hmac->free(cipherCtx->macCtx.hmacCtx);
406 cipherCtx->macCtx.hmacCtx = NULL;
407 }
408 return noErr;
409 }
410
411 /*
412 * mac = HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type +
413 * TLSCompressed.version + TLSCompressed.length +
414 * TLSCompressed.fragment));
415 */
416
417 /* sequence, type, version, length */
418 #define HDR_LENGTH (8 + 1 + 2 + 2)
419 static OSStatus tls1ComputeMac (
420 UInt8 type,
421 SSLBuffer data,
422 SSLBuffer mac, // caller mallocs data
423 CipherContext *cipherCtx, // assumes macCtx, macRef
424 sslUint64 seqNo,
425 SSLContext *ctx)
426 {
427 uint8_t hdr[HDR_LENGTH];
428 uint8_t *p;
429 HMACContextRef hmacCtx;
430 OSStatus serr;
431 const HMACReference *hmac;
432 size_t macLength;
433
434 assert(cipherCtx != NULL);
435 assert(cipherCtx->macRef != NULL);
436 hmac = cipherCtx->macRef->hmac;
437 assert(hmac != NULL);
438 hmacCtx = cipherCtx->macCtx.hmacCtx; // may be NULL, for null cipher
439
440 serr = hmac->init(hmacCtx);
441 if(serr) {
442 goto fail;
443 }
444 p = SSLEncodeUInt64(hdr, seqNo);
445 *p++ = type;
446 *p++ = ctx->negProtocolVersion >> 8;
447 *p++ = ctx->negProtocolVersion & 0xff;
448 *p++ = data.length >> 8;
449 *p = data.length & 0xff;
450 serr = hmac->update(hmacCtx, hdr, HDR_LENGTH);
451 if(serr) {
452 goto fail;
453 }
454 serr = hmac->update(hmacCtx, data.data, data.length);
455 if(serr) {
456 goto fail;
457 }
458 macLength = mac.length;
459 serr = hmac->final(hmacCtx, mac.data, &macLength);
460 if(serr) {
461 goto fail;
462 }
463 mac.length = macLength;
464 fail:
465 return serr;
466 }
467
468 /*
469 * On input, the following are valid:
470 * MasterSecret[48]
471 * ClientHello.random[32]
472 * ServerHello.random[32]
473 *
474 * key_block = PRF(SecurityParameters.master_secret,
475 * "key expansion",
476 * SecurityParameters.server_random +
477 * SecurityParameters.client_random);
478 */
479
480 #define GKM_SEED_LEN (PLS_KEY_EXPAND_LEN + (2 * SSL_CLIENT_SRVR_RAND_SIZE))
481
482 static OSStatus tls1GenerateKeyMaterial (
483 SSLBuffer key, // caller mallocs and specifies length of
484 // required key material here
485 SSLContext *ctx)
486 {
487 unsigned char seedBuf[GKM_SEED_LEN];
488 OSStatus serr;
489
490 /* use optimized label-less PRF */
491 memmove(seedBuf, PLS_KEY_EXPAND, PLS_KEY_EXPAND_LEN);
492 memmove(seedBuf + PLS_KEY_EXPAND_LEN, ctx->serverRandom,
493 SSL_CLIENT_SRVR_RAND_SIZE);
494 memmove(seedBuf + PLS_KEY_EXPAND_LEN + SSL_CLIENT_SRVR_RAND_SIZE,
495 ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
496 serr = SSLInternal_PRF(ctx,
497 ctx->masterSecret,
498 SSL_MASTER_SECRET_SIZE,
499 NULL, // no label
500 0,
501 seedBuf,
502 GKM_SEED_LEN,
503 key.data, // destination
504 key.length);
505 tlsDump("key expansion", key.data, key.length);
506 return serr;
507 }
508
509 /*
510 * final_client_write_key =
511 * PRF(SecurityParameters.client_write_key,
512 * "client write key",
513 * SecurityParameters.client_random +
514 * SecurityParameters.server_random);
515 * final_server_write_key =
516 * PRF(SecurityParameters.server_write_key,
517 * "server write key",
518 * SecurityParameters.client_random +
519 * SecurityParameters.server_random);
520 *
521 * iv_block = PRF("", "IV block", SecurityParameters.client_random +
522 * SecurityParameters.server_random);
523 *
524 * iv_block is broken up into:
525 *
526 * client_write_IV[SecurityParameters.IV_size]
527 * server_write_IV[SecurityParameters.IV_size]
528 */
529 static OSStatus tls1GenerateExportKeyAndIv (
530 SSLContext *ctx, // clientRandom, serverRandom valid
531 const SSLBuffer clientWriteKey,
532 const SSLBuffer serverWriteKey,
533 SSLBuffer finalClientWriteKey, // RETURNED, mallocd by caller
534 SSLBuffer finalServerWriteKey, // RETURNED, mallocd by caller
535 SSLBuffer finalClientIV, // RETURNED, mallocd by caller
536 SSLBuffer finalServerIV) // RETURNED, mallocd by caller
537 {
538 unsigned char randBuf[2 * SSL_CLIENT_SRVR_RAND_SIZE];
539 OSStatus serr;
540 unsigned char *ivBlock;
541 char *nullKey = "";
542
543 /* all three PRF calls use the same seed */
544 memmove(randBuf, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
545 memmove(randBuf + SSL_CLIENT_SRVR_RAND_SIZE,
546 ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
547
548 serr = SSLInternal_PRF(ctx,
549 clientWriteKey.data,
550 clientWriteKey.length,
551 (const unsigned char *)PLS_EXPORT_CLIENT_WRITE,
552 PLS_EXPORT_CLIENT_WRITE_LEN,
553 randBuf,
554 2 * SSL_CLIENT_SRVR_RAND_SIZE,
555 finalClientWriteKey.data, // destination
556 finalClientWriteKey.length);
557 if(serr) {
558 return serr;
559 }
560 serr = SSLInternal_PRF(ctx,
561 serverWriteKey.data,
562 serverWriteKey.length,
563 (const unsigned char *)PLS_EXPORT_SERVER_WRITE,
564 PLS_EXPORT_SERVER_WRITE_LEN,
565 randBuf,
566 2 * SSL_CLIENT_SRVR_RAND_SIZE,
567 finalServerWriteKey.data, // destination
568 finalServerWriteKey.length);
569 if(serr) {
570 return serr;
571 }
572 if((finalClientIV.length == 0) && (finalServerIV.length == 0)) {
573 /* skip remainder as optimization */
574 return noErr;
575 }
576 ivBlock = (unsigned char *)sslMalloc(finalClientIV.length + finalServerIV.length);
577 if(ivBlock == NULL) {
578 return memFullErr;
579 }
580 serr = SSLInternal_PRF(ctx,
581 (const unsigned char *)nullKey,
582 0,
583 (const unsigned char *)PLS_EXPORT_IV_BLOCK,
584 PLS_EXPORT_IV_BLOCK_LEN,
585 randBuf,
586 2 * SSL_CLIENT_SRVR_RAND_SIZE,
587 ivBlock, // destination
588 finalClientIV.length + finalServerIV.length);
589 if(serr) {
590 goto done;
591 }
592 memmove(finalClientIV.data, ivBlock, finalClientIV.length);
593 memmove(finalServerIV.data, ivBlock + finalClientIV.length, finalServerIV.length);
594 done:
595 sslFree(ivBlock);
596 return serr;
597 }
598
599 /*
600 * On entry: clientRandom, serverRandom, preMasterSecret valid
601 * On return: masterSecret valid
602 *
603 * master_secret = PRF(pre_master_secret, "master secret",
604 * ClientHello.random + ServerHello.random)
605 * [0..47];
606 */
607
608 static OSStatus tls1GenerateMasterSecret (
609 SSLContext *ctx)
610 {
611 unsigned char randBuf[2 * SSL_CLIENT_SRVR_RAND_SIZE];
612 OSStatus serr;
613
614 memmove(randBuf, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
615 memmove(randBuf + SSL_CLIENT_SRVR_RAND_SIZE,
616 ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
617 serr = SSLInternal_PRF(ctx,
618 ctx->preMasterSecret.data,
619 ctx->preMasterSecret.length,
620 (const unsigned char *)PLS_MASTER_SECRET,
621 PLS_MASTER_SECRET_LEN,
622 randBuf,
623 2 * SSL_CLIENT_SRVR_RAND_SIZE,
624 ctx->masterSecret, // destination
625 SSL_MASTER_SECRET_SIZE);
626 tlsDump("master secret", ctx->masterSecret, SSL_MASTER_SECRET_SIZE);
627 return serr;
628 }
629
630 /*
631 * Given digests contexts representing the running total of all handshake messages,
632 * calculate mac for "finished" message.
633 *
634 * verify_data = 12 bytes =
635 * PRF(master_secret, finished_label, MD5(handshake_messages) +
636 * SHA-1(handshake_messages)) [0..11];
637 */
638 static OSStatus tls1ComputeFinishedMac (
639 SSLContext *ctx,
640 SSLBuffer finished, // output - mallocd by caller
641 Boolean isServer)
642 {
643 unsigned char digests[SSL_MD5_DIGEST_LEN + SSL_SHA1_DIGEST_LEN];
644 SSLBuffer digBuf;
645 char *finLabel;
646 unsigned finLabelLen;
647 OSStatus serr;
648 SSLBuffer shaMsgState, md5MsgState;
649
650 shaMsgState.data = 0;
651 md5MsgState.data = 0;
652 if ((serr = CloneHashState(&SSLHashSHA1, &ctx->shaState, &shaMsgState, ctx)) != 0)
653 goto fail;
654 if ((serr = CloneHashState(&SSLHashMD5, &ctx->md5State, &md5MsgState, ctx)) != 0)
655 goto fail;
656
657 if(isServer) {
658 finLabel = PLS_SERVER_FINISH;
659 finLabelLen = PLS_SERVER_FINISH_LEN;
660 }
661 else {
662 finLabel = PLS_CLIENT_FINISH;
663 finLabelLen = PLS_CLIENT_FINISH_LEN;
664 }
665
666 /* concatenate two digest results */
667 digBuf.data = digests;
668 digBuf.length = SSL_MD5_DIGEST_LEN;
669 serr = SSLHashMD5.final(&md5MsgState, &digBuf);
670 if(serr) {
671 return serr;
672 }
673 digBuf.data += SSL_MD5_DIGEST_LEN;
674 digBuf.length = SSL_SHA1_DIGEST_LEN;
675 serr = SSLHashSHA1.final(&shaMsgState, &digBuf);
676 if(serr) {
677 return serr;
678 }
679 serr = SSLInternal_PRF(ctx,
680 ctx->masterSecret,
681 SSL_MASTER_SECRET_SIZE,
682 (const unsigned char *)finLabel,
683 finLabelLen,
684 digests,
685 SSL_MD5_DIGEST_LEN + SSL_SHA1_DIGEST_LEN,
686 finished.data, // destination
687 finished.length);
688
689 fail:
690 SSLFreeBuffer(&shaMsgState, ctx);
691 SSLFreeBuffer(&md5MsgState, ctx);
692
693 return serr;
694 }
695
696 /*
697 * Given digests contexts representing the running total of all handshake messages,
698 * calculate mac for "finished" message.
699 *
700 * verify_data = 12 bytes =
701 * PRF(master_secret, finished_label, SHA256(handshake_messages)) [0..11];
702 */
703 static OSStatus tls12ComputeFinishedMac (
704 SSLContext *ctx,
705 SSLBuffer finished, // output - mallocd by caller
706 Boolean isServer)
707 {
708 unsigned char digest[SSL_MAX_DIGEST_LEN];
709 SSLBuffer digBuf;
710 char *finLabel;
711 unsigned finLabelLen;
712 OSStatus serr;
713 SSLBuffer hashState;
714 const HashReference *hashRef;
715 const SSLBuffer *ctxHashState;
716
717 /* The PRF used in the finished message is based on the cipherspec */
718 if (ctx->selectedCipherSpec.macAlgorithm->hmac->alg == HA_SHA384) {
719 hashRef = &SSLHashSHA384;
720 ctxHashState = &ctx->sha512State;
721 } else {
722 hashRef = &SSLHashSHA256;
723 ctxHashState = &ctx->sha256State;
724 }
725
726 hashState.data = 0;
727 if ((serr = CloneHashState(hashRef, ctxHashState, &hashState, ctx)) != 0)
728 goto fail;
729 if(isServer) {
730 finLabel = PLS_SERVER_FINISH;
731 finLabelLen = PLS_SERVER_FINISH_LEN;
732 }
733 else {
734 finLabel = PLS_CLIENT_FINISH;
735 finLabelLen = PLS_CLIENT_FINISH_LEN;
736 }
737
738 /* concatenate two digest results */
739 digBuf.data = digest;
740 digBuf.length = hashRef->digestSize;
741 if ((serr = hashRef->final(&hashState, &digBuf)) != 0)
742 goto fail;
743 serr = SSLInternal_PRF(ctx,
744 ctx->masterSecret,
745 SSL_MASTER_SECRET_SIZE,
746 (const unsigned char *)finLabel,
747 finLabelLen,
748 digBuf.data,
749 digBuf.length,
750 finished.data, // destination
751 finished.length);
752 fail:
753 SSLFreeBuffer(&hashState, ctx);
754 return serr;
755 }
756
757 /*
758 * This one is trivial.
759 *
760 * mac := MD5(handshake_messages) + SHA(handshake_messages);
761 *
762 * I don't know why this one doesn't use an HMAC or the master secret (as SSLv3
763 * does).
764 */
765 static OSStatus tls1ComputeCertVfyMac (
766 SSLContext *ctx,
767 SSLBuffer *finished, // output - mallocd by caller
768 SSL_HashAlgorithm hash) //unused in this one
769 {
770 SSLBuffer digBuf, shaMsgState, md5MsgState;
771 OSStatus serr;
772
773 shaMsgState.data = 0;
774 md5MsgState.data = 0;
775
776 if ((serr = CloneHashState(&SSLHashSHA1, &ctx->shaState, &shaMsgState, ctx)) != 0)
777 goto fail;
778 if ((serr = CloneHashState(&SSLHashMD5, &ctx->md5State, &md5MsgState, ctx)) != 0)
779 goto fail;
780
781 if ((ctx->protocolSide == kSSLServerSide && sslPubKeyGetAlgorithmID(ctx->peerPubKey) == kSecECDSAAlgorithmID) ||
782 (ctx->protocolSide == kSSLClientSide && ctx->negAuthType == SSLClientAuth_ECDSASign)) {
783 /* Only take SHA1 regardless of TLSv1.0 or TLSv1.1 If we are the server
784 and our peer signed with an ECDSA key, or if we are the client and
785 are about to sign with ECDSA. */
786 assert(finished->length >= SSL_SHA1_DIGEST_LEN);
787 digBuf.data = finished->data;
788 finished->length = SSL_SHA1_DIGEST_LEN;
789 } else {
790 /* Put MD5 follow by SHA1 hash in buffer. */
791 assert(finished->length >= (SSL_MD5_DIGEST_LEN + SSL_SHA1_DIGEST_LEN));
792 digBuf.data = finished->data;
793 digBuf.length = SSL_MD5_DIGEST_LEN;
794 if ((serr = SSLHashMD5.final(&md5MsgState, &digBuf)) != 0)
795 goto fail;
796 digBuf.data = finished->data + SSL_MD5_DIGEST_LEN;
797 finished->length = SSL_MD5_DIGEST_LEN + SSL_SHA1_DIGEST_LEN;
798 }
799
800 digBuf.length = SSL_SHA1_DIGEST_LEN;
801 serr = SSLHashSHA1.final(&shaMsgState, &digBuf);
802
803 fail:
804 SSLFreeBuffer(&shaMsgState, ctx);
805 SSLFreeBuffer(&md5MsgState, ctx);
806
807 return serr;
808 }
809
810 static OSStatus tls12ComputeCertVfyMac (
811 SSLContext *ctx,
812 SSLBuffer *finished, // output - mallocd by caller
813 SSL_HashAlgorithm hash)
814 {
815 const SSLBuffer *ctxHashState;
816 const HashReference *hashRef;
817 SSLBuffer hashState;
818 OSStatus serr;
819
820 hashState.data = 0;
821
822 switch (hash) {
823 case SSL_HashAlgorithmSHA1:
824 hashRef = &SSLHashSHA1;
825 ctxHashState = &ctx->shaState;
826 break;
827 case SSL_HashAlgorithmSHA256:
828 hashRef = &SSLHashSHA256;
829 ctxHashState = &ctx->sha256State;
830 break;
831 case SSL_HashAlgorithmSHA384:
832 hashRef = &SSLHashSHA384;
833 ctxHashState = &ctx->sha512State;
834 break;
835 default:
836 break;
837 }
838
839 if ((serr = CloneHashState(hashRef, ctxHashState, &hashState, ctx)) != 0)
840 goto fail;
841
842 assert(finished->length >= (hashRef->digestSize));
843 finished->length = hashRef->digestSize;
844 serr = hashRef->final(&hashState, finished);
845
846 fail:
847 SSLFreeBuffer(&hashState, ctx);
848
849 return serr;
850 }
851
852
853 const SslTlsCallouts Tls1Callouts = {
854 tls1DecryptRecord,
855 ssl3WriteRecord,
856 tls1InitMac,
857 tls1FreeMac,
858 tls1ComputeMac,
859 tls1GenerateKeyMaterial,
860 tls1GenerateExportKeyAndIv,
861 tls1GenerateMasterSecret,
862 tls1ComputeFinishedMac,
863 tls1ComputeCertVfyMac
864 };
865
866
867 const SslTlsCallouts Tls12Callouts = {
868 tls1DecryptRecord,
869 ssl3WriteRecord,
870 tls1InitMac,
871 tls1FreeMac,
872 tls1ComputeMac,
873 tls1GenerateKeyMaterial,
874 tls1GenerateExportKeyAndIv,
875 tls1GenerateMasterSecret,
876 tls12ComputeFinishedMac,
877 tls12ComputeCertVfyMac
878 };