Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ssl_common.c Source File

ssl_common.c

Go to the documentation of this file.
00001 /**
00002  * @file ssl_common.c
00003  * @brief Functions common to SSL 3.0 client and server
00004  *
00005  * @section License
00006  *
00007  * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
00008  *
00009  * This file is part of CycloneSSL Open.
00010  *
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU General Public License
00013  * as published by the Free Software Foundation; either version 2
00014  * of the License, or (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software Foundation,
00023  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00024  *
00025  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00026  * @version 1.7.6
00027  **/
00028 
00029 //Switch to the appropriate trace level
00030 #define TRACE_LEVEL TLS_TRACE_LEVEL
00031 
00032 //Dependencies
00033 #include <string.h>
00034 #include "crypto.h"
00035 #include "tls.h"
00036 #include "ssl_common.h"
00037 #include "debug.h"
00038 
00039 //Check SSL library configuration
00040 #if (TLS_SUPPORT == ENABLED)
00041 
00042 //pad1 pattern
00043 const uint8_t sslPad1[48] =
00044 {
00045    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
00046    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
00047    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
00048 };
00049 
00050 //pad2 pattern
00051 const uint8_t sslPad2[48] =
00052 {
00053    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
00054    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
00055    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
00056 };
00057 
00058 
00059 /**
00060  * @brief Key expansion function (SSL 3.0)
00061  * @param[in] secret Pointer to the secret
00062  * @param[in] secretLength Length of the secret
00063  * @param[in] random Pointer to the random bytes
00064  * @param[in] randomLength Length of the random bytes
00065  * @param[out] output Pointer to the output
00066  * @param[in] outputLength Desired output length
00067  * @return Error code
00068  **/
00069 
00070 error_t sslExpandKey(const uint8_t *secret, size_t secretLength,
00071    const uint8_t *random, size_t randomLength, uint8_t *output, size_t outputLength)
00072 {
00073    uint_t i;
00074    size_t n;
00075    char_t pad[16];
00076    Md5Context *md5Context;
00077    Sha1Context *sha1Context;
00078 
00079    //Output length cannot exceed 256 bytes
00080    if(outputLength > (sizeof(pad) * MD5_DIGEST_SIZE))
00081       return ERROR_INVALID_LENGTH;
00082 
00083    //Allocate a memory buffer to hold the MD5 context
00084    md5Context = tlsAllocMem(sizeof(Md5Context));
00085    //Allocate a memory buffer to hold the SHA-1 context
00086    sha1Context = tlsAllocMem(sizeof(Sha1Context));
00087 
00088    //Failed to allocate memory?
00089    if(md5Context == NULL || sha1Context == NULL)
00090    {
00091       //Release previously allocated resources
00092       tlsFreeMem(md5Context);
00093       tlsFreeMem(sha1Context);
00094 
00095       //Report an error
00096       return ERROR_OUT_OF_MEMORY;
00097    }
00098 
00099    //Loop until enough output has been generated
00100    for(i = 0; outputLength > 0; i++)
00101    {
00102       //Generate pad
00103       memset(pad, 'A' + i, i + 1);
00104 
00105       //Compute SHA(pad + secret + random)
00106       sha1Init(sha1Context);
00107       sha1Update(sha1Context, pad, i + 1);
00108       sha1Update(sha1Context, secret, secretLength);
00109       sha1Update(sha1Context, random, randomLength);
00110       sha1Final(sha1Context, NULL);
00111 
00112       //Then compute MD5(secret + SHA(pad + secret + random))
00113       md5Init(md5Context);
00114       md5Update(md5Context, secret, secretLength);
00115       md5Update(md5Context, sha1Context->digest, SHA1_DIGEST_SIZE);
00116       md5Final(md5Context, NULL);
00117 
00118       //Calculate the number of bytes to copy
00119       n = MIN(outputLength, MD5_DIGEST_SIZE);
00120       //Copy the resulting hash value
00121       memcpy(output, md5Context->digest, n);
00122 
00123       //Advance data pointer
00124       output += n;
00125       //Decrement byte counter
00126       outputLength -= n;
00127    }
00128 
00129    //Release previously allocated resources
00130    tlsFreeMem(md5Context);
00131    tlsFreeMem(sha1Context);
00132 
00133    //Successful processing
00134    return NO_ERROR;
00135 }
00136 
00137 
00138 /**
00139  * @brief Compute message authentication code (SSL 3.0)
00140  * @param[in] context Pointer to the TLS context
00141  * @param[in] secret MAC secret
00142  * @param[in] seqNum 64-bit sequence number
00143  * @param[in] record Pointer to the TLS record
00144  * @param[in] data Pointer to the record data
00145  * @param[in] length Length of the data
00146  * @param[out] mac The computed MAC value
00147  * @return Error code
00148  **/
00149 
00150 error_t sslComputeMac(TlsContext *context, const void *secret, TlsSequenceNumber seqNum,
00151    const TlsRecord *record, const uint8_t *data, size_t length, uint8_t *mac)
00152 {
00153    size_t padLength;
00154    HashContext *hashContext;
00155    const HashAlgo *hash;
00156 
00157    //Hash function that will be used to compute MAC
00158    hash = context->hashAlgo;
00159    //Point to the hash context
00160    hashContext = (HashContext *) context->hmacContext.hashContext;
00161 
00162    //The length of pad1 and pad2 depends on hash algorithm
00163    if(hash == MD5_HASH_ALGO)
00164    {
00165       //48-byte long patterns are used with MD5
00166       padLength = 48;
00167    }
00168    else if(hash == SHA1_HASH_ALGO)
00169    {
00170       //40-byte long patterns are used with SHA-1
00171       padLength = 40;
00172    }
00173    else
00174    {
00175       //SSL 3.0 supports only MD5 and SHA-1 hash functions
00176       return ERROR_INVALID_PARAMETER;
00177    }
00178 
00179    //Compute hash(secret + pad1 + seqNum + type + length + data)
00180    hash->init(hashContext);
00181    hash->update(hashContext, secret, context->macKeyLen);
00182    hash->update(hashContext, sslPad1, padLength);
00183    hash->update(hashContext, seqNum, sizeof(TlsSequenceNumber));
00184    hash->update(hashContext, &record->type, sizeof(record->type));
00185    hash->update(hashContext, (void *) &record->length, sizeof(record->length));
00186    hash->update(hashContext, data, length);
00187    hash->final(hashContext, mac);
00188 
00189    //Then compute hash(secret + pad2 + hash(secret + pad1 + seqNum + type + length + data))
00190    hash->init(hashContext);
00191    hash->update(hashContext, secret, context->macKeyLen);
00192    hash->update(hashContext, sslPad2, padLength);
00193    hash->update(hashContext, mac, hash->digestSize);
00194    hash->final(hashContext, mac);
00195 
00196    //Successful processing
00197    return NO_ERROR;
00198 }
00199 
00200 #endif
00201