File Coverage

inc/matrixssl-3-9-3-open/matrixssl/hsHash.c
Criterion Covered Total %
statement 45 86 52.3
branch 14 24 58.3
condition n/a
subroutine n/a
pod n/a
total 59 110 53.6


line stmt bran cond sub pod time code
1             /**
2             * @file hsHash.c
3             * @version 950bba4 (HEAD -> master)
4             *
5             * "Native" handshake hash.
6             */
7             /*
8             * Copyright (c) 2013-2017 INSIDE Secure Corporation
9             * Copyright (c) PeerSec Networks, 2002-2011
10             * All Rights Reserved
11             *
12             * The latest version of this code is available at http://www.matrixssl.org
13             *
14             * This software is open source; you can redistribute it and/or modify
15             * it under the terms of the GNU General Public License as published by
16             * the Free Software Foundation; either version 2 of the License, or
17             * (at your option) any later version.
18             *
19             * This General Public License does NOT permit incorporating this software
20             * into proprietary programs. If you are unable to comply with the GPL, a
21             * commercial license for this software may be purchased from INSIDE at
22             * http://www.insidesecure.com/
23             *
24             * This program is distributed in WITHOUT ANY WARRANTY; without even the
25             * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26             * See the GNU General Public License for more details.
27             *
28             * You should have received a copy of the GNU General Public License
29             * along with this program; if not, write to the Free Software
30             * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31             * http://www.gnu.org/copyleft/gpl.html
32             */
33              
34             #include "matrixsslImpl.h"
35              
36             #ifdef USE_NATIVE_TLS_HS_HASH
37              
38             # define FINISHED_LABEL_SIZE 15
39             # define LABEL_CLIENT "client finished"
40             # define LABEL_SERVER "server finished"
41             /******************************************************************************/
42             /**
43             Initialize the SHA1 and MD5 hash contexts for the handshake messages.
44             The handshake hashes are used in 3 messages in TLS:
45             ClientFinished, ServerFinished and ClientCertificateVerify.
46             The version of TLS affects which hashes are used for the Finished messages.
47             TLS 1.2 allows a different hash algorithm for the CertificatVerify message
48             than is used by the Finished messages, determined by the
49             Signature Algorithms extension.
50             Multiple handshake hash contexts must be maintained until the handshake has
51             progressed enough to determine the negotiated TLS version and whether or
52             not Client Authentication is to be performed. Also, if USE_ONLY_TLS_1_2 is
53             defined at compile time, or USE_CLIENT_AUTH is undefined at compile time,
54             the potential runtime combinations are reduced.
55             The various algorithms are used as follows (+ means concatenation):
56             Client and Server Finished messages
57             < TLS 1.2 - MD5+SHA1
58             TLS 1.2 - SHA256
59             Client CertificateVerify message.
60             < TLS 1.2 - MD5+SHA1
61             TLS 1.2 - One of the hashes present in the union of the
62             SignatureAlgorithms Client extension and the CertificateRequest
63             message from the server. At most this is the set
64             {SHA1,SHA256,SHA384,SHA512}.
65             @return < 0 on failure.
66             @param[in,out] ssl TLS context
67             */
68 12313           int32_t sslInitHSHash(ssl_t *ssl)
69             {
70             # ifdef USE_DTLS
71             if (ssl->flags & SSL_FLAGS_DTLS)
72             {
73             /* Don't allow CLIENT_HELLO message retransmit to reset hash */
74             if (ssl->retransmit)
75             {
76             return 0;
77             }
78             }
79             # endif /* USE_DTLS */
80              
81             # ifndef USE_ONLY_TLS_1_2
82 12313           psMd5Sha1Init(&ssl->sec.msgHashMd5Sha1);
83             # endif
84              
85             # ifdef USE_TLS_1_2
86 12313           psSha256Init(&ssl->sec.msgHashSha256);
87             # ifdef USE_SHA1
88 12313           psSha1Init(&ssl->sec.msgHashSha1);
89             # endif
90             # ifdef USE_SHA384
91 12313           psSha384Init(&ssl->sec.msgHashSha384);
92             # endif
93             # ifdef USE_SHA512
94 12313           psSha512Init(&ssl->sec.msgHashSha512);
95             # endif
96             # endif
97              
98 12313           return 0;
99             }
100              
101             /******************************************************************************/
102             /**
103             Add the given data to the running hash of the handshake messages.
104             @param[in,out] ssl TLS context
105             @param[in] in Pointer to handshake data to hash.
106             @param[in] len Number of bytes of handshake data to hash.
107             @return < 0 on failure.
108             */
109 27667           int32_t sslUpdateHSHash(ssl_t *ssl, const unsigned char *in, psSize_t len)
110             {
111              
112             # ifdef USE_DTLS
113             if (ssl->flags & SSL_FLAGS_DTLS)
114             {
115             /* Don't update handshake hashes on resends. Already been through here */
116             if (ssl->retransmit)
117             {
118             return 0;
119             }
120             }
121             # endif /* USE_DTLS */
122              
123             # ifdef USE_TLS_1_2
124             /* Keep a running total of each for greatest RFC support when it comes
125             to the CertificateVerify message. Although, trying to be smart
126             about MD5 and SHA-2 based on protocol version. */
127 27667 100         if ((ssl->majVer == 0 && ssl->minVer == 0) ||
    50          
    50          
128             # ifdef USE_DTLS
129             ssl->minVer == DTLS_1_2_MIN_VER ||
130             # endif
131 26525           ssl->minVer == TLS_1_2_MIN_VER)
132             {
133 27667           psSha256Update(&ssl->sec.msgHashSha256, in, len);
134             # ifdef USE_SHA1
135 27667           psSha1Update(&ssl->sec.msgHashSha1, in, len);
136             # endif
137             # ifdef USE_SHA384
138 27667           psSha384Update(&ssl->sec.msgHashSha384, in, len);
139             # endif
140             # ifdef USE_SHA512
141 27667           psSha512Update(&ssl->sec.msgHashSha512, in, len);
142             # endif
143             }
144             # endif
145              
146             # ifndef USE_ONLY_TLS_1_2
147             /* Below TLS 1.2, the hash is always the md5sha1 hash. If we negotiate
148             to TLS 1.2 and need sha1, we use just that part of the md5Sha1. */
149             /* TODO if (ssl->reqMinVer == 0 || ssl->minVer != TLS_1_2_MIN_VER) { */
150 27667           psMd5Sha1Update(&ssl->sec.msgHashMd5Sha1, in, len);
151              
152             # endif
153              
154 27667           return 0;
155             }
156              
157             # ifdef USE_TLS_1_2
158             /* Functions necessary to deal with needing to keep track of both SHA-1
159             and SHA-256 handshake hash states. FINISHED message will always be
160             SHA-256 but client might be sending SHA-1 CertificateVerify message */
161             # if defined(USE_SERVER_SIDE_SSL) && defined(USE_CLIENT_AUTH)
162             # ifdef USE_SHA1
163 0           int32 sslSha1RetrieveHSHash(ssl_t *ssl, unsigned char *out)
164             {
165 0           memcpy(out, ssl->sec.sha1Snapshot, SHA1_HASH_SIZE);
166 0           return SHA1_HASH_SIZE;
167             }
168             # endif
169             # ifdef USE_SHA384
170 0           int32 sslSha384RetrieveHSHash(ssl_t *ssl, unsigned char *out)
171             {
172 0           memcpy(out, ssl->sec.sha384Snapshot, SHA384_HASH_SIZE);
173 0           return SHA384_HASH_SIZE;
174             }
175             # endif
176             # ifdef USE_SHA512
177 0           int32 sslSha512RetrieveHSHash(ssl_t *ssl, unsigned char *out)
178             {
179 0           memcpy(out, ssl->sec.sha512Snapshot, SHA512_HASH_SIZE);
180 0           return SHA512_HASH_SIZE;
181             }
182             # endif
183             # endif /* USE_SERVER_SIDE_SSL && USE_CLIENT_AUTH */
184              
185             # if defined(USE_CLIENT_SIDE_SSL) && defined(USE_CLIENT_AUTH)
186             # ifdef USE_SHA1
187             /* It is possible the certificate verify message wants a non-SHA256 hash */
188 0           void sslSha1SnapshotHSHash(ssl_t *ssl, unsigned char *out)
189             {
190 0           psSha1Final(&ssl->sec.msgHashSha1, out);
191 0           }
192             # endif
193             # ifdef USE_SHA384
194 0           void sslSha384SnapshotHSHash(ssl_t *ssl, unsigned char *out)
195             {
196             psSha384_t sha384;
197              
198             /* SHA384 must copy the context because it could be needed again for
199             final handshake hash. SHA1 doesn't need this because it will
200             not ever be used again after this client auth one-off */
201 0           psSha384Sync(&ssl->sec.msgHashSha384, 0);
202 0           sha384 = ssl->sec.msgHashSha384;
203 0           psSha384Final(&sha384, out);
204 0           }
205             # endif
206             # ifdef USE_SHA512
207 0           void sslSha512SnapshotHSHash(ssl_t *ssl, unsigned char *out)
208             {
209             psSha512_t sha512;
210              
211             /* SHA512 must copy the context because it could be needed again for
212             final handshake hash. SHA1 doesn't need this because it will
213             not ever be used again after this client auth one-off */
214 0           psSha512Sync(&ssl->sec.msgHashSha512, 0);
215 0           sha512 = ssl->sec.msgHashSha512;
216 0           psSha512Final(&sha512, out);
217 0           }
218             # endif
219             # endif /* USE_CLIENT_SIDE_SSL && USE_CLIENT_AUTH */
220             # endif /* USE_TLS_1_2 */
221              
222             # ifdef USE_TLS
223             /******************************************************************************/
224             /*
225             TLS handshake hash computation
226             */
227 4238           static int32_t tlsGenerateFinishedHash(ssl_t *ssl,
228             # ifndef USE_ONLY_TLS_1_2
229             psMd5Sha1_t *md5sha1,
230             # endif
231             # ifdef USE_TLS_1_2
232             # ifdef USE_SHA1
233             psSha1_t *sha1,
234             # endif
235             # ifdef USE_SHA256
236             psSha256_t *sha256,
237             # endif
238             # ifdef USE_SHA384
239             psSha384_t *sha384,
240             # endif
241             # ifdef USE_SHA512
242             psSha512_t *sha512,
243             # endif
244             # endif /* USE_TLS_1_2 */
245             unsigned char *masterSecret,
246             unsigned char *out, int32 senderFlag)
247             {
248             unsigned char tmp[FINISHED_LABEL_SIZE + SHA384_HASH_SIZE];
249              
250             # ifndef USE_ONLY_TLS_1_2
251             psMd5Sha1_t md5sha1_backup;
252             # endif
253             # ifdef USE_SHA1
254             psSha1_t sha1_backup;
255             # endif
256             # ifdef USE_SHA256
257             psSha256_t sha256_backup;
258             # endif
259             # ifdef USE_SHA384
260             psSha384_t sha384_backup;
261             # endif
262             # ifdef USE_SHA512
263             psSha512_t sha512_backup;
264             # endif
265             /*
266             In each branch: Use a backup of the message hash-to-date because we don't
267             want to destroy the state of the handshaking until truly complete
268             */
269              
270 4238 50         if (senderFlag >= 0)
271             {
272 4238 100         memcpy(tmp, (senderFlag & SSL_FLAGS_SERVER) ? LABEL_SERVER : LABEL_CLIENT,
273             FINISHED_LABEL_SIZE);
274             # ifdef USE_TLS_1_2
275 4238 50         if (ssl->flags & SSL_FLAGS_TLS_1_2)
276             {
277 4238 100         if (ssl->cipher->flags & CRYPTO_FLAGS_SHA3)
278             {
279             # ifdef USE_SHA384
280 4232           psSha384Cpy(&sha384_backup, sha384);
281 4232           psSha384Final(&sha384_backup, tmp + FINISHED_LABEL_SIZE);
282 4232           return prf2(masterSecret, SSL_HS_MASTER_SIZE, tmp,
283             FINISHED_LABEL_SIZE + SHA384_HASH_SIZE, out,
284             TLS_HS_FINISHED_SIZE, CRYPTO_FLAGS_SHA3);
285             # endif
286             }
287             else
288             {
289 6           psSha256Cpy(&sha256_backup, sha256);
290 6           psSha256Final(&sha256_backup, tmp + FINISHED_LABEL_SIZE);
291 6           return prf2(masterSecret, SSL_HS_MASTER_SIZE, tmp,
292             FINISHED_LABEL_SIZE + SHA256_HASH_SIZE, out,
293             TLS_HS_FINISHED_SIZE, CRYPTO_FLAGS_SHA2);
294             }
295             # ifndef USE_ONLY_TLS_1_2
296             }
297             else
298             {
299 0           psMd5Sha1Cpy(&md5sha1_backup, md5sha1);
300 0           psMd5Sha1Final(&md5sha1_backup, tmp + FINISHED_LABEL_SIZE);
301 0           return prf(masterSecret, SSL_HS_MASTER_SIZE, tmp,
302             FINISHED_LABEL_SIZE + MD5SHA1_HASHLEN,
303             out, TLS_HS_FINISHED_SIZE);
304             # endif
305             }
306             # else
307             psMd5Sha1Cpy(&md5sha1_backup, md5sha1);
308             psMd5Sha1Final(&md5sha1_backup, tmp + FINISHED_LABEL_SIZE);
309             return prf(masterSecret, SSL_HS_MASTER_SIZE, tmp,
310             FINISHED_LABEL_SIZE + MD5SHA1_HASHLEN,
311             out, TLS_HS_FINISHED_SIZE);
312             # endif
313             }
314             else
315             {
316             /* Overloading this function to handle the client auth needs of
317             handshake hashing. */
318             # ifdef USE_TLS_1_2
319 0 0         if (ssl->flags & SSL_FLAGS_TLS_1_2)
320             {
321 0           psSha256Cpy(&sha256_backup, sha256);
322 0           psSha256Final(&sha256_backup, out);
323             # if defined(USE_SERVER_SIDE_SSL) && defined(USE_CLIENT_AUTH)
324             /* Check to make sure we are a server because clients come
325             through here as well and they do not need to snapshot any
326             hashes because they are in a write state during the
327             CERTIFICATE_VERIFY creation. So if they detect a non-default
328             in digest, they just run the sslSha384SnapshotHSHash family
329             of functions. Servers really do have to save aside the
330             snapshots beause the CERTIFICATE_VERIFY is a parse and so the
331             handshake hash is being set aside for all possible combos
332             here so the sslSha384RetrieveHSHash can fetch. Previous
333             versions were not testing for SERVER here so clients were
334             running digest operations that were not needed in client auth */
335 0 0         if (ssl->flags & SSL_FLAGS_SERVER)
336             {
337             # ifdef USE_SHA384
338 0           psSha384Cpy(&sha384_backup, sha384);
339 0           psSha384Final(&sha384_backup, ssl->sec.sha384Snapshot);
340             # endif
341             # ifdef USE_SHA512
342 0           psSha512Cpy(&sha512_backup, sha512);
343 0           psSha512Final(&sha512_backup, ssl->sec.sha512Snapshot);
344             # endif
345             # ifdef USE_SHA1
346 0           psSha1Cpy(&sha1_backup, sha1);
347 0           psSha1Final(&sha1_backup, ssl->sec.sha1Snapshot);
348             # endif
349             }
350             # endif
351 0           return SHA256_HASH_SIZE;
352             # ifndef USE_ONLY_TLS_1_2
353             }
354             else
355             {
356 0           psMd5Sha1Cpy(&md5sha1_backup, md5sha1);
357 0           psMd5Sha1Final(&md5sha1_backup, out);
358 4238           return MD5SHA1_HASHLEN;
359             # endif
360             }
361             # else
362             /*
363             The handshake snapshot for client authentication is simply the
364             appended MD5 and SHA1 hashes
365             */
366             psMd5Sha1Cpy(&md5sha1_backup, md5sha1);
367             psMd5Sha1Final(&md5sha1_backup, out);
368             return MD5SHA1_HASHLEN;
369             # endif /* USE_TLS_1_2 */
370             }
371             return PS_FAILURE; /* Should not reach this */
372             }
373             # endif /* USE_TLS */
374              
375              
376             /* The extended master secret computation uses a handshake hash */
377 2115           int32_t extMasterSecretSnapshotHSHash(ssl_t *ssl, unsigned char *out,
378             uint32 *outLen)
379             {
380             # ifndef USE_ONLY_TLS_1_2
381             psMd5Sha1_t md5sha1;
382             # endif
383             # ifdef USE_SHA256
384             psSha256_t sha256;
385             # endif
386             # ifdef USE_SHA384
387             psSha384_t sha384;
388             # endif
389              
390             /*
391             Use a backup of the message hash-to-date because we don't want
392             to destroy the state of the handshaking until truly complete
393             */
394              
395 2115           *outLen = 0;
396              
397             # ifdef USE_TLS_1_2
398 2115 50         if (ssl->flags & SSL_FLAGS_TLS_1_2)
399             {
400 2115 100         if (ssl->cipher->flags & CRYPTO_FLAGS_SHA3)
401             {
402             # ifdef USE_SHA384
403 2112           psSha384Cpy(&sha384, &ssl->sec.msgHashSha384);
404 2112           psSha384Final(&sha384, out);
405 2112           *outLen = SHA384_HASH_SIZE;
406             # endif
407             }
408             else
409             {
410 3           psSha256Cpy(&sha256, &ssl->sec.msgHashSha256);
411 3           psSha256Final(&sha256, out);
412 2115           *outLen = SHA256_HASH_SIZE;
413             }
414             # ifndef USE_ONLY_TLS_1_2
415             }
416             else
417             {
418 0           psMd5Sha1Cpy(&md5sha1, &ssl->sec.msgHashMd5Sha1);
419 0           psMd5Sha1Final(&md5sha1, out);
420 0           *outLen = MD5SHA1_HASHLEN;
421             # endif
422             }
423             # else /* no TLS 1.2 */
424             psMd5Sha1Cpy(&md5sha1, &ssl->sec.msgHashMd5Sha1);
425             psMd5Sha1Final(&md5sha1, out);
426             *outLen = MD5SHA1_HASHLEN;
427             # endif
428              
429 2115           return *outLen;
430             }
431              
432              
433             /******************************************************************************/
434             /*
435             Snapshot is called by the receiver of the finished message to produce
436             a hash of the preceeding handshake messages for comparison to incoming
437             message.
438             */
439 4238           int32_t sslSnapshotHSHash(ssl_t *ssl, unsigned char *out, int32 senderFlag)
440             {
441 4238           int32 len = PS_FAILURE;
442              
443             # ifdef USE_DTLS
444             if (ssl->flags & SSL_FLAGS_DTLS)
445             {
446             /* Don't allow FINISHED message retransmit to re-calc hash */
447             if (ssl->retransmit)
448             {
449             memcpy(out, ssl->hsSnapshot, ssl->hsSnapshotLen);
450             return ssl->hsSnapshotLen;
451             }
452             }
453             # endif /* USE_DTLS */
454              
455             # ifdef USE_TLS
456 4238 50         if (ssl->flags & SSL_FLAGS_TLS)
457             {
458 4238           len = tlsGenerateFinishedHash(ssl,
459             # ifndef USE_ONLY_TLS_1_2
460             &ssl->sec.msgHashMd5Sha1,
461             # endif
462             # ifdef USE_TLS_1_2
463             # ifdef USE_SHA1
464             &ssl->sec.msgHashSha1,
465             # endif
466             # ifdef USE_SHA256
467             &ssl->sec.msgHashSha256,
468             # endif
469             # ifdef USE_SHA384
470             &ssl->sec.msgHashSha384,
471             # endif
472             # ifdef USE_SHA512
473             &ssl->sec.msgHashSha512,
474             # endif
475             # endif /* USE_TLS_1_2 */
476 4238           ssl->sec.masterSecret, out, senderFlag);
477              
478             # ifndef DISABLE_SSLV3
479             }
480             else
481             {
482             len = sslGenerateFinishedHash(&ssl->sec.msgHashMd5Sha1,
483             ssl->sec.masterSecret, out, senderFlag);
484             # endif /* DISABLE_SSLV3 */
485             }
486             # endif /* USE_TLS */
487              
488             # ifdef USE_DTLS
489             if (ssl->flags & SSL_FLAGS_DTLS)
490             {
491             if (len > 0)
492             {
493             memcpy(ssl->hsSnapshot, out, len);
494             ssl->hsSnapshotLen = len;
495             }
496             }
497             # endif /* USE_DTLS */
498 4238           return len;
499             }
500              
501             #endif /* USE_NATIVE_TLS_HS_HASH */
502              
503             /******************************************************************************/
504