ssl_misc.c
Go to the documentation of this file.
1 /**
2  * @file ssl_misc.c
3  * @brief SSL 3.0 helper functions
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 "core/crypto.h"
35 #include "tls.h"
36 #include "ssl_misc.h"
37 #include "debug.h"
38 
39 //Check TLS library configuration
40 #if (TLS_SUPPORT == ENABLED && TLS_MIN_VERSION <= SSL_VERSION_3_0)
41 
42 //pad1 pattern
43 const uint8_t sslPad1[48] =
44 {
45  0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
46  0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
47  0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
48 };
49 
50 //pad2 pattern
51 const uint8_t sslPad2[48] =
52 {
53  0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
54  0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
55  0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
56 };
57 
58 
59 /**
60  * @brief Key expansion function (SSL 3.0)
61  * @param[in] secret Pointer to the secret
62  * @param[in] secretLen Length of the secret
63  * @param[in] random Pointer to the random bytes
64  * @param[in] randomLen Length of the random bytes
65  * @param[out] output Pointer to the output
66  * @param[in] outputLen Desired output length
67  * @return Error code
68  **/
69 
70 error_t sslExpandKey(const uint8_t *secret, size_t secretLen,
71  const uint8_t *random, size_t randomLen, uint8_t *output, size_t outputLen)
72 {
73  uint_t i;
74  size_t n;
75  char_t pad[16];
76  Md5Context *md5Context;
77  Sha1Context *sha1Context;
78 
79  //Output length cannot exceed 256 bytes
80  if(outputLen > (sizeof(pad) * MD5_DIGEST_SIZE))
81  return ERROR_INVALID_LENGTH;
82 
83  //Allocate a memory buffer to hold the MD5 context
84  md5Context = tlsAllocMem(sizeof(Md5Context));
85  //Failed to allocate memory?
86  if(md5Context == NULL)
87  {
88  //Report an error
89  return ERROR_OUT_OF_MEMORY;
90  }
91 
92  //Allocate a memory buffer to hold the SHA-1 context
93  sha1Context = tlsAllocMem(sizeof(Sha1Context));
94  //Failed to allocate memory?
95  if(sha1Context == NULL)
96  {
97  //Clean up side effects
98  tlsFreeMem(md5Context);
99  //Report an error
100  return ERROR_OUT_OF_MEMORY;
101  }
102 
103  //Loop until enough output has been generated
104  for(i = 0; outputLen > 0; i++)
105  {
106  //Generate pad
107  memset(pad, 'A' + i, i + 1);
108 
109  //Compute SHA(pad + secret + random)
110  sha1Init(sha1Context);
111  sha1Update(sha1Context, pad, i + 1);
112  sha1Update(sha1Context, secret, secretLen);
113  sha1Update(sha1Context, random, randomLen);
114  sha1Final(sha1Context, NULL);
115 
116  //Then compute MD5(secret + SHA(pad + secret + random))
117  md5Init(md5Context);
118  md5Update(md5Context, secret, secretLen);
119  md5Update(md5Context, sha1Context->digest, SHA1_DIGEST_SIZE);
120  md5Final(md5Context, NULL);
121 
122  //Calculate the number of bytes to copy
123  n = MIN(outputLen, MD5_DIGEST_SIZE);
124  //Copy the resulting hash value
125  memcpy(output, md5Context->digest, n);
126 
127  //Advance data pointer
128  output += n;
129  //Decrement byte counter
130  outputLen -= n;
131  }
132 
133  //Release previously allocated resources
134  tlsFreeMem(md5Context);
135  tlsFreeMem(sha1Context);
136 
137  //Successful processing
138  return NO_ERROR;
139 }
140 
141 
142 /**
143  * @brief Compute message authentication code (SSL 3.0)
144  * @param[in] encryptionEngine Pointer to the encryption/decryption engine
145  * @param[in] record Pointer to the TLS record
146  * @param[in] data Pointer to the record data
147  * @param[in] dataLen Length of the data
148  * @param[out] mac The computed MAC value
149  * @return Error code
150  **/
151 
152 error_t sslComputeMac(TlsEncryptionEngine *encryptionEngine,
153  const TlsRecord *record, const uint8_t *data, size_t dataLen, uint8_t *mac)
154 {
155  size_t padLen;
156  const HashAlgo *hashAlgo;
157  HashContext *hashContext;
158 
159  //Point to the hash algorithm to be used
160  hashAlgo = encryptionEngine->hashAlgo;
161  //Point to the hash context
162  hashContext = (HashContext *) encryptionEngine->hmacContext->hashContext;
163 
164  //The length of pad1 and pad2 depends on hash algorithm
165  if(hashAlgo == MD5_HASH_ALGO)
166  {
167  //48-byte long patterns are used with MD5
168  padLen = 48;
169  }
170  else if(hashAlgo == SHA1_HASH_ALGO)
171  {
172  //40-byte long patterns are used with SHA-1
173  padLen = 40;
174  }
175  else
176  {
177  //SSL 3.0 supports only MD5 and SHA-1 hash functions
179  }
180 
181  //Compute hash(secret + pad1 + seqNum + type + length + data)
182  hashAlgo->init(hashContext);
183  hashAlgo->update(hashContext, encryptionEngine->macKey, encryptionEngine->macKeyLen);
184  hashAlgo->update(hashContext, sslPad1, padLen);
185  hashAlgo->update(hashContext, &encryptionEngine->seqNum, sizeof(TlsSequenceNumber));
186  hashAlgo->update(hashContext, &record->type, sizeof(record->type));
187  hashAlgo->update(hashContext, (void *) &record->length, sizeof(record->length));
188  hashAlgo->update(hashContext, data, dataLen);
189  hashAlgo->final(hashContext, mac);
190 
191  //Then compute hash(secret + pad2 + hash(secret + pad1 + seqNum + type + length + data))
192  hashAlgo->init(hashContext);
193  hashAlgo->update(hashContext, encryptionEngine->macKey, encryptionEngine->macKeyLen);
194  hashAlgo->update(hashContext, sslPad2, padLen);
195  hashAlgo->update(hashContext, mac, hashAlgo->digestSize);
196  hashAlgo->final(hashContext, mac);
197 
198  //Successful processing
199  return NO_ERROR;
200 }
201 
202 #endif
uint8_t hashContext[MAX_HASH_CONTEXT_SIZE]
Definition: hmac.h:183
TLS (Transport Layer Security)
__start_packed struct @83 TlsRecord
TLS record.
char char_t
Definition: compiler_port.h:41
void sha1Init(Sha1Context *context)
Initialize SHA-1 message digest context.
Definition: sha1.c:124
error_t sslExpandKey(const uint8_t *secret, size_t secretLen, const uint8_t *random, size_t randomLen, uint8_t *output, size_t outputLen)
Debugging facilities.
#define tlsFreeMem(p)
Definition: tls.h:760
SHA-1 algorithm context.
Definition: sha1.h:54
General definitions for cryptographic algorithms.
Invalid parameter.
Definition: error.h:45
HashAlgoInit init
Definition: crypto.h:1063
#define SHA1_DIGEST_SIZE
Definition: sha1.h:38
HmacContext * hmacContext
HMAC context.
Definition: tls.h:1941
Generic hash algorithm context.
Definition: crypto.h:1044
void md5Final(Md5Context *context, uint8_t *digest)
Finish the MD5 message digest.
Definition: md5.c:192
TlsSequenceNumber seqNum
TLS sequence number.
Definition: tls.h:1945
const uint8_t sslPad1[48]
uint8_t digest[16]
Definition: md5.h:59
const HashAlgo * hashAlgo
Hash algorithm for MAC operations.
Definition: tls.h:1940
MD5 algorithm context.
Definition: md5.h:54
#define MIN(a, b)
Definition: os_port.h:60
Encryption engine.
Definition: tls.h:1926
uint8_t macKey[48]
MAC key.
Definition: tls.h:1929
SSL 3.0 helper functions.
void sha1Final(Sha1Context *context, uint8_t *digest)
Finish the SHA-1 message digest.
Definition: sha1.c:186
Success.
Definition: error.h:42
error_t
Error codes.
Definition: error.h:40
uint8_t digest[20]
Definition: sha1.h:59
unsigned int uint_t
Definition: compiler_port.h:43
uint8_t data[]
Definition: dtls_misc.h:167
__start_packed struct @61 TlsSequenceNumber
Sequence number.
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
size_t macKeyLen
Length of the MAC key.
Definition: tls.h:1930
#define SHA1_HASH_ALGO
Definition: sha1.h:42
uint8_t random[32]
Definition: tls.h:1608
error_t sslComputeMac(TlsEncryptionEngine *encryptionEngine, const TlsRecord *record, const uint8_t *data, size_t dataLen, uint8_t *mac)
void md5Init(Md5Context *context)
Initialize MD5 message digest context.
Definition: md5.c:131
#define MD5_DIGEST_SIZE
Definition: md5.h:38
HashAlgoFinal final
Definition: crypto.h:1065
#define tlsAllocMem(size)
Definition: tls.h:755
size_t digestSize
Definition: crypto.h:1061
Common interface for hash algorithms.
Definition: crypto.h:1054
uint8_t n
const uint8_t sslPad2[48]
HashAlgoUpdate update
Definition: crypto.h:1064
#define MD5_HASH_ALGO
Definition: md5.h:42
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