tls_transcript_hash.c
Go to the documentation of this file.
1 /**
2  * @file tls_transcript_hash.c
3  * @brief Transcript hash calculation
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneSSL Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL TLS_TRACE_LEVEL
31 
32 //Dependencies
33 #include <string.h>
34 #include "tls.h"
35 #include "tls_client.h"
36 #include "tls_key_material.h"
37 #include "tls_transcript_hash.h"
38 #include "tls13_key_material.h"
39 #include "ssl_misc.h"
40 #include "debug.h"
41 
42 //Check TLS library configuration
43 #if (TLS_SUPPORT == ENABLED)
44 
45 
46 /**
47  * @brief Initialize handshake message hashing
48  * @param[in] context Pointer to the TLS context
49  * @return Error code
50  **/
51 
53 {
54 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1)
55  //MD5 context already instantiated?
56  if(context->handshakeMd5Context != NULL)
57  {
58  tlsFreeMem(context->handshakeMd5Context);
59  context->handshakeMd5Context = NULL;
60  }
61 #endif
62 
63 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
64  //SHA-1 context already instantiated?
65  if(context->handshakeSha1Context != NULL)
66  {
67  tlsFreeMem(context->handshakeSha1Context);
68  context->handshakeSha1Context = NULL;
69  }
70 #endif
71 
72 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
73  //Hash algorithm context already instantiated?
74  if(context->handshakeHashContext != NULL)
75  {
76  tlsFreeMem(context->handshakeHashContext);
77  context->handshakeHashContext = NULL;
78  }
79 #endif
80 
81 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1)
82  //SSL 3.0, TLS 1.0 or TLS 1.1 currently selected?
83  if(context->version <= TLS_VERSION_1_1)
84  {
85  //Allocate MD5 context
86  context->handshakeMd5Context = tlsAllocMem(sizeof(Md5Context));
87  //Failed to allocate memory?
88  if(context->handshakeMd5Context == NULL)
89  return ERROR_OUT_OF_MEMORY;
90 
91  //Initialize MD5 context
92  md5Init(context->handshakeMd5Context);
93  }
94 #endif
95 
96 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
97  //SSL 3.0, TLS 1.0, TLS 1.1 or TLS 1.2 currently selected?
98  if(context->version <= TLS_VERSION_1_2)
99  {
100  //Allocate SHA-1 context
101  context->handshakeSha1Context = tlsAllocMem(sizeof(Sha1Context));
102  //Failed to allocate memory?
103  if(context->handshakeSha1Context == NULL)
104  return ERROR_OUT_OF_MEMORY;
105 
106  //Initialize SHA-1 context
107  sha1Init(context->handshakeSha1Context);
108  }
109 #endif
110 
111 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
112  //TLS 1.2 or 1.3 currently selected?
113  if(context->version >= TLS_VERSION_1_2)
114  {
115  const HashAlgo *hashAlgo;
116 
117  //Point to the hash algorithm to be used
118  hashAlgo = context->cipherSuite.prfHashAlgo;
119  //Make sure the hash algorithm is valid
120  if(hashAlgo == NULL)
121  return ERROR_FAILURE;
122 
123  //Allocate hash algorithm context
124  context->handshakeHashContext = tlsAllocMem(hashAlgo->contextSize);
125  //Failed to allocate memory?
126  if(context->handshakeHashContext == NULL)
127  return ERROR_OUT_OF_MEMORY;
128 
129  //Initialize the hash algorithm context
130  hashAlgo->init(context->handshakeHashContext);
131  }
132 #endif
133 
134 #if (TLS_CLIENT_SUPPORT == ENABLED)
135  //TLS operates as a client?
136  if(context->entity == TLS_CONNECTION_END_CLIENT)
137  {
138 #if (DTLS_SUPPORT == ENABLED)
139  //DTLS protocol?
140  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
141  {
142  size_t length;
143  DtlsRecord *record;
144 
145  //Point to the DTLS record that holds the ClientHello message
146  record = (DtlsRecord *) context->txBuffer;
147 
148  //Sanity check
149  if(context->txBufferLen > sizeof(DtlsRecord))
150  {
151  //Retrieve the length of the handshake message
152  length = context->txBufferLen - sizeof(DtlsRecord);
153 
154  //Update the hash value with the ClientHello message
155  tlsUpdateTranscriptHash(context, record->data, length);
156  }
157  }
158  else
159 #endif
160  //TLS protocol?
161  {
162  size_t length;
163  TlsRecord *record;
164 
165  //Point to the TLS record that holds the ClientHello message
166  record = (TlsRecord *) context->txBuffer;
167 
168  //Retrieve the length of the handshake message
169  length = ntohs(record->length);
170 
171  //Sanity check
172  if((length + sizeof(TlsRecord)) <= context->txBufferSize)
173  {
174  //Update the hash value with the ClientHello message
175  tlsUpdateTranscriptHash(context, record->data, length);
176  }
177  }
178  }
179 #endif
180 
181  //Successful initialization
182  return NO_ERROR;
183 }
184 
185 
186 /**
187  * @brief Update hash value with a handshake message
188  * @param[in] context Pointer to the TLS context
189  * @param[in] data Pointer to the handshake message being hashed
190  * @param[in] length Length of the message
191  **/
192 
193 void tlsUpdateTranscriptHash(TlsContext *context, const void *data,
194  size_t length)
195 {
196 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1)
197  //SSL 3.0, TLS 1.0 or TLS 1.1 currently selected?
198  if(context->version <= TLS_VERSION_1_1)
199  {
200  //Valid MD5 context?
201  if(context->handshakeMd5Context != NULL)
202  {
203  //Update MD5 hash value with message contents
204  md5Update(context->handshakeMd5Context, data, length);
205  }
206  }
207 #endif
208 
209 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
210  //SSL 3.0, TLS 1.0, TLS 1.1 or TLS 1.2 currently selected?
211  if(context->version <= TLS_VERSION_1_2)
212  {
213  //Valid SHA-1 context?
214  if(context->handshakeSha1Context != NULL)
215  {
216  //Update SHA-1 hash value with message contents
217  sha1Update(context->handshakeSha1Context, data, length);
218  }
219  }
220 #endif
221 
222 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
223  //TLS 1.2 or TLS 1.3 currently selected?
224  if(context->version >= TLS_VERSION_1_2)
225  {
226  const HashAlgo *hashAlgo;
227 
228  //Point to the PRF hash algorithm to be used
229  hashAlgo = context->cipherSuite.prfHashAlgo;
230 
231  //Valid hash algorithm?
232  if(hashAlgo != NULL && context->handshakeHashContext != NULL)
233  {
234  //Update hash value with message contents
235  hashAlgo->update(context->handshakeHashContext, data, length);
236  }
237  }
238 #endif
239 }
240 
241 
242 /**
243  * @brief Finalize hash calculation from previous handshake messages
244  * @param[in] context Pointer to the TLS context
245  * @param[in] hash Hash function used to digest the handshake messages
246  * @param[in] hashContext Pointer to the hash context
247  * @param[in] label NULL-terminated string
248  * @param[out] output Buffer where to store the resulting hash value
249  * @return Error code
250  **/
251 
253  const void *hashContext, const char_t *label, uint8_t *output)
254 {
255  error_t error;
256  HashContext *tempHashContext;
257 
258  //Make sure the hash context is valid
259  if(hash == NULL || hashContext == NULL)
261 
262  //Allocate a temporary hash context
263  tempHashContext = tlsAllocMem(hash->contextSize);
264 
265  //Successful memory allocation?
266  if(tempHashContext != NULL)
267  {
268  //The original hash context must be preserved
269  memcpy(tempHashContext, hashContext, hash->contextSize);
270 
271 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= SSL_VERSION_3_0)
272  //SSL 3.0 currently selected?
273  if(context->version == SSL_VERSION_3_0)
274  {
275  size_t labelLen;
276  size_t padLen;
277 
278  //Retrieve the length of the label
279  labelLen = strlen(label);
280 
281  //The pad character is repeated 48 times for MD5 or 40 times for SHA-1
282  padLen = (hash == MD5_HASH_ALGO) ? 48 : 40;
283 
284  //hash(handshakeMessages + label + masterSecret + pad1)
285  hash->update(tempHashContext, label, labelLen);
286  hash->update(tempHashContext, context->masterSecret, TLS_MASTER_SECRET_SIZE);
287  hash->update(tempHashContext, sslPad1, padLen);
288  hash->final(tempHashContext, output);
289 
290  //hash(masterSecret + pad2 + hash(handshakeMessages + label +
291  //masterSecret + pad1))
292  hash->init(tempHashContext);
293  hash->update(tempHashContext, context->masterSecret, TLS_MASTER_SECRET_SIZE);
294  hash->update(tempHashContext, sslPad2, padLen);
295  hash->update(tempHashContext, output, hash->digestSize);
296  hash->final(tempHashContext, output);
297 
298  //Successful processing
299  error = NO_ERROR;
300  }
301  else
302 #endif
303 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
304  //TLS 1.0, TLS 1.1, TLS 1.2 or TLS 1.3 currently selected?
305  if(context->version >= TLS_VERSION_1_0 && context->version <= TLS_VERSION_1_3)
306  {
307  //Compute hash(handshakeMessages)
308  hash->final(tempHashContext, output);
309  //Successful processing
310  error = NO_ERROR;
311  }
312  else
313 #endif
314  //Invalid TLS version?
315  {
316  //Report an error
317  error = ERROR_INVALID_VERSION;
318  }
319 
320  //Release previously allocated resources
321  tlsFreeMem(tempHashContext);
322  }
323  else
324  {
325  //Failed to allocate memory
326  error = ERROR_OUT_OF_MEMORY;
327  }
328 
329  //Return status code
330  return error;
331 }
332 
333 
334 /**
335  * @brief Release transcript hash context
336  * @param[in] context Pointer to the TLS context
337  * @return Error code
338  **/
339 
341 {
342 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1)
343  //Release MD5 hash context
344  if(context->handshakeMd5Context != NULL)
345  {
346  memset(context->handshakeMd5Context, 0, sizeof(Md5Context));
347  tlsFreeMem(context->handshakeMd5Context);
348  context->handshakeMd5Context = NULL;
349  }
350 #endif
351 
352 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
353  //Release SHA-1 hash context
354  if(context->handshakeSha1Context != NULL)
355  {
356  memset(context->handshakeSha1Context, 0, sizeof(Sha1Context));
357  tlsFreeMem(context->handshakeSha1Context);
358  context->handshakeSha1Context = NULL;
359  }
360 #endif
361 
362 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
363  //Release transcript hash context
364  if(context->handshakeHashContext != NULL)
365  {
366  tlsFreeMem(context->handshakeHashContext);
367  context->handshakeHashContext = NULL;
368  }
369 #endif
370 }
371 
372 
373 /**
374  * @brief Compute verify data from previous handshake messages
375  * @param[in] context Pointer to the TLS context
376  * @param[in] entity Specifies whether the computation is performed at client
377  * or server side
378  * @param[out] verifyData Pointer to the buffer where to store the verify data
379  * @param[out] verifyDataLen Length of the verify data
380  * @return Error code
381  **/
382 
384  uint8_t *verifyData, size_t *verifyDataLen)
385 {
386  error_t error;
387 
388 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= SSL_VERSION_3_0)
389  //SSL 3.0 currently selected?
390  if(context->version == SSL_VERSION_3_0)
391  {
392  const char_t *label;
393 
394  //Check whether the computation is performed at client or server side
395  if(entity == TLS_CONNECTION_END_CLIENT)
396  label = "CLNT";
397  else
398  label = "SRVR";
399 
400  //Compute MD5(masterSecret + pad2 + MD5(handshakeMessages + label +
401  //masterSecret + pad1))
402  error = tlsFinalizeTranscriptHash(context, MD5_HASH_ALGO,
403  context->handshakeMd5Context, label, verifyData);
404 
405  //Check status code
406  if(!error)
407  {
408  //Compute SHA(masterSecret + pad2 + SHA(handshakeMessages + label +
409  //masterSecret + pad1))
410  error = tlsFinalizeTranscriptHash(context, SHA1_HASH_ALGO,
411  context->handshakeSha1Context, label, verifyData + MD5_DIGEST_SIZE);
412  }
413  }
414  else
415 #endif
416 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1)
417  //TLS 1.0 or 1.1 currently selected?
418  if(context->version == TLS_VERSION_1_0 || context->version == TLS_VERSION_1_1)
419  {
420  const char_t *label;
421  uint8_t digest[MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE];
422 
423  //Finalize MD5 hash computation
424  error = tlsFinalizeTranscriptHash(context, MD5_HASH_ALGO,
425  context->handshakeMd5Context, "", digest);
426 
427  //Check status code
428  if(!error)
429  {
430  //Finalize SHA-1 hash computation
431  error = tlsFinalizeTranscriptHash(context, SHA1_HASH_ALGO,
432  context->handshakeSha1Context, "", digest + MD5_DIGEST_SIZE);
433  }
434 
435  //Check status code
436  if(!error)
437  {
438  //Check whether the computation is performed at client or server side
439  if(entity == TLS_CONNECTION_END_CLIENT)
440  label = "client finished";
441  else
442  label = "server finished";
443 
444  //The verify data is always 12-byte long for TLS 1.0 and 1.1
445  error = tlsPrf(context->masterSecret, TLS_MASTER_SECRET_SIZE,
446  label, digest, sizeof(digest), verifyData, 12);
447  }
448  }
449  else
450 #endif
451 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
452  //TLS 1.2 currently selected?
453  if(context->version == TLS_VERSION_1_2)
454  {
455  const char_t *label;
456  const HashAlgo *hashAlgo;
457  HashContext *hashContext;
458 
459  //Point to the hash algorithm to be used
460  hashAlgo = context->cipherSuite.prfHashAlgo;
461 
462  //Valid hash algorithm?
463  if(hashAlgo != NULL && context->handshakeHashContext != NULL)
464  {
465  //Allocate hash algorithm context
466  hashContext = tlsAllocMem(hashAlgo->contextSize);
467 
468  //Successful memory allocation?
469  if(hashContext != NULL)
470  {
471  //The original hash context must be preserved
472  memcpy(hashContext, context->handshakeHashContext,
473  hashAlgo->contextSize);
474 
475  //Finalize hash computation
476  hashAlgo->final(hashContext, NULL);
477 
478  //Check whether the computation is performed at client or server side
479  if(entity == TLS_CONNECTION_END_CLIENT)
480  label = "client finished";
481  else
482  label = "server finished";
483 
484  //Compute the verify data
485  error = tls12Prf(hashAlgo, context->masterSecret, TLS_MASTER_SECRET_SIZE,
486  label, hashContext->digest, hashAlgo->digestSize,
487  verifyData, context->cipherSuite.verifyDataLen);
488 
489  //Release previously allocated memory
490  tlsFreeMem(hashContext);
491  }
492  else
493  {
494  //Failed to allocate memory
495  error = ERROR_OUT_OF_MEMORY;
496  }
497  }
498  else
499  {
500  //Invalid hash algorithm
501  error = ERROR_FAILURE;
502  }
503  }
504  else
505 #endif
506 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
507  //TLS 1.3 currently selected?
508  if(context->version == TLS_VERSION_1_3)
509  {
510  uint8_t *baseKey;
511  const HashAlgo *hashAlgo;
512  uint8_t digest[TLS_MAX_HKDF_DIGEST_SIZE];
513  uint8_t finishedKey[TLS_MAX_HKDF_DIGEST_SIZE];
514 
515  //The hash function used by HKDF is the cipher suite hash algorithm
516  hashAlgo = context->cipherSuite.prfHashAlgo;
517 
518  //Valid hash algorithm?
519  if(hashAlgo != NULL && context->handshakeHashContext != NULL)
520  {
521  //Check whether the computation is performed at client or server side
522  if(entity == TLS_CONNECTION_END_CLIENT)
523  baseKey = context->clientHsTrafficSecret;
524  else
525  baseKey = context->serverHsTrafficSecret;
526 
527  //The key used to compute the Finished message is computed from the
528  //base key using HKDF
529  error = tls13HkdfExpandLabel(hashAlgo, baseKey, hashAlgo->digestSize,
530  "finished", NULL, 0, finishedKey, hashAlgo->digestSize);
531 
532  //Check status code
533  if(!error)
534  {
535  //Compute the transcript hash
536  error = tlsFinalizeTranscriptHash(context, hashAlgo,
537  context->handshakeHashContext, "", digest);
538  }
539 
540  //Check status code
541  if(!error)
542  {
543  //Compute the verify data
544  error = hmacCompute(hashAlgo, finishedKey, hashAlgo->digestSize,
545  digest, hashAlgo->digestSize, verifyData);
546  }
547  }
548  else
549  {
550  //Invalid hash algorithm
551  error = ERROR_FAILURE;
552  }
553  }
554  else
555 #endif
556  //Invalid TLS version?
557  {
558  //Report an error
559  error = ERROR_INVALID_VERSION;
560  }
561 
562  //Check status code
563  if(!error)
564  {
565  //Save the length of the verify data
566  *verifyDataLen = context->cipherSuite.verifyDataLen;
567 
568  //Debug message
569  TRACE_DEBUG("Verify data:\r\n");
570  TRACE_DEBUG_ARRAY(" ", verifyData, *verifyDataLen);
571  }
572 
573  //Return status code
574  return error;
575 }
576 
577 #endif
TLS (Transport Layer Security)
__start_packed struct @83 TlsRecord
TLS record.
char char_t
Definition: compiler_port.h:41
Handshake message processing (TLS client)
uint8_t digest[1]
Definition: crypto.h:1046
void sha1Init(Sha1Context *context)
Initialize SHA-1 message digest context.
Definition: sha1.c:124
Debugging facilities.
#define tlsFreeMem(p)
Definition: tls.h:760
uint8_t hash
Definition: tls.h:1363
TLS 1.3 key schedule.
Generic error code.
Definition: error.h:43
SHA-1 algorithm context.
Definition: sha1.h:54
Invalid parameter.
Definition: error.h:45
HashAlgoInit init
Definition: crypto.h:1063
#define TLS_VERSION_1_3
Definition: tls.h:90
#define SHA1_DIGEST_SIZE
Definition: sha1.h:38
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:99
Generic hash algorithm context.
Definition: crypto.h:1044
void tlsFreeTranscriptHash(TlsContext *context)
Release transcript hash context.
error_t tlsInitTranscriptHash(TlsContext *context)
Initialize handshake message hashing.
__start_packed struct @58 DtlsRecord
DTLS record.
error_t tlsComputeVerifyData(TlsContext *context, TlsConnectionEnd entity, uint8_t *verifyData, size_t *verifyDataLen)
Compute verify data from previous handshake messages.
#define ntohs(value)
Definition: cpu_endian.h:396
const uint8_t sslPad1[48]
size_t contextSize
Definition: crypto.h:1059
MD5 algorithm context.
Definition: md5.h:54
error_t tls13HkdfExpandLabel(const HashAlgo *hash, const uint8_t *secret, size_t secretLen, const char_t *label, const uint8_t *context, size_t contextLen, uint8_t *output, size_t outputLen)
#define TLS_VERSION_1_2
Definition: tls.h:83
#define TLS_VERSION_1_1
Definition: tls.h:82
SSL 3.0 helper functions.
Success.
Definition: error.h:42
error_t
Error codes.
Definition: error.h:40
error_t tlsFinalizeTranscriptHash(TlsContext *context, const HashAlgo *hash, const void *hashContext, const char_t *label, uint8_t *output)
Finalize hash calculation from previous handshake messages.
#define TLS_VERSION_1_0
Definition: tls.h:81
uint8_t data[]
Definition: dtls_misc.h:167
error_t tls12Prf(const HashAlgo *hash, const uint8_t *secret, size_t secretLen, const char_t *label, const uint8_t *seed, size_t seedLen, uint8_t *output, size_t outputLen)
Pseudorandom function (TLS 1.2)
void sha1Update(Sha1Context *context, const void *data, size_t length)
Update the SHA-1 context with a portion of the message being hashed.
Definition: sha1.c:147
error_t hmacCompute(const HashAlgo *hash, const void *key, size_t keyLen, const void *data, size_t dataLen, uint8_t *digest)
Compute HMAC using the specified hash function.
Definition: hmac.c:83
#define SHA1_HASH_ALGO
Definition: sha1.h:42
void tlsUpdateTranscriptHash(TlsContext *context, const void *data, size_t length)
Update hash value with a handshake message.
TlsConnectionEnd
TLS connection end.
Definition: tls.h:855
void md5Init(Md5Context *context)
Initialize MD5 message digest context.
Definition: md5.c:131
Key material generation.
#define MD5_DIGEST_SIZE
Definition: md5.h:38
Transcript hash calculation.
HashAlgoFinal final
Definition: crypto.h:1065
#define tlsAllocMem(size)
Definition: tls.h:755
size_t digestSize
Definition: crypto.h:1061
#define TLS_MAX_HKDF_DIGEST_SIZE
Definition: tls.h:815
Common interface for hash algorithms.
Definition: crypto.h:1054
uint8_t length
Definition: dtls_misc.h:140
const uint8_t sslPad2[48]
HashAlgoUpdate update
Definition: crypto.h:1064
#define TlsContext
Definition: tls.h:34
error_t tlsPrf(const uint8_t *secret, size_t secretLen, const char_t *label, const uint8_t *seed, size_t seedLen, uint8_t *output, size_t outputLen)
Pseudorandom function (TLS 1.0 and 1.1)
#define MD5_HASH_ALGO
Definition: md5.h:42
#define SSL_VERSION_3_0
Definition: tls.h:80
#define TRACE_DEBUG(...)
Definition: debug.h:98
#define TLS_MASTER_SECRET_SIZE
Definition: tls.h:832
void md5Update(Md5Context *context, const void *data, size_t length)
Update the MD5 context with a portion of the message being hashed.
Definition: md5.c:153