Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
tls_misc.c
00001 /** 00002 * @file tls_misc.c 00003 * @brief Helper functions (TLS 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 "tls.h" 00035 #include "tls_cipher_suites.h" 00036 #include "tls_common.h" 00037 #include "tls_record.h" 00038 #include "tls_misc.h" 00039 #include "ssl_common.h" 00040 #include "asn1.h" 00041 #include "oid.h" 00042 #include "x509.h" 00043 #include "pem.h" 00044 #include "debug.h" 00045 00046 //Check SSL library configuration 00047 #if (TLS_SUPPORT == ENABLED) 00048 00049 00050 /** 00051 * @brief Translate an error code to an alert message 00052 * @param[in] context Pointer to the TLS context 00053 * @param[in] errorCode Internal error code 00054 * @return Error code 00055 **/ 00056 00057 void tlsProcessError(TlsContext *context, error_t errorCode) 00058 { 00059 //Check current state 00060 if(context->state != TLS_STATE_CLOSED) 00061 { 00062 //Check status code 00063 switch(errorCode) 00064 { 00065 //The timeout interval has elapsed 00066 case ERROR_TIMEOUT: 00067 break; 00068 //The read/write operation would have blocked 00069 case ERROR_WOULD_BLOCK: 00070 break; 00071 //The read/write operation has failed 00072 case ERROR_WRITE_FAILED: 00073 case ERROR_READ_FAILED: 00074 break; 00075 //An inappropriate message was received 00076 case ERROR_UNEXPECTED_MESSAGE: 00077 tlsSendAlert(context, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_UNEXPECTED_MESSAGE); 00078 break; 00079 //A record is received with an incorrect MAC 00080 case ERROR_BAD_RECORD_MAC: 00081 tlsSendAlert(context, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_BAD_RECORD_MAC); 00082 break; 00083 //Invalid record length 00084 case ERROR_RECORD_OVERFLOW: 00085 tlsSendAlert(context, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_RECORD_OVERFLOW); 00086 break; 00087 //Unable to negotiate an acceptable set of security parameters 00088 case ERROR_HANDSHAKE_FAILED: 00089 tlsSendAlert(context, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_HANDSHAKE_FAILURE); 00090 break; 00091 //A certificate was corrupt 00092 case ERROR_BAD_CERTIFICATE: 00093 tlsSendAlert(context, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_BAD_CERTIFICATE); 00094 break; 00095 //A certificate was of an unsupported type 00096 case ERROR_UNSUPPORTED_CERTIFICATE: 00097 tlsSendAlert(context, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_UNSUPPORTED_CERTIFICATE); 00098 break; 00099 //A certificate has expired or is not currently valid 00100 case ERROR_CERTIFICATE_EXPIRED: 00101 tlsSendAlert(context, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_CERTIFICATE_EXPIRED); 00102 break; 00103 //A field in the handshake was out of range or inconsistent with other fields 00104 case ERROR_ILLEGAL_PARAMETER: 00105 tlsSendAlert(context, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_ILLEGAL_PARAMETER); 00106 break; 00107 //The certificate could not be matched with a known, trusted CA 00108 case ERROR_UNKNOWN_CA: 00109 tlsSendAlert(context, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_UNKNOWN_CA); 00110 break; 00111 //A message could not be decoded because some field was incorrect 00112 case ERROR_DECODING_FAILED: 00113 tlsSendAlert(context, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR); 00114 break; 00115 //A handshake cryptographic operation failed 00116 case ERROR_INVALID_SIGNATURE: 00117 tlsSendAlert(context, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECRYPT_ERROR); 00118 break; 00119 //The protocol version the client has attempted to negotiate is not supported 00120 case ERROR_VERSION_NOT_SUPPORTED: 00121 tlsSendAlert(context, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_PROTOCOL_VERSION); 00122 break; 00123 //Internal error 00124 default: 00125 tlsSendAlert(context, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_INTERNAL_ERROR); 00126 break; 00127 } 00128 } 00129 } 00130 00131 00132 /** 00133 * @brief Generate client or server random value 00134 * @param[in] context Pointer to the TLS context 00135 * @param[out] random Pointer to the random value 00136 * @return Error code 00137 **/ 00138 00139 error_t tlsGenerateRandomValue(TlsContext *context, TlsRandom *random) 00140 { 00141 error_t error; 00142 uint32_t time; 00143 00144 //Verify that the pseudorandom number generator is properly configured 00145 if(context->prngAlgo != NULL && context->prngContext != NULL) 00146 { 00147 //Get current time 00148 time = (uint32_t) getCurrentUnixTime(); 00149 00150 //Clocks are not required to be set correctly by the basic TLS protocol 00151 if(time != 0) 00152 { 00153 //Generate the random value. The first four bytes code the current 00154 //time and date in standard Unix format 00155 random->gmtUnixTime = htonl(time); 00156 00157 //The last 28 bytes contain securely-generated random bytes 00158 error = context->prngAlgo->read(context->prngContext, random->randomBytes, 28); 00159 } 00160 else 00161 { 00162 //Generate a 32-byte random value using a cryptographically-safe 00163 //pseudorandom number generator 00164 error = context->prngAlgo->read(context->prngContext, (uint8_t *) random, 32); 00165 } 00166 } 00167 else 00168 { 00169 //Report an error 00170 error = ERROR_NOT_CONFIGURED; 00171 } 00172 00173 //Return status code 00174 return error; 00175 } 00176 00177 00178 /** 00179 * @brief Set TLS version to use 00180 * @param[in] context Pointer to the TLS context 00181 * @param[in] version TLS version 00182 * @return Error code 00183 **/ 00184 00185 error_t tlsSetVersion(TlsContext *context, uint16_t version) 00186 { 00187 //Check TLS version 00188 if(version < TLS_MIN_VERSION || version > TLS_MAX_VERSION) 00189 { 00190 //Debug message 00191 TRACE_WARNING("TLS version not supported!\r\n"); 00192 //Report an error 00193 return ERROR_VERSION_NOT_SUPPORTED; 00194 } 00195 00196 //Save the TLS protocol version to use 00197 context->version = version; 00198 //Successful processing 00199 return NO_ERROR; 00200 } 00201 00202 00203 /** 00204 * @brief Set cipher suite 00205 * @param[in] context Pointer to the TLS context 00206 * @param[in] identifier Cipher suite identifier 00207 * @return Error code 00208 **/ 00209 00210 error_t tlsSetCipherSuite(TlsContext *context, uint16_t identifier) 00211 { 00212 error_t error; 00213 uint_t i; 00214 uint_t n; 00215 bool_t acceptable; 00216 const TlsCipherSuiteInfo *cipherSuite; 00217 00218 //Initialize pointer 00219 cipherSuite = NULL; 00220 00221 //Restrict the use of certain cipher suites? 00222 if(context->numCipherSuites > 0) 00223 { 00224 //This flag will be set if the specified cipher suite is acceptable 00225 acceptable = FALSE; 00226 00227 //Loop through allowed cipher suites 00228 for(i = 0; i < context->numCipherSuites; i++) 00229 { 00230 //Compare cipher suite identifiers 00231 if(context->cipherSuites[i] == identifier) 00232 { 00233 acceptable = TRUE; 00234 break; 00235 } 00236 } 00237 } 00238 else 00239 { 00240 //The use of the cipher suite is not restricted 00241 acceptable = TRUE; 00242 } 00243 00244 //No restrictions exist concerning the use of the specified cipher suite? 00245 if(acceptable) 00246 { 00247 //This flag will be set if the specified cipher suite is acceptable 00248 acceptable = FALSE; 00249 00250 //Determine the number of supported cipher suites 00251 n = tlsGetNumSupportedCipherSuites(); 00252 00253 //Loop through the list of supported cipher suites 00254 for(i = 0; i < n; i++) 00255 { 00256 //Point to the current item 00257 cipherSuite = &tlsSupportedCipherSuites[i]; 00258 00259 //Compare cipher suite identifiers 00260 if(cipherSuite->identifier == identifier) 00261 { 00262 acceptable = TRUE; 00263 break; 00264 } 00265 } 00266 } 00267 00268 //TLS 1.2 cipher suites must not be negotiated in older versions of TLS 00269 if(acceptable && context->version < TLS_VERSION_1_2) 00270 { 00271 if(cipherSuite->prfHashAlgo != NULL) 00272 acceptable = FALSE; 00273 } 00274 00275 //Ensure that the selected cipher suite matches all the criteria 00276 if(acceptable) 00277 { 00278 //Save cipher suite identifier 00279 context->cipherSuite = identifier; 00280 //Set key exchange method 00281 context->keyExchMethod = cipherSuite->keyExchMethod; 00282 00283 //Set encryption algorithm and hash function 00284 context->cipherAlgo = cipherSuite->cipherAlgo; 00285 context->cipherMode = cipherSuite->cipherMode; 00286 context->hashAlgo = cipherSuite->hashAlgo; 00287 context->prfHashAlgo = cipherSuite->prfHashAlgo; 00288 00289 //Set appropriate length for MAC keys, encryption keys and IVs 00290 context->macKeyLen = cipherSuite->macKeyLen; 00291 context->encKeyLen = cipherSuite->encKeyLen; 00292 context->fixedIvLen = cipherSuite->fixedIvLen; 00293 context->recordIvLen = cipherSuite->recordIvLen; 00294 00295 //Size of the authentication tag 00296 context->authTagLen = cipherSuite->authTagLen; 00297 //Size of the verify data 00298 context->verifyDataLen = cipherSuite->verifyDataLen; 00299 00300 //PRF with the SHA-256 is used for all cipher suites published 00301 //prior than TLS 1.2 when TLS 1.2 is negotiated 00302 if(context->prfHashAlgo == NULL) 00303 context->prfHashAlgo = SHA256_HASH_ALGO; 00304 00305 //The length of the verify data depends on the TLS version currently used 00306 if(context->version == SSL_VERSION_3_0) 00307 context->verifyDataLen = 36; 00308 else if(context->version <= TLS_VERSION_1_1) 00309 context->verifyDataLen = 12; 00310 00311 //Successful processing 00312 error = NO_ERROR; 00313 } 00314 else 00315 { 00316 //Debug message 00317 TRACE_ERROR("Cipher suite not supported!\r\n"); 00318 //The specified cipher suite is not supported 00319 error = ERROR_HANDSHAKE_FAILED; 00320 } 00321 00322 //Return status code 00323 return error; 00324 } 00325 00326 00327 /** 00328 * @brief Set compression method 00329 * @param[in] context Pointer to the TLS context 00330 * @param[in] identifier Compression method identifier 00331 * @return Error code 00332 **/ 00333 00334 error_t tlsSetCompressionMethod(TlsContext *context, uint8_t identifier) 00335 { 00336 //Check if the requested compression algorithm is supported 00337 if(identifier != TLS_COMPRESSION_METHOD_NULL) 00338 return ERROR_HANDSHAKE_FAILED; 00339 00340 //Save compression method identifier 00341 context->compressionMethod = identifier; 00342 //Successful processing 00343 return NO_ERROR; 00344 } 00345 00346 00347 /** 00348 * @brief Select the hash algorithm to be used when generating signatures 00349 * @param[in] context Pointer to the TLS context 00350 * @param[in] signAlgo Desired signature algorithm (RSA, DSA or ECDSA) 00351 * @param[in] supportedSignAlgos List of supported signature/hash algorithm pairs 00352 * @return Error code 00353 **/ 00354 00355 error_t tlsSelectSignHashAlgo(TlsContext *context, 00356 TlsSignatureAlgo signAlgo, const TlsSignHashAlgos *supportedSignAlgos) 00357 { 00358 uint_t i; 00359 uint_t n; 00360 00361 //Check whether the peer has provided a list of supported 00362 //hash/signature algorithm pairs? 00363 if(supportedSignAlgos != NULL) 00364 { 00365 //Process the list and select the relevant hash algorithm... 00366 context->signHashAlgo = TLS_HASH_ALGO_NONE; 00367 //Get the number of hash/signature algorithm pairs present in the list 00368 n = ntohs(supportedSignAlgos->length) / sizeof(TlsSignHashAlgo); 00369 00370 //The hash algorithm to be used when generating signatures must be 00371 //one of those present in the list 00372 for(i = 0; i < n; i++) 00373 { 00374 //Acceptable signature algorithm found? 00375 if(supportedSignAlgos->value[i].signature == signAlgo) 00376 { 00377 //TLS operates as a client? 00378 if(context->entity == TLS_CONNECTION_END_CLIENT) 00379 { 00380 //Check whether the associated hash algorithm is supported 00381 if(supportedSignAlgos->value[i].hash == TLS_HASH_ALGO_SHA1) 00382 context->signHashAlgo = (TlsHashAlgo) supportedSignAlgos->value[i].hash; 00383 else if(tlsGetHashAlgo(supportedSignAlgos->value[i].hash) == context->prfHashAlgo) 00384 context->signHashAlgo = (TlsHashAlgo) supportedSignAlgos->value[i].hash; 00385 } 00386 //TLS operates as a server? 00387 else 00388 { 00389 //Check whether the associated hash algorithm is supported 00390 switch(supportedSignAlgos->value[i].hash) 00391 { 00392 //MD5 hash identifier? 00393 case TLS_HASH_ALGO_MD5: 00394 //SHA-1 hash identifier? 00395 case TLS_HASH_ALGO_SHA1: 00396 //SHA-256 hash identifier? 00397 case TLS_HASH_ALGO_SHA256: 00398 #if (TLS_SHA224_SUPPORT == ENABLED) 00399 //SHA-224 hash identifier? 00400 case TLS_HASH_ALGO_SHA224: 00401 #endif 00402 #if (TLS_SHA384_SUPPORT == ENABLED) 00403 //SHA-384 hash identifier? 00404 case TLS_HASH_ALGO_SHA384: 00405 #endif 00406 #if (TLS_SHA512_SUPPORT == ENABLED) 00407 //SHA-512 hash identifier? 00408 case TLS_HASH_ALGO_SHA512: 00409 #endif 00410 //Select the hash algorithm to be used for signing 00411 context->signHashAlgo = (TlsHashAlgo) supportedSignAlgos->value[i].hash; 00412 break; 00413 default: 00414 break; 00415 } 00416 } 00417 00418 //Acceptable hash algorithm found? 00419 if(context->signHashAlgo != TLS_HASH_ALGO_NONE) 00420 break; 00421 } 00422 } 00423 } 00424 else 00425 { 00426 //Use default hash algorithm when generating RSA, DSA or ECDSA signatures 00427 context->signHashAlgo = TLS_HASH_ALGO_SHA1; 00428 } 00429 00430 //If no acceptable choices are presented, return an error 00431 if(context->signHashAlgo == TLS_HASH_ALGO_NONE) 00432 return ERROR_FAILURE; 00433 00434 //Successful processing 00435 return NO_ERROR; 00436 } 00437 00438 00439 /** 00440 * @brief Select the named curve to be used when performing ECDH key exchange 00441 * @param[in] context Pointer to the TLS context 00442 * @param[in] curveList Set of elliptic curves supported by the peer 00443 * @return Error code 00444 **/ 00445 00446 error_t tlsSelectNamedCurve(TlsContext *context, 00447 const TlsEllipticCurveList *curveList) 00448 { 00449 uint_t i; 00450 uint_t n; 00451 00452 //Check whether a list of elliptic curves has been provided 00453 if(curveList != NULL) 00454 { 00455 //Process the list and select the relevant elliptic curve... 00456 context->namedCurve = TLS_EC_CURVE_NONE; 00457 //Get the number of named curves present in the list 00458 n = ntohs(curveList->length) / sizeof(uint16_t); 00459 00460 //The named curve to be used when performing ECDH key exchange must be 00461 //one of those present in the list 00462 for(i = 0; i < n; i++) 00463 { 00464 //Acceptable elliptic curve found? 00465 if(tlsGetCurveInfo(ntohs(curveList->value[i])) != NULL) 00466 { 00467 //Save the named curve 00468 context->namedCurve = ntohs(curveList->value[i]); 00469 //We are done 00470 break; 00471 } 00472 } 00473 } 00474 else 00475 { 00476 //No list provided 00477 context->namedCurve = TLS_EC_CURVE_NONE; 00478 } 00479 00480 //If no acceptable choices are presented, return an error 00481 if(context->namedCurve == TLS_EC_CURVE_NONE) 00482 return ERROR_FAILURE; 00483 00484 //Successful processing 00485 return NO_ERROR; 00486 } 00487 00488 00489 /** 00490 * @brief Initialize handshake message hashing 00491 * @param[in] context Pointer to the TLS context 00492 * @return Error code 00493 **/ 00494 00495 error_t tlsInitHandshakeHash(TlsContext *context) 00496 { 00497 //Allocate SHA-1 context 00498 context->handshakeSha1Context = tlsAllocMem(sizeof(Sha1Context)); 00499 //Failed to allocate memory? 00500 if(context->handshakeSha1Context == NULL) 00501 return ERROR_OUT_OF_MEMORY; 00502 00503 //Initialize SHA-1 context 00504 sha1Init(context->handshakeSha1Context); 00505 00506 //SSL 3.0, TLS 1.0 or 1.1 currently selected? 00507 if(context->version <= TLS_VERSION_1_1) 00508 { 00509 //Allocate MD5 context 00510 context->handshakeMd5Context = tlsAllocMem(sizeof(Md5Context)); 00511 00512 //Failed to allocate memory? 00513 if(context->handshakeMd5Context == NULL) 00514 { 00515 //Clean up side effects 00516 tlsFreeMem(context->handshakeSha1Context); 00517 //Report an error 00518 return ERROR_OUT_OF_MEMORY; 00519 } 00520 00521 //Initialize MD5 context 00522 md5Init(context->handshakeMd5Context); 00523 } 00524 //TLS 1.2 currently selected? 00525 else 00526 { 00527 //Allocate a memory buffer to hold the hash algorithm context 00528 context->handshakeHashContext = tlsAllocMem(context->prfHashAlgo->contextSize); 00529 00530 //Failed to allocate memory? 00531 if(context->handshakeHashContext == NULL) 00532 { 00533 //Clean up side effects 00534 tlsFreeMem(context->handshakeSha1Context); 00535 //Report an error 00536 return ERROR_OUT_OF_MEMORY; 00537 } 00538 00539 //Initialize the hash algorithm context 00540 context->prfHashAlgo->init(context->handshakeHashContext); 00541 } 00542 00543 #if (TLS_CLIENT_SUPPORT == ENABLED) 00544 //TLS operates as a client? 00545 if(context->entity == TLS_CONNECTION_END_CLIENT) 00546 { 00547 size_t length; 00548 TlsHandshake *message; 00549 00550 //Point to the ClientHello message 00551 message = (TlsHandshake *) (context->txBuffer + sizeof(TlsRecord)); 00552 //Retrieve the length of the message 00553 length = LOAD24BE(message->length); 00554 00555 //Sanity check 00556 if(length <= context->txRecordMaxLen) 00557 { 00558 //Update the hash value with ClientHello message contents 00559 tlsUpdateHandshakeHash(context, message, length + sizeof(TlsHandshake)); 00560 } 00561 } 00562 #endif 00563 00564 //Successful initialization 00565 return NO_ERROR; 00566 } 00567 00568 00569 /** 00570 * @brief Update hash value with a handshake message 00571 * @param[in] context Pointer to the TLS context 00572 * @param[in] data Pointer to the handshake message being hashed 00573 * @param[in] length Length of the message 00574 **/ 00575 00576 void tlsUpdateHandshakeHash(TlsContext *context, const void *data, size_t length) 00577 { 00578 //Update SHA-1 hash value with message contents 00579 if(context->handshakeSha1Context) 00580 sha1Update(context->handshakeSha1Context, data, length); 00581 00582 //SSL 3.0, TLS 1.0 or 1.1 currently selected? 00583 if(context->version <= TLS_VERSION_1_1) 00584 { 00585 //Update MD5 hash value with message contents 00586 if(context->handshakeMd5Context) 00587 md5Update(context->handshakeMd5Context, data, length); 00588 } 00589 //TLS 1.2 currently selected? 00590 else 00591 { 00592 //Update hash value with message contents 00593 if(context->handshakeHashContext) 00594 context->prfHashAlgo->update(context->handshakeHashContext, data, length); 00595 } 00596 } 00597 00598 00599 /** 00600 * @brief Finalize hash calculation from previous handshake messages 00601 * @param[in] context Pointer to the TLS context 00602 * @param[in] hash Hash function used to digest the handshake messages 00603 * @param[in] hashContext Pointer to the hash context 00604 * @param[in] label NULL-terminated string 00605 * @param[out] output Buffer where to store the resulting hash value 00606 * @return Error code 00607 **/ 00608 00609 error_t tlsFinalizeHandshakeHash(TlsContext *context, const HashAlgo *hash, 00610 const void *hashContext, const char_t *label, uint8_t *output) 00611 { 00612 error_t error; 00613 HashContext *tempHashContext; 00614 00615 //Check parameters 00616 if(!context || !hash || !hashContext || !label || !output) 00617 return ERROR_INVALID_PARAMETER; 00618 00619 //Allocate a temporary hash context 00620 tempHashContext = tlsAllocMem(hash->contextSize); 00621 //Memory allocation failed? 00622 if(tempHashContext == NULL) 00623 return ERROR_OUT_OF_MEMORY; 00624 00625 //Original hash context must be preserved 00626 memcpy(tempHashContext, hashContext, hash->contextSize); 00627 00628 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= SSL_VERSION_3_0) 00629 //SSL 3.0 currently selected? 00630 if(context->version == SSL_VERSION_3_0) 00631 { 00632 size_t labelLength; 00633 size_t padLength; 00634 00635 //Compute the length of the label 00636 labelLength = strlen(label); 00637 00638 //The pad character is repeated 48 times for MD5 or 40 times for SHA-1 00639 padLength = (hash == MD5_HASH_ALGO) ? 48 : 40; 00640 00641 //hash(handshakeMessages + label + masterSecret + pad1) 00642 hash->update(tempHashContext, label, labelLength); 00643 hash->update(tempHashContext, context->masterSecret, 48); 00644 hash->update(tempHashContext, sslPad1, padLength); 00645 hash->final(tempHashContext, output); 00646 00647 //hash(masterSecret + pad2 + hash(handshakeMessages + label + masterSecret + pad1)) 00648 hash->init(tempHashContext); 00649 hash->update(tempHashContext, context->masterSecret, 48); 00650 hash->update(tempHashContext, sslPad2, padLength); 00651 hash->update(tempHashContext, output, hash->digestSize); 00652 hash->final(tempHashContext, output); 00653 00654 //Successful processing 00655 error = NO_ERROR; 00656 } 00657 else 00658 #endif 00659 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2) 00660 //TLS 1.0, TLS 1.1 or TLS 1.2 currently selected? 00661 if(context->version >= TLS_VERSION_1_0 && context->version <= TLS_VERSION_1_2) 00662 { 00663 //Compute hash(handshakeMessages) 00664 hash->final(tempHashContext, output); 00665 //Successful processing 00666 error = NO_ERROR; 00667 } 00668 else 00669 #endif 00670 //The negotiated TLS version is not valid... 00671 { 00672 //Report an error 00673 error = ERROR_INVALID_VERSION; 00674 } 00675 00676 //Release previously allocated resources 00677 tlsFreeMem(tempHashContext); 00678 //Return status code 00679 return error; 00680 } 00681 00682 00683 /** 00684 * @brief Compute verify data from previous handshake messages 00685 * @param[in] context Pointer to the TLS context 00686 * @param[in] entity Specifies whether the computation is performed at client or server side 00687 * @return Error code 00688 **/ 00689 00690 error_t tlsComputeVerifyData(TlsContext *context, TlsConnectionEnd entity) 00691 { 00692 error_t error; 00693 const char_t *label; 00694 00695 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= SSL_VERSION_3_0) 00696 //SSL 3.0 currently selected? 00697 if(context->version == SSL_VERSION_3_0) 00698 { 00699 //Computation is performed at client or server side? 00700 label = (entity == TLS_CONNECTION_END_CLIENT) ? "CLNT" : "SRVR"; 00701 00702 //Compute MD5(masterSecret + pad2 + MD5(handshakeMessages + label + masterSecret + pad1)) 00703 error = tlsFinalizeHandshakeHash(context, MD5_HASH_ALGO, 00704 context->handshakeMd5Context, label, context->verifyData); 00705 //Any error to report? 00706 if(error) 00707 return error; 00708 00709 //Compute SHA(masterSecret + pad2 + SHA(handshakeMessages + label + masterSecret + pad1)) 00710 error = tlsFinalizeHandshakeHash(context, SHA1_HASH_ALGO, 00711 context->handshakeSha1Context, label, context->verifyData + MD5_DIGEST_SIZE); 00712 //Any error to report? 00713 if(error) 00714 return error; 00715 } 00716 else 00717 #endif 00718 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1) 00719 //TLS 1.0 or 1.1 currently selected? 00720 if(context->version == TLS_VERSION_1_0 || context->version == TLS_VERSION_1_1) 00721 { 00722 //A temporary buffer is needed to concatenate MD5 00723 //and SHA-1 hash values before computing PRF 00724 uint8_t buffer[MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE]; 00725 00726 //Finalize MD5 hash computation 00727 error = tlsFinalizeHandshakeHash(context, MD5_HASH_ALGO, 00728 context->handshakeMd5Context, "", buffer); 00729 //Any error to report? 00730 if(error) 00731 return error; 00732 00733 //Finalize SHA-1 hash computation 00734 error = tlsFinalizeHandshakeHash(context, SHA1_HASH_ALGO, 00735 context->handshakeSha1Context, "", buffer + MD5_DIGEST_SIZE); 00736 //Any error to report? 00737 if(error) 00738 return error; 00739 00740 //Computation is performed at client or server side? 00741 label = (entity == TLS_CONNECTION_END_CLIENT) ? "client finished" : "server finished"; 00742 00743 //Verify data is always 12-byte long for TLS 1.0 and 1.1 00744 error = tlsPrf(context->masterSecret, 48, label, buffer, 00745 MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE, context->verifyData, 12); 00746 //Any error to report? 00747 if(error) 00748 return error; 00749 } 00750 else 00751 #endif 00752 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_2) 00753 //TLS 1.2 currently selected? 00754 if(context->version == TLS_VERSION_1_2) 00755 { 00756 //Allocate a memory buffer to hold the hash algorithm context 00757 HashContext *hashContext = tlsAllocMem(context->prfHashAlgo->contextSize); 00758 //Failed to allocate memory? 00759 if(hashContext == NULL) 00760 return ERROR_OUT_OF_MEMORY; 00761 00762 //The original hash context must be preserved 00763 memcpy(hashContext, context->handshakeHashContext, context->prfHashAlgo->contextSize); 00764 //Finalize hash computation 00765 context->prfHashAlgo->final(hashContext, NULL); 00766 00767 //Computation is performed at client or server side? 00768 label = (entity == TLS_CONNECTION_END_CLIENT) ? "client finished" : "server finished"; 00769 00770 //Generate the verify data 00771 error = tlsPrf2(context->prfHashAlgo, context->masterSecret, 48, label, hashContext->digest, 00772 context->prfHashAlgo->digestSize, context->verifyData, context->verifyDataLen); 00773 00774 //Release previously allocated memory 00775 tlsFreeMem(hashContext); 00776 00777 //Any error to report? 00778 if(error) 00779 return error; 00780 } 00781 else 00782 #endif 00783 //The negotiated TLS version is not valid... 00784 { 00785 //Report an error 00786 return ERROR_INVALID_VERSION; 00787 } 00788 00789 //Debug message 00790 TRACE_DEBUG("Verify data:\r\n"); 00791 TRACE_DEBUG_ARRAY(" ", context->verifyData, context->verifyDataLen); 00792 00793 //Successful processing 00794 return NO_ERROR; 00795 } 00796 00797 00798 /** 00799 * @brief Initialize encryption engine 00800 * @param[in] context Pointer to the TLS context 00801 * @return Error code 00802 **/ 00803 00804 error_t tlsInitEncryptionEngine(TlsContext *context) 00805 { 00806 error_t error; 00807 00808 //Check cipher mode of operation 00809 if(context->cipherMode == CIPHER_MODE_STREAM || 00810 context->cipherMode == CIPHER_MODE_CBC || 00811 context->cipherMode == CIPHER_MODE_CCM || 00812 context->cipherMode == CIPHER_MODE_GCM) 00813 { 00814 //Sanity check 00815 if(context->cipherAlgo != NULL) 00816 { 00817 //Allocate a memory buffer to hold the encryption context 00818 context->writeCipherContext = tlsAllocMem(context->cipherAlgo->contextSize); 00819 00820 //Successful memory allocation? 00821 if(context->writeCipherContext != NULL) 00822 { 00823 //Configure the encryption engine with the write key 00824 error = context->cipherAlgo->init(context->writeCipherContext, 00825 context->writeEncKey, context->encKeyLen); 00826 } 00827 else 00828 { 00829 //Failed to allocate memory 00830 error = ERROR_OUT_OF_MEMORY; 00831 } 00832 } 00833 else 00834 { 00835 //Report an error 00836 error = ERROR_FAILURE; 00837 } 00838 00839 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED) 00840 //GCM AEAD cipher? 00841 if(context->cipherMode == CIPHER_MODE_GCM) 00842 { 00843 //Check status code 00844 if(!error) 00845 { 00846 //Allocate a memory buffer to hold the GCM context 00847 context->writeGcmContext = tlsAllocMem(sizeof(GcmContext)); 00848 00849 //Successful memory allocation? 00850 if(context->writeGcmContext != NULL) 00851 { 00852 //Initialize GCM context 00853 error = gcmInit(context->writeGcmContext, 00854 context->cipherAlgo, context->writeCipherContext); 00855 } 00856 else 00857 { 00858 //Failed to allocate memory 00859 error = ERROR_OUT_OF_MEMORY; 00860 } 00861 } 00862 } 00863 #endif 00864 } 00865 else if(context->cipherMode == CIPHER_MODE_CHACHA20_POLY1305) 00866 { 00867 //We are done 00868 error = NO_ERROR; 00869 } 00870 else 00871 { 00872 //Unsupported mode of operation 00873 error = ERROR_FAILURE; 00874 } 00875 00876 //Return status code 00877 return error; 00878 } 00879 00880 00881 /** 00882 * @brief Initialize decryption engine 00883 * @param[in] context Pointer to the TLS context 00884 * @return Error code 00885 **/ 00886 00887 error_t tlsInitDecryptionEngine(TlsContext *context) 00888 { 00889 error_t error; 00890 00891 //Check cipher mode of operation 00892 if(context->cipherMode == CIPHER_MODE_STREAM || 00893 context->cipherMode == CIPHER_MODE_CBC || 00894 context->cipherMode == CIPHER_MODE_CCM || 00895 context->cipherMode == CIPHER_MODE_GCM) 00896 { 00897 //Sanity check 00898 if(context->cipherAlgo != NULL) 00899 { 00900 //Allocate a memory buffer to hold the decryption context 00901 context->readCipherContext = tlsAllocMem(context->cipherAlgo->contextSize); 00902 00903 //Successful memory allocation? 00904 if(context->readCipherContext != NULL) 00905 { 00906 //Configure the decryption engine with the read key 00907 error = context->cipherAlgo->init(context->readCipherContext, 00908 context->readEncKey, context->encKeyLen); 00909 } 00910 else 00911 { 00912 //Failed to allocate memory 00913 error = ERROR_OUT_OF_MEMORY; 00914 } 00915 } 00916 else 00917 { 00918 //Report an error 00919 error = ERROR_FAILURE; 00920 } 00921 00922 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED) 00923 //GCM AEAD cipher? 00924 if(context->cipherMode == CIPHER_MODE_GCM) 00925 { 00926 //Check status code 00927 if(!error) 00928 { 00929 //Allocate a memory buffer to hold the GCM context 00930 context->readGcmContext = tlsAllocMem(sizeof(GcmContext)); 00931 00932 //Successful memory allocation? 00933 if(context->readGcmContext != NULL) 00934 { 00935 //Initialize GCM context 00936 error = gcmInit(context->readGcmContext, 00937 context->cipherAlgo, context->readCipherContext); 00938 } 00939 else 00940 { 00941 //Failed to allocate memory 00942 error = ERROR_OUT_OF_MEMORY; 00943 } 00944 } 00945 } 00946 #endif 00947 } 00948 else if(context->cipherMode == CIPHER_MODE_CHACHA20_POLY1305) 00949 { 00950 //We are done 00951 error = NO_ERROR; 00952 } 00953 else 00954 { 00955 //Unsupported mode of operation 00956 error = ERROR_FAILURE; 00957 } 00958 00959 //Return status code 00960 return error; 00961 } 00962 00963 00964 /** 00965 * @brief Encode a multiple precision integer to an opaque vector 00966 * @param[in] a Pointer to a multiple precision integer 00967 * @param[out] data Buffer where to store the opaque vector 00968 * @param[out] length Total number of bytes that have been written 00969 * @return Error code 00970 **/ 00971 00972 error_t tlsWriteMpi(const Mpi *a, uint8_t *data, size_t *length) 00973 { 00974 error_t error; 00975 size_t n; 00976 00977 //Retrieve the actual size of the integer 00978 n = mpiGetByteLength(a); 00979 00980 //The data is preceded by a 2-byte length field 00981 STORE16BE(n, data); 00982 00983 //Convert the integer to an octet string 00984 error = mpiWriteRaw(a, data + 2, n); 00985 //Conversion failed? 00986 if(error) 00987 return error; 00988 00989 //Return the total number of bytes that have been written 00990 *length = n + 2; 00991 //Successful processing 00992 return NO_ERROR; 00993 } 00994 00995 00996 /** 00997 * @brief Read a multiple precision integer from an opaque vector 00998 * @param[out] a Resulting multiple precision integer 00999 * @param[in] data Buffer where to read the opaque vector 01000 * @param[in] size Total number of bytes available in the buffer 01001 * @param[out] length Total number of bytes that have been read 01002 * @return Error code 01003 **/ 01004 01005 error_t tlsReadMpi(Mpi *a, const uint8_t *data, size_t size, size_t *length) 01006 { 01007 error_t error; 01008 size_t n; 01009 01010 //Buffer underrun? 01011 if(size < 2) 01012 return ERROR_DECODING_FAILED; 01013 01014 //Decode the length field 01015 n = LOAD16BE(data); 01016 01017 //Buffer underrun? 01018 if(size < (n + 2)) 01019 return ERROR_DECODING_FAILED; 01020 01021 //Convert the octet string to a multiple precision integer 01022 error = mpiReadRaw(a, data + 2, n); 01023 //Any error to report? 01024 if(error) 01025 return error; 01026 01027 //Return the total number of bytes that have been read 01028 *length = n + 2; 01029 //Successful processing 01030 return NO_ERROR; 01031 } 01032 01033 01034 /** 01035 * @brief Encode an EC point to an opaque vector 01036 * @param[in] params EC domain parameters 01037 * @param[in] a Pointer to an EC point 01038 * @param[out] data Buffer where to store the opaque vector 01039 * @param[out] length Total number of bytes that have been written 01040 * @return Error code 01041 **/ 01042 01043 error_t tlsWriteEcPoint(const EcDomainParameters *params, 01044 const EcPoint *a, uint8_t *data, size_t *length) 01045 { 01046 #if (TLS_ECDH_ANON_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED || \ 01047 TLS_ECDHE_ECDSA_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED) 01048 error_t error; 01049 01050 //Convert the EC point to an octet string 01051 error = ecExport(params, a, data + 1, length); 01052 //Any error to report? 01053 if(error) 01054 return error; 01055 01056 //Set the length of the opaque vector 01057 data[0] = (uint8_t) (*length); 01058 01059 //Return the total number of bytes that have been written 01060 *length += 1; 01061 //Successful processing 01062 return NO_ERROR; 01063 #else 01064 //Not implemented 01065 return ERROR_NOT_IMPLEMENTED; 01066 #endif 01067 } 01068 01069 01070 /** 01071 * @brief Read an EC point from an opaque vector 01072 * @param[in] params EC domain parameters 01073 * @param[out] a Resulting EC point 01074 * @param[in] data Buffer where to read the opaque vector 01075 * @param[in] size Total number of bytes available in the buffer 01076 * @param[out] length Total number of bytes that have been read 01077 * @return Error code 01078 **/ 01079 01080 error_t tlsReadEcPoint(const EcDomainParameters *params, 01081 EcPoint *a, const uint8_t *data, size_t size, size_t *length) 01082 { 01083 #if (TLS_ECDH_ANON_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED || \ 01084 TLS_ECDHE_ECDSA_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED) 01085 error_t error; 01086 size_t n; 01087 01088 //Buffer underrun? 01089 if(size < 1) 01090 return ERROR_DECODING_FAILED; 01091 01092 //The EC point representation is preceded by a length field 01093 n = data[0]; 01094 01095 //Valid EC point representation? 01096 if(size < (n + 1)) 01097 return ERROR_DECODING_FAILED; 01098 01099 //Convert the octet string to an EC point 01100 error = ecImport(params, a, data + 1, n); 01101 //Any error to report? 01102 if(error) 01103 return error; 01104 01105 //Return the total number of bytes that have been read 01106 *length = n + 1; 01107 //Successful processing 01108 return NO_ERROR; 01109 #else 01110 //Not implemented 01111 return ERROR_NOT_IMPLEMENTED; 01112 #endif 01113 } 01114 01115 01116 /** 01117 * @brief Generate RSA signature (SSL 3.0, TLS 1.0 and TLS 1.1) 01118 * @param[in] key Signer's RSA private key 01119 * @param[in] digest Digest of the message to be signed 01120 * @param[out] signature Resulting signature 01121 * @param[out] signatureLength Length of the resulting signature 01122 * @return Error code 01123 **/ 01124 01125 error_t tlsGenerateRsaSignature(const RsaPrivateKey *key, 01126 const uint8_t *digest, uint8_t *signature, size_t *signatureLength) 01127 { 01128 #if (TLS_RSA_SIGN_SUPPORT == ENABLED || TLS_DHE_RSA_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED) 01129 error_t error; 01130 size_t k; 01131 size_t paddingLength; 01132 uint8_t *em; 01133 Mpi m; 01134 Mpi s; 01135 01136 //Debug message 01137 TRACE_DEBUG("RSA signature generation...\r\n"); 01138 TRACE_DEBUG(" Modulus:\r\n"); 01139 TRACE_DEBUG_MPI(" ", &key->n); 01140 TRACE_DEBUG(" Public exponent:\r\n"); 01141 TRACE_DEBUG_MPI(" ", &key->e); 01142 TRACE_DEBUG(" Private exponent:\r\n"); 01143 TRACE_DEBUG_MPI(" ", &key->d); 01144 TRACE_DEBUG(" Prime 1:\r\n"); 01145 TRACE_DEBUG_MPI(" ", &key->p); 01146 TRACE_DEBUG(" Prime 2:\r\n"); 01147 TRACE_DEBUG_MPI(" ", &key->q); 01148 TRACE_DEBUG(" Prime exponent 1:\r\n"); 01149 TRACE_DEBUG_MPI(" ", &key->dp); 01150 TRACE_DEBUG(" Prime exponent 2:\r\n"); 01151 TRACE_DEBUG_MPI(" ", &key->dq); 01152 TRACE_DEBUG(" Coefficient:\r\n"); 01153 TRACE_DEBUG_MPI(" ", &key->qinv); 01154 TRACE_DEBUG(" Message digest:\r\n"); 01155 TRACE_DEBUG_ARRAY(" ", digest, MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE); 01156 01157 //Initialize multiple-precision integers 01158 mpiInit(&m); 01159 mpiInit(&s); 01160 01161 //Get the length in octets of the modulus n 01162 k = mpiGetByteLength(&key->n); 01163 01164 //Check the length of the modulus 01165 if(k < (MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE + 11)) 01166 return ERROR_INVALID_KEY; 01167 01168 //Point to the buffer where the encoded message EM will be generated 01169 em = signature; 01170 01171 //The leading 0x00 octet ensures that the encoded message, 01172 //converted to an integer, is less than the modulus 01173 em[0] = 0x00; 01174 //Block type 0x01 is used for private-key operations 01175 em[1] = 0x01; 01176 01177 //Compute the length of the padding string PS 01178 paddingLength = k - (MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE + 3); 01179 //Fill the padding string with 0xFF 01180 memset(em + 2, 0xFF, paddingLength); 01181 //Append a 0x00 octet to PS 01182 em[paddingLength + 2] = 0x00; 01183 01184 //Append the digest value 01185 memcpy(em + paddingLength + 3, digest, MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE); 01186 01187 //Debug message 01188 TRACE_DEBUG(" Encoded message\r\n"); 01189 TRACE_DEBUG_ARRAY(" ", em, k); 01190 01191 //Start of exception handling block 01192 do 01193 { 01194 //Convert the encoded message EM to an integer message representative m 01195 error = mpiReadRaw(&m, em, k); 01196 //Conversion failed? 01197 if(error) 01198 break; 01199 01200 //Apply the RSASP1 signature primitive 01201 error = rsasp1(key, &m, &s); 01202 //Any error to report? 01203 if(error) 01204 break; 01205 01206 //Convert the signature representative s to a signature of length k octets 01207 error = mpiWriteRaw(&s, signature, k); 01208 //Conversion failed? 01209 if(error) 01210 break; 01211 01212 //Length of the resulting signature 01213 *signatureLength = k; 01214 01215 //Debug message 01216 TRACE_DEBUG(" Signature:\r\n"); 01217 TRACE_DEBUG_ARRAY(" ", signature, *signatureLength); 01218 01219 //End of exception handling block 01220 } while(0); 01221 01222 //Free previously allocated memory 01223 mpiFree(&m); 01224 mpiFree(&s); 01225 01226 //Return status code 01227 return error; 01228 #else 01229 //Not implemented 01230 return ERROR_NOT_IMPLEMENTED; 01231 #endif 01232 } 01233 01234 01235 /** 01236 * @brief Verify RSA signature (SSL 3.0, TLS 1.0 and TLS 1.1) 01237 * @param[in] key Signer's RSA public key 01238 * @param[in] digest Digest of the message whose signature is to be verified 01239 * @param[in] signature Signature to be verified 01240 * @param[in] signatureLength Length of the signature to be verified 01241 * @return Error code 01242 **/ 01243 01244 error_t tlsVerifyRsaSignature(const RsaPublicKey *key, 01245 const uint8_t *digest, const uint8_t *signature, size_t signatureLength) 01246 { 01247 #if (TLS_RSA_SIGN_SUPPORT == ENABLED || TLS_DHE_RSA_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED) 01248 error_t error; 01249 uint_t i; 01250 uint_t k; 01251 uint8_t *em; 01252 Mpi s; 01253 Mpi m; 01254 01255 //Debug message 01256 TRACE_DEBUG("RSA signature verification...\r\n"); 01257 TRACE_DEBUG(" Modulus:\r\n"); 01258 TRACE_DEBUG_MPI(" ", &key->n); 01259 TRACE_DEBUG(" Public exponent:\r\n"); 01260 TRACE_DEBUG_MPI(" ", &key->e); 01261 TRACE_DEBUG(" Message digest:\r\n"); 01262 TRACE_DEBUG_ARRAY(" ", digest, MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE); 01263 TRACE_DEBUG(" Signature:\r\n"); 01264 TRACE_DEBUG_ARRAY(" ", signature, signatureLength); 01265 01266 //Get the length in octets of the modulus n 01267 k = mpiGetByteLength(&key->n); 01268 01269 //Check the length of the signature 01270 if(signatureLength != k) 01271 return ERROR_INVALID_SIGNATURE; 01272 01273 //Initialize multiple-precision integers 01274 mpiInit(&s); 01275 mpiInit(&m); 01276 01277 //Allocate a memory buffer to hold the encoded message 01278 em = tlsAllocMem(k); 01279 //Failed to allocate memory? 01280 if(em == NULL) 01281 return ERROR_OUT_OF_MEMORY; 01282 01283 //Start of exception handling block 01284 do 01285 { 01286 //Convert the signature to an integer signature representative s 01287 error = mpiReadRaw(&s, signature, signatureLength); 01288 //Conversion failed? 01289 if(error) 01290 break; 01291 01292 //Apply the RSAVP1 verification primitive 01293 error = rsavp1(key, &s, &m); 01294 //Any error to report? 01295 if(error) 01296 break; 01297 01298 //Convert the message representative m to an encoded message EM of length k octets 01299 error = mpiWriteRaw(&m, em, k); 01300 //Conversion failed? 01301 if(error) 01302 break; 01303 01304 //Debug message 01305 TRACE_DEBUG(" Encoded message\r\n"); 01306 TRACE_DEBUG_ARRAY(" ", em, k); 01307 01308 //Assume an error... 01309 error = ERROR_INVALID_SIGNATURE; 01310 01311 //The first octet of EM must have a value of 0x00 01312 if(em[0] != 0x00) 01313 break; 01314 //The block type BT shall be 0x01 01315 if(em[1] != 0x01) 01316 break; 01317 01318 //Check the padding string PS 01319 for(i = 2; i < k; i++) 01320 { 01321 //A 0x00 octet indicates the end of the padding string 01322 if(em[i] == 0x00) 01323 break; 01324 01325 //Each byte of PS must be set to 0xFF when the block type is 0x01 01326 if(em[i] != 0xFF) 01327 break; 01328 } 01329 01330 //Check whether the padding string is properly terminated 01331 if(i >= k || em[i] != 0x00) 01332 break; 01333 01334 //The length of PS cannot be less than 8 octets 01335 if(i < 10) 01336 break; 01337 01338 //Check the length of the digest 01339 if((k - i - 1) != (MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE)) 01340 break; 01341 //Check the digest value 01342 if(memcmp(digest, em + i + 1, MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE)) 01343 break; 01344 01345 //The RSA signature is valid 01346 error = NO_ERROR; 01347 01348 //End of exception handling block 01349 } while(0); 01350 01351 //Release multiple precision integers 01352 mpiFree(&s); 01353 mpiFree(&m); 01354 //Release previously allocated memory 01355 tlsFreeMem(em); 01356 01357 //Return status code 01358 return error; 01359 #else 01360 //Not implemented 01361 return ERROR_NOT_IMPLEMENTED; 01362 #endif 01363 } 01364 01365 01366 /** 01367 * @brief Generate DSA signature 01368 * @param[in] prngAlgo PRNG algorithm 01369 * @param[in] prngContext Pointer to the PRNG context 01370 * @param[in] key Signer's DSA private key 01371 * @param[in] digest Digest of the message to be signed 01372 * @param[in] digestLength Length in octets of the digest 01373 * @param[out] signature Resulting signature 01374 * @param[out] signatureLength Length of the resulting signature 01375 * @return Error code 01376 **/ 01377 01378 error_t tlsGenerateDsaSignature(const PrngAlgo *prngAlgo, void *prngContext, const DsaPrivateKey *key, 01379 const uint8_t *digest, size_t digestLength, uint8_t *signature, size_t *signatureLength) 01380 { 01381 #if (TLS_DSA_SIGN_SUPPORT == ENABLED || TLS_DHE_DSS_SUPPORT == ENABLED) 01382 error_t error; 01383 DsaSignature dsaSignature; 01384 01385 //Initialize DSA signature 01386 dsaInitSignature(&dsaSignature); 01387 01388 //Generate DSA signature 01389 error = dsaGenerateSignature(prngAlgo, prngContext, 01390 key, digest, digestLength, &dsaSignature); 01391 //Failed to generate signature? 01392 if(error) 01393 return error; 01394 01395 //Encode the resulting (R, S) integer pair using ASN.1 01396 error = dsaWriteSignature(&dsaSignature, signature, signatureLength); 01397 01398 //Free previously allocated resources 01399 dsaFreeSignature(&dsaSignature); 01400 01401 //Return status code 01402 return error; 01403 #else 01404 //Not implemented 01405 return ERROR_NOT_IMPLEMENTED; 01406 #endif 01407 } 01408 01409 01410 /** 01411 * @brief Verify DSA signature 01412 * @param[in] key Signer's DSA public key 01413 * @param[in] digest Digest of the message whose signature is to be verified 01414 * @param[in] digestLength Length in octets of the digest 01415 * @param[in] signature Signature to be verified 01416 * @param[in] signatureLength Length of the signature to be verified 01417 * @return Error code 01418 **/ 01419 01420 error_t tlsVerifyDsaSignature(const DsaPublicKey *key, const uint8_t *digest, 01421 size_t digestLength, const uint8_t *signature, size_t signatureLength) 01422 { 01423 #if (TLS_DSA_SIGN_SUPPORT == ENABLED || TLS_DHE_DSS_SUPPORT == ENABLED) 01424 error_t error; 01425 DsaSignature dsaSignature; 01426 01427 //Initialize DSA signature 01428 dsaInitSignature(&dsaSignature); 01429 01430 //Read the ASN.1 encoded DSA signature 01431 error = dsaReadSignature(signature, signatureLength, &dsaSignature); 01432 //Failed to decode ASN.1 structure? 01433 if(error) 01434 return error; 01435 01436 //DSA signature verification 01437 error = dsaVerifySignature(key, digest, digestLength, &dsaSignature); 01438 01439 //Free previously allocated resources 01440 dsaFreeSignature(&dsaSignature); 01441 01442 //Return status code 01443 return error; 01444 #else 01445 //Not implemented 01446 return ERROR_NOT_IMPLEMENTED; 01447 #endif 01448 } 01449 01450 01451 /** 01452 * @brief Generate ECDSA signature 01453 * @param[in] params EC domain parameters 01454 * @param[in] prngAlgo PRNG algorithm 01455 * @param[in] prngContext Pointer to the PRNG context 01456 * @param[in] key Signer's ECDSA private key 01457 * @param[in] digest Digest of the message to be signed 01458 * @param[in] digestLength Length in octets of the digest 01459 * @param[out] signature Resulting signature 01460 * @param[out] signatureLength Length of the resulting signature 01461 * @return Error code 01462 **/ 01463 01464 error_t tlsGenerateEcdsaSignature(const EcDomainParameters *params, 01465 const PrngAlgo *prngAlgo, void *prngContext, const Mpi *key, const uint8_t *digest, 01466 size_t digestLength, uint8_t *signature, size_t *signatureLength) 01467 { 01468 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_ECDHE_ECDSA_SUPPORT == ENABLED) 01469 error_t error; 01470 EcdsaSignature ecdsaSignature; 01471 01472 //Initialize ECDSA signature 01473 ecdsaInitSignature(&ecdsaSignature); 01474 01475 //Generate ECDSA signature 01476 error = ecdsaGenerateSignature(params, prngAlgo, 01477 prngContext, key, digest, digestLength, &ecdsaSignature); 01478 //Failed to generate signature? 01479 if(error) 01480 return error; 01481 01482 //Encode the resulting (R, S) integer pair using ASN.1 01483 error = ecdsaWriteSignature(&ecdsaSignature, signature, signatureLength); 01484 01485 //Free previously allocated resources 01486 ecdsaFreeSignature(&ecdsaSignature); 01487 01488 //Return status code 01489 return error; 01490 #else 01491 //Not implemented 01492 return ERROR_NOT_IMPLEMENTED; 01493 #endif 01494 } 01495 01496 01497 /** 01498 * @brief Verify ECDSA signature 01499 * @param[in] params EC domain parameters 01500 * @param[in] key Signer's ECDSA public key 01501 * @param[in] digest Digest of the message whose signature is to be verified 01502 * @param[in] digestLength Length in octets of the digest 01503 * @param[in] signature Signature to be verified 01504 * @param[in] signatureLength Length of the signature to be verified 01505 * @return Error code 01506 **/ 01507 01508 error_t tlsVerifyEcdsaSignature(const EcDomainParameters *params, 01509 const EcPoint *key, const uint8_t *digest, size_t digestLength, 01510 const uint8_t *signature, size_t signatureLength) 01511 { 01512 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_ECDHE_ECDSA_SUPPORT == ENABLED) 01513 error_t error; 01514 EcdsaSignature ecdsaSignature; 01515 01516 //Initialize ECDSA signature 01517 ecdsaInitSignature(&ecdsaSignature); 01518 01519 //Read the ASN.1 encoded ECDSA signature 01520 error = ecdsaReadSignature(signature, signatureLength, &ecdsaSignature); 01521 //Failed to decode ASN.1 structure? 01522 if(error) 01523 return error; 01524 01525 //ECDSA signature verification 01526 error = ecdsaVerifySignature(params, key, 01527 digest, digestLength, &ecdsaSignature); 01528 01529 //Free previously allocated resources 01530 ecdsaFreeSignature(&ecdsaSignature); 01531 01532 //Return status code 01533 return error; 01534 #else 01535 //Not implemented 01536 return ERROR_NOT_IMPLEMENTED; 01537 #endif 01538 } 01539 01540 01541 /** 01542 * @brief Premaster secret generation (for PSK cipher suites) 01543 * @param[in] context Pointer to the TLS context 01544 * @return Error code 01545 **/ 01546 01547 error_t tlsGeneratePskPremasterSecret(TlsContext *context) 01548 { 01549 error_t error; 01550 01551 #if (TLS_PSK_SUPPORT == ENABLED) 01552 //PSK key exchange method? 01553 if(context->keyExchMethod == TLS_KEY_EXCH_PSK) 01554 { 01555 size_t n; 01556 01557 //Let N be the length of pre-shared key 01558 n = context->pskLen; 01559 01560 //Check whether the output buffer is large enough to hold the premaster secret 01561 if((n * 2 + 4) <= TLS_MAX_PREMASTER_SECRET_SIZE) 01562 { 01563 //The premaster secret is formed as follows: if the PSK is N octets 01564 //long, concatenate a uint16 with the value N, N zero octets, a second 01565 //uint16 with the value N, and the PSK itself 01566 STORE16BE(n, context->premasterSecret); 01567 memset(context->premasterSecret + 2, 0, n); 01568 STORE16BE(n, context->premasterSecret + n + 2); 01569 memcpy(context->premasterSecret + n + 4, context->psk, n); 01570 01571 //Save the length of the premaster secret 01572 context->premasterSecretLen = n * 2 + 4; 01573 01574 //Premaster secret successfully generated 01575 error = NO_ERROR; 01576 } 01577 else 01578 { 01579 //Report an error 01580 error = ERROR_BUFFER_OVERFLOW; 01581 } 01582 } 01583 else 01584 #endif 01585 #if (TLS_RSA_PSK_SUPPORT == ENABLED || TLS_DHE_PSK_SUPPORT == ENABLED || \ 01586 TLS_ECDHE_PSK_SUPPORT == ENABLED) 01587 //RSA_PSK, DHE_PSK or ECDHE_PSK key exchange method? 01588 if(context->keyExchMethod == TLS_KEY_EXCH_RSA_PSK || 01589 context->keyExchMethod == TLS_KEY_EXCH_DHE_PSK || 01590 context->keyExchMethod == TLS_KEY_EXCH_ECDHE_PSK) 01591 { 01592 size_t n; 01593 01594 //Let N be the length of pre-shared key 01595 n = context->pskLen; 01596 01597 //Check whether the output buffer is large enough to hold the premaster secret 01598 if((context->premasterSecretLen + n + 4) <= TLS_MAX_PREMASTER_SECRET_SIZE) 01599 { 01600 //The "other_secret" field comes from the Diffie-Hellman, ECDH or 01601 //RSA exchange (DHE_PSK, ECDH_PSK and RSA_PSK, respectively) 01602 memmove(context->premasterSecret + 2, context->premasterSecret, 01603 context->premasterSecretLen); 01604 01605 //The "other_secret" field is preceded by a 2-byte length field 01606 STORE16BE(context->premasterSecretLen, context->premasterSecret); 01607 01608 //if the PSK is N octets long, concatenate a uint16 with the value N 01609 STORE16BE(n, context->premasterSecret + context->premasterSecretLen + 2); 01610 01611 //Concatenate the PSK itself 01612 memcpy(context->premasterSecret + context->premasterSecretLen + 4, 01613 context->psk, n); 01614 01615 //Adjust the length of the premaster secret 01616 context->premasterSecretLen += n + 4; 01617 01618 //Premaster secret successfully generated 01619 error = NO_ERROR; 01620 } 01621 else 01622 { 01623 //Report an error 01624 error = ERROR_BUFFER_OVERFLOW; 01625 } 01626 } 01627 else 01628 #endif 01629 //Invalid key exchange method? 01630 { 01631 //The specified key exchange method is not supported 01632 error = ERROR_UNSUPPORTED_KEY_EXCH_METHOD; 01633 } 01634 01635 //Return status code 01636 return error; 01637 } 01638 01639 01640 /** 01641 * @brief Key generation 01642 * @param[in] context Pointer to the TLS context 01643 * @return Error code 01644 **/ 01645 01646 error_t tlsGenerateKeys(TlsContext *context) 01647 { 01648 error_t error; 01649 size_t i; 01650 size_t n; 01651 uint8_t temp; 01652 01653 //Length of necessary key material 01654 n = 2 * (context->macKeyLen + context->encKeyLen + context->fixedIvLen); 01655 01656 //Make sure that the key block is large enough 01657 if(n > sizeof(context->keyBlock)) 01658 return ERROR_FAILURE; 01659 01660 //Debug message 01661 TRACE_DEBUG("Generating keys...\r\n"); 01662 TRACE_DEBUG(" Client random bytes:\r\n"); 01663 TRACE_DEBUG_ARRAY(" ", &context->clientRandom, 32); 01664 TRACE_DEBUG(" Server random bytes:\r\n"); 01665 TRACE_DEBUG_ARRAY(" ", &context->serverRandom, 32); 01666 01667 //If a full handshake is being performed, the premaster secret 01668 //shall be first converted to the master secret 01669 if(!context->resume) 01670 { 01671 //Debug message 01672 TRACE_DEBUG(" Premaster secret:\r\n"); 01673 TRACE_DEBUG_ARRAY(" ", context->premasterSecret, context->premasterSecretLen); 01674 01675 //Convert the premaster secret to the master secret 01676 if(context->version == SSL_VERSION_3_0) 01677 { 01678 //SSL 3.0 does not use a PRF, instead makes use abundantly of MD5 01679 error = sslExpandKey(context->premasterSecret, context->premasterSecretLen, 01680 context->random, 64, context->masterSecret, 48); 01681 } 01682 else if(context->version <= TLS_VERSION_1_1) 01683 { 01684 //TLS 1.0 and 1.1 use a PRF that combines MD5 and SHA-1 01685 error = tlsPrf(context->premasterSecret, context->premasterSecretLen, 01686 "master secret", context->random, 64, context->masterSecret, 48); 01687 } 01688 else 01689 { 01690 //TLS 1.2 PRF uses SHA-256 or a stronger hash algorithm 01691 //as the core function in its construction 01692 error = tlsPrf2(context->prfHashAlgo, context->premasterSecret, 01693 context->premasterSecretLen, "master secret", 01694 context->random, 64, context->masterSecret, 48); 01695 } 01696 01697 //Check the return status 01698 if(error) 01699 return error; 01700 01701 //The premaster secret should be deleted from memory 01702 //once the master secret has been computed 01703 memset(context->premasterSecret, 0, 48); 01704 } 01705 01706 //Debug message 01707 TRACE_DEBUG(" Master secret:\r\n"); 01708 TRACE_DEBUG_ARRAY(" ", context->masterSecret, 48); 01709 01710 //Exchange client and server random bytes 01711 for(i = 0; i < 32; i++) 01712 { 01713 //Swap each byte 01714 temp = context->random[i]; 01715 context->random[i] = context->random[i + 32]; 01716 context->random[i + 32] = temp; 01717 } 01718 01719 //Perform key expansion 01720 if(context->version == SSL_VERSION_3_0) 01721 { 01722 //SSL 3.0 does not use a PRF, instead makes use abundantly of MD5 01723 error = sslExpandKey(context->masterSecret, 48, 01724 context->random, 64, context->keyBlock, n); 01725 } 01726 else if(context->version <= TLS_VERSION_1_1) 01727 { 01728 //TLS 1.0 and 1.1 use a PRF that combines MD5 and SHA-1 01729 error = tlsPrf(context->masterSecret, 48, "key expansion", 01730 context->random, 64, context->keyBlock, n); 01731 } 01732 else 01733 { 01734 //TLS 1.2 PRF uses SHA-256 or a stronger hash algorithm 01735 //as the core function in its construction 01736 error = tlsPrf2(context->prfHashAlgo, context->masterSecret, 48, 01737 "key expansion", context->random, 64, context->keyBlock, n); 01738 } 01739 01740 //Exchange client and server random bytes 01741 for(i = 0; i < 32; i++) 01742 { 01743 //Swap each byte 01744 temp = context->random[i]; 01745 context->random[i] = context->random[i + 32]; 01746 context->random[i + 32] = temp; 01747 } 01748 01749 //Any error while performing key expansion? 01750 if(error) 01751 return error; 01752 01753 //Debug message 01754 TRACE_DEBUG(" Key block:\r\n"); 01755 TRACE_DEBUG_ARRAY(" ", context->keyBlock, n); 01756 01757 //TLS operates as a client? 01758 if(context->entity == TLS_CONNECTION_END_CLIENT) 01759 { 01760 //MAC keys 01761 context->writeMacKey = context->keyBlock; 01762 context->readMacKey = context->writeMacKey + context->macKeyLen; 01763 //Encryption keys 01764 context->writeEncKey = context->readMacKey + context->macKeyLen; 01765 context->readEncKey = context->writeEncKey + context->encKeyLen; 01766 //Initialization vectors 01767 context->writeIv = context->readEncKey + context->encKeyLen; 01768 context->readIv = context->writeIv + context->fixedIvLen; 01769 } 01770 //TLS operates as a server? 01771 else 01772 { 01773 //MAC keys 01774 context->readMacKey = context->keyBlock; 01775 context->writeMacKey = context->readMacKey + context->macKeyLen; 01776 //Encryption keys 01777 context->readEncKey = context->writeMacKey + context->macKeyLen; 01778 context->writeEncKey = context->readEncKey + context->encKeyLen; 01779 //Initialization vectors 01780 context->readIv = context->writeEncKey + context->encKeyLen; 01781 context->writeIv = context->readIv + context->fixedIvLen; 01782 } 01783 01784 //Dump MAC keys for debugging purpose 01785 if(context->macKeyLen > 0) 01786 { 01787 TRACE_DEBUG(" Write MAC key:\r\n"); 01788 TRACE_DEBUG_ARRAY(" ", context->writeMacKey, context->macKeyLen); 01789 TRACE_DEBUG(" Read MAC key:\r\n"); 01790 TRACE_DEBUG_ARRAY(" ", context->readMacKey, context->macKeyLen); 01791 } 01792 01793 //Dump encryption keys for debugging purpose 01794 TRACE_DEBUG(" Write encryption key:\r\n"); 01795 TRACE_DEBUG_ARRAY(" ", context->writeEncKey, context->encKeyLen); 01796 TRACE_DEBUG(" Read encryption key:\r\n"); 01797 TRACE_DEBUG_ARRAY(" ", context->readEncKey, context->encKeyLen); 01798 01799 //Dump initialization vectors for debugging purpose 01800 if(context->fixedIvLen > 0) 01801 { 01802 TRACE_DEBUG(" Write IV:\r\n"); 01803 TRACE_DEBUG_ARRAY(" ", context->writeIv, context->fixedIvLen); 01804 TRACE_DEBUG(" Read IV:\r\n"); 01805 TRACE_DEBUG_ARRAY(" ", context->readIv, context->fixedIvLen); 01806 } 01807 01808 //Key generation is successful 01809 return NO_ERROR; 01810 } 01811 01812 01813 /** 01814 * @brief Pseudorandom function (TLS 1.0 and 1.1) 01815 * 01816 * The pseudorandom function (PRF) takes as input a secret, a seed, and 01817 * an identifying label and produces an output of arbitrary length. This 01818 * function is used to expand secrets into blocks of data for the purpose 01819 * of key generation 01820 * 01821 * @param[in] secret Pointer to the secret 01822 * @param[in] secretLength Length of the secret 01823 * @param[in] label Identifying label (NULL-terminated string) 01824 * @param[in] seed Pointer to the seed 01825 * @param[in] seedLength Length of the seed 01826 * @param[out] output Pointer to the output 01827 * @param[in] outputLength Desired output length 01828 * @return Error code 01829 **/ 01830 01831 error_t tlsPrf(const uint8_t *secret, size_t secretLength, const char_t *label, 01832 const uint8_t *seed, size_t seedLength, uint8_t *output, size_t outputLength) 01833 { 01834 uint_t i; 01835 uint_t j; 01836 size_t labelLength; 01837 size_t sLength; 01838 const uint8_t *s1; 01839 const uint8_t *s2; 01840 HmacContext *hmacContext; 01841 uint8_t a[SHA1_DIGEST_SIZE]; 01842 01843 //Allocate a memory buffer to hold the HMAC context 01844 hmacContext = tlsAllocMem(sizeof(HmacContext)); 01845 //Failed to allocate memory? 01846 if(hmacContext == NULL) 01847 return ERROR_OUT_OF_MEMORY; 01848 01849 //Compute the length of the label 01850 labelLength = strlen(label); 01851 01852 //The secret is partitioned into two halves S1 and S2 01853 //with the possibility of one shared byte 01854 sLength = (secretLength + 1) / 2; 01855 //S1 is taken from the first half of the secret 01856 s1 = secret; 01857 //S2 is taken from the second half 01858 s2 = secret + secretLength - sLength; 01859 01860 //First compute A(1) = HMAC_MD5(S1, label + seed) 01861 hmacInit(hmacContext, MD5_HASH_ALGO, s1, sLength); 01862 hmacUpdate(hmacContext, label, labelLength); 01863 hmacUpdate(hmacContext, seed, seedLength); 01864 hmacFinal(hmacContext, a); 01865 01866 //Apply the data expansion function P_MD5 01867 for(i = 0; i < outputLength; ) 01868 { 01869 //Compute HMAC_MD5(S1, A(i) + label + seed) 01870 hmacInit(hmacContext, MD5_HASH_ALGO, s1, sLength); 01871 hmacUpdate(hmacContext, a, MD5_DIGEST_SIZE); 01872 hmacUpdate(hmacContext, label, labelLength); 01873 hmacUpdate(hmacContext, seed, seedLength); 01874 hmacFinal(hmacContext, NULL); 01875 01876 //Copy the resulting digest 01877 for(j = 0; i < outputLength && j < MD5_DIGEST_SIZE; i++, j++) 01878 output[i] = hmacContext->digest[j]; 01879 01880 //Compute A(i + 1) = HMAC_MD5(S1, A(i)) 01881 hmacInit(hmacContext, MD5_HASH_ALGO, s1, sLength); 01882 hmacUpdate(hmacContext, a, MD5_DIGEST_SIZE); 01883 hmacFinal(hmacContext, a); 01884 } 01885 01886 //First compute A(1) = HMAC_SHA1(S2, label + seed) 01887 hmacInit(hmacContext, SHA1_HASH_ALGO, s2, sLength); 01888 hmacUpdate(hmacContext, label, labelLength); 01889 hmacUpdate(hmacContext, seed, seedLength); 01890 hmacFinal(hmacContext, a); 01891 01892 //Apply the data expansion function P_SHA1 01893 for(i = 0; i < outputLength; ) 01894 { 01895 //Compute HMAC_SHA1(S2, A(i) + label + seed) 01896 hmacInit(hmacContext, SHA1_HASH_ALGO, s2, sLength); 01897 hmacUpdate(hmacContext, a, SHA1_DIGEST_SIZE); 01898 hmacUpdate(hmacContext, label, labelLength); 01899 hmacUpdate(hmacContext, seed, seedLength); 01900 hmacFinal(hmacContext, NULL); 01901 01902 //Copy the resulting digest 01903 for(j = 0; i < outputLength && j < SHA1_DIGEST_SIZE; i++, j++) 01904 output[i] ^= hmacContext->digest[j]; 01905 01906 //Compute A(i + 1) = HMAC_SHA1(S2, A(i)) 01907 hmacInit(hmacContext, SHA1_HASH_ALGO, s2, sLength); 01908 hmacUpdate(hmacContext, a, SHA1_DIGEST_SIZE); 01909 hmacFinal(hmacContext, a); 01910 } 01911 01912 //Free previously allocated memory 01913 tlsFreeMem(hmacContext); 01914 //Successful processing 01915 return NO_ERROR; 01916 } 01917 01918 01919 /** 01920 * @brief Pseudorandom function (TLS 1.2) 01921 * 01922 * The pseudorandom function (PRF) takes as input a secret, a seed, and 01923 * an identifying label and produces an output of arbitrary length. This 01924 * function is used to expand secrets into blocks of data for the purpose 01925 * of key generation 01926 * 01927 * @param[in] hash Hash function used to compute PRF 01928 * @param[in] secret Pointer to the secret 01929 * @param[in] secretLength Length of the secret 01930 * @param[in] label Identifying label (NULL-terminated string) 01931 * @param[in] seed Pointer to the seed 01932 * @param[in] seedLength Length of the seed 01933 * @param[out] output Pointer to the output 01934 * @param[in] outputLength Desired output length 01935 * @return Error code 01936 **/ 01937 01938 error_t tlsPrf2(const HashAlgo *hash, const uint8_t *secret, size_t secretLength, 01939 const char_t *label, const uint8_t *seed, size_t seedLength, uint8_t *output, size_t outputLength) 01940 { 01941 size_t n; 01942 size_t labelLength; 01943 HmacContext *hmacContext; 01944 uint8_t a[MAX_HASH_DIGEST_SIZE]; 01945 01946 //Allocate a memory buffer to hold the HMAC context 01947 hmacContext = tlsAllocMem(sizeof(HmacContext)); 01948 //Failed to allocate memory? 01949 if(hmacContext == NULL) 01950 return ERROR_OUT_OF_MEMORY; 01951 01952 //Compute the length of the label 01953 labelLength = strlen(label); 01954 01955 //First compute A(1) = HMAC_hash(secret, label + seed) 01956 hmacInit(hmacContext, hash, secret, secretLength); 01957 hmacUpdate(hmacContext, label, labelLength); 01958 hmacUpdate(hmacContext, seed, seedLength); 01959 hmacFinal(hmacContext, a); 01960 01961 //Apply the data expansion function P_hash 01962 while(outputLength > 0) 01963 { 01964 //Compute HMAC_hash(secret, A(i) + label + seed) 01965 hmacInit(hmacContext, hash, secret, secretLength); 01966 hmacUpdate(hmacContext, a, hash->digestSize); 01967 hmacUpdate(hmacContext, label, labelLength); 01968 hmacUpdate(hmacContext, seed, seedLength); 01969 hmacFinal(hmacContext, NULL); 01970 01971 //Calculate the number of bytes to copy 01972 n = MIN(outputLength, hash->digestSize); 01973 //Copy the resulting digest 01974 memcpy(output, hmacContext->digest, n); 01975 01976 //Compute A(i + 1) = HMAC_hash(secret, A(i)) 01977 hmacInit(hmacContext, hash, secret, secretLength); 01978 hmacUpdate(hmacContext, a, hash->digestSize); 01979 hmacFinal(hmacContext, a); 01980 01981 //Advance data pointer 01982 output += n; 01983 //Decrement byte counter 01984 outputLength -= n; 01985 } 01986 01987 //Free previously allocated memory 01988 tlsFreeMem(hmacContext); 01989 //Successful processing 01990 return NO_ERROR; 01991 } 01992 01993 01994 /** 01995 * @brief Check whether a certificate is acceptable 01996 * @param[in] cert End entity certificate 01997 * @param[in] certTypes List of supported certificate types 01998 * @param[in] numCertTypes Size of the list that contains the supported certificate types 01999 * @param[in] signHashAlgos List of supported signature algorithms 02000 * @param[in] curveList List of supported elliptic curves 02001 * @param[in] certAuthorities List of trusted CA 02002 * @return TRUE if the specified certificate conforms to the requirements, else FALSE 02003 **/ 02004 02005 bool_t tlsIsCertificateAcceptable(const TlsCertDesc *cert, 02006 const uint8_t *certTypes, size_t numCertTypes, const TlsSignHashAlgos *signHashAlgos, 02007 const TlsEllipticCurveList *curveList, const TlsCertAuthorities *certAuthorities) 02008 { 02009 size_t i; 02010 size_t n; 02011 size_t length; 02012 bool_t acceptable; 02013 02014 //Make sure that a valid certificate has been loaded 02015 if(!cert->certChain || !cert->certChainLength) 02016 return FALSE; 02017 02018 //This flag tells whether the certificate is acceptable 02019 acceptable = TRUE; 02020 02021 //Filter out certificates with unsupported type 02022 if(numCertTypes > 0) 02023 { 02024 //Loop through the list of supported certificate types 02025 for(acceptable = FALSE, i = 0; i < numCertTypes; i++) 02026 { 02027 //Check whether the certificate type is acceptable 02028 if(certTypes[i] == cert->type) 02029 { 02030 acceptable = TRUE; 02031 break; 02032 } 02033 } 02034 } 02035 02036 //Filter out certificates that are signed with an unsupported 02037 //hash/signature algorithm 02038 if(acceptable && signHashAlgos != NULL) 02039 { 02040 //Retrieve the number of items in the list 02041 n = ntohs(signHashAlgos->length) / sizeof(TlsSignHashAlgo); 02042 02043 //Loop through the list of supported hash/signature algorithm pairs 02044 for(acceptable = FALSE, i = 0; i < n; i++) 02045 { 02046 //The certificate must be signed using a valid hash/signature algorithm pair 02047 if(signHashAlgos->value[i].signature == cert->signAlgo && 02048 signHashAlgos->value[i].hash == cert->hashAlgo) 02049 { 02050 acceptable = TRUE; 02051 break; 02052 } 02053 } 02054 } 02055 02056 //Check whether the certificate contains an ECDSA public key 02057 if(cert->type == TLS_CERT_ECDSA_SIGN) 02058 { 02059 //Filter out ECDSA certificates that use an unsupported elliptic curve 02060 if(acceptable && curveList != NULL) 02061 { 02062 //Retrieve the number of items in the list 02063 n = ntohs(curveList->length) / sizeof(uint16_t); 02064 02065 //Loop through the list of supported elliptic curves 02066 for(acceptable = FALSE, i = 0; i < n; i++) 02067 { 02068 //Check whether the elliptic curve is supported 02069 if(ntohs(curveList->value[i]) == cert->namedCurve) 02070 { 02071 acceptable = TRUE; 02072 break; 02073 } 02074 } 02075 } 02076 } 02077 02078 //Filter out certificates that are issued by a non trusted CA 02079 if(acceptable && certAuthorities != NULL) 02080 { 02081 //Retrieve the length of the list 02082 length = ntohs(certAuthorities->length); 02083 02084 //If the certificate authorities list is empty, then the client 02085 //may send any certificate of the appropriate type 02086 if(length > 0) 02087 { 02088 error_t error; 02089 const uint8_t *p; 02090 const char_t *pemCert; 02091 size_t pemCertLength; 02092 uint8_t *derCert; 02093 size_t derCertSize; 02094 size_t derCertLength; 02095 X509CertificateInfo *certInfo; 02096 02097 //The list of acceptable certificate authorities describes the known roots CA 02098 acceptable = FALSE; 02099 02100 //Point to the first distinguished name 02101 p = certAuthorities->value; 02102 02103 //Point to the end entity certificate 02104 pemCert = cert->certChain; 02105 //Get the total length, in bytes, of the certificate chain 02106 pemCertLength = cert->certChainLength; 02107 02108 //DER encoded certificate 02109 derCert = NULL; 02110 derCertSize = 0; 02111 derCertLength = 0; 02112 02113 //Start of exception handling block 02114 do 02115 { 02116 //Allocate a memory buffer to store X.509 certificate info 02117 certInfo = tlsAllocMem(sizeof(X509CertificateInfo)); 02118 //Failed to allocate memory? 02119 if(certInfo == NULL) 02120 break; 02121 02122 //Point to the last certificate of the chain 02123 do 02124 { 02125 //Read PEM certificates, one by one 02126 error = pemReadCertificate(&pemCert, &pemCertLength, 02127 &derCert, &derCertSize, &derCertLength); 02128 02129 //Loop as long as necessary 02130 } while(!error); 02131 02132 //Any error to report? 02133 if(error != ERROR_END_OF_FILE) 02134 break; 02135 02136 //Parse the last certificate of the chain 02137 error = x509ParseCertificate(derCert, derCertLength, certInfo); 02138 //Failed to parse the X.509 certificate? 02139 if(error) 02140 break; 02141 02142 //Parse each distinguished name of the list 02143 while(length > 0) 02144 { 02145 //Sanity check 02146 if(length < 2) 02147 break; 02148 02149 //Each distinguished name is preceded by a 2-byte length field 02150 n = LOAD16BE(p); 02151 02152 //Make sure the length field is valid 02153 if(length < (n + 2)) 02154 break; 02155 02156 //Check if the distinguished name matches the root CA 02157 if(n == certInfo->issuer.rawDataLen && !memcmp(p + 2, certInfo->issuer.rawData, n)) 02158 { 02159 acceptable = TRUE; 02160 break; 02161 } 02162 02163 //Advance data pointer 02164 p += n + 2; 02165 //Number of bytes left in the list 02166 length -= n + 2; 02167 } 02168 02169 //End of exception handling block 02170 } while(0); 02171 02172 //Release previously allocated memory 02173 tlsFreeMem(derCert); 02174 tlsFreeMem(certInfo); 02175 } 02176 } 02177 02178 //The return value specifies whether all the criteria were matched 02179 return acceptable; 02180 } 02181 02182 02183 /** 02184 * @brief Retrieve the certificate type 02185 * @param[in] certInfo X.509 certificate 02186 * @param[out] certType Certificate type 02187 * @param[out] certSignAlgo Signature algorithm that has been used to sign the certificate 02188 * @param[out] certHashAlgo Hash algorithm that has been used to sign the certificate 02189 * @param[out] namedCurve Elliptic curve (only for ECDSA certificates) 02190 * @return Error code 02191 **/ 02192 02193 error_t tlsGetCertificateType(const X509CertificateInfo *certInfo, TlsCertificateType *certType, 02194 TlsSignatureAlgo *certSignAlgo, TlsHashAlgo *certHashAlgo, TlsEcNamedCurve *namedCurve) 02195 { 02196 //Check parameters 02197 if(certInfo == NULL || certType == NULL || certSignAlgo == NULL || 02198 certHashAlgo == NULL || namedCurve == NULL) 02199 { 02200 //Report an error 02201 return ERROR_INVALID_PARAMETER; 02202 } 02203 02204 #if (TLS_RSA_SIGN_SUPPORT == ENABLED || TLS_RSA_SUPPORT == ENABLED || \ 02205 TLS_DHE_RSA_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED) 02206 //A valid RSA public key has been found? 02207 if(!oidComp(certInfo->subjectPublicKeyInfo.oid, certInfo->subjectPublicKeyInfo.oidLen, 02208 RSA_ENCRYPTION_OID, sizeof(RSA_ENCRYPTION_OID))) 02209 { 02210 //Save certificate type 02211 *certType = TLS_CERT_RSA_SIGN; 02212 //Elliptic curve cryptography is not used 02213 *namedCurve = TLS_EC_CURVE_NONE; 02214 } 02215 else 02216 #endif 02217 #if (TLS_DSA_SIGN_SUPPORT == ENABLED || TLS_DHE_DSS_SUPPORT == ENABLED) 02218 //A valid DSA public key has been found? 02219 if(!oidComp(certInfo->subjectPublicKeyInfo.oid, certInfo->subjectPublicKeyInfo.oidLen, 02220 DSA_OID, sizeof(DSA_OID))) 02221 { 02222 //Save certificate type 02223 *certType = TLS_CERT_DSS_SIGN; 02224 //Elliptic curve cryptography is not used 02225 *namedCurve = TLS_EC_CURVE_NONE; 02226 } 02227 else 02228 #endif 02229 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_ECDHE_ECDSA_SUPPORT == ENABLED) 02230 //A valid EC public key has been found? 02231 if(!oidComp(certInfo->subjectPublicKeyInfo.oid, certInfo->subjectPublicKeyInfo.oidLen, 02232 EC_PUBLIC_KEY_OID, sizeof(EC_PUBLIC_KEY_OID))) 02233 { 02234 //Save certificate type 02235 *certType = TLS_CERT_ECDSA_SIGN; 02236 02237 //Retrieve the named curve that has been used to generate the EC public key 02238 *namedCurve = tlsGetNamedCurve(certInfo->subjectPublicKeyInfo.ecParams.namedCurve, 02239 certInfo->subjectPublicKeyInfo.ecParams.namedCurveLen); 02240 } 02241 else 02242 #endif 02243 //The certificate does not contain any valid public key... 02244 { 02245 //Report an error 02246 return ERROR_BAD_CERTIFICATE; 02247 } 02248 02249 //Retrieve the signature algorithm that has been used to sign the certificate 02250 if(certInfo->signatureAlgo == NULL) 02251 { 02252 //Invalid certificate 02253 return ERROR_BAD_CERTIFICATE; 02254 } 02255 #if (TLS_RSA_SIGN_SUPPORT == ENABLED) 02256 else if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02257 MD5_WITH_RSA_ENCRYPTION_OID, sizeof(MD5_WITH_RSA_ENCRYPTION_OID))) 02258 { 02259 //MD5 with RSA signature algorithm 02260 *certSignAlgo = TLS_SIGN_ALGO_RSA; 02261 *certHashAlgo = TLS_HASH_ALGO_MD5; 02262 } 02263 else if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02264 SHA1_WITH_RSA_ENCRYPTION_OID, sizeof(SHA1_WITH_RSA_ENCRYPTION_OID))) 02265 { 02266 //SHA-1 with RSA signature algorithm 02267 *certSignAlgo = TLS_SIGN_ALGO_RSA; 02268 *certHashAlgo = TLS_HASH_ALGO_SHA1; 02269 } 02270 else if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02271 SHA256_WITH_RSA_ENCRYPTION_OID, sizeof(SHA256_WITH_RSA_ENCRYPTION_OID))) 02272 { 02273 //SHA-256 with RSA signature algorithm 02274 *certSignAlgo = TLS_SIGN_ALGO_RSA; 02275 *certHashAlgo = TLS_HASH_ALGO_SHA256; 02276 } 02277 else if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02278 SHA384_WITH_RSA_ENCRYPTION_OID, sizeof(SHA384_WITH_RSA_ENCRYPTION_OID))) 02279 { 02280 //SHA-384 with RSA signature algorithm 02281 *certSignAlgo = TLS_SIGN_ALGO_RSA; 02282 *certHashAlgo = TLS_HASH_ALGO_SHA384; 02283 } 02284 else if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02285 SHA512_WITH_RSA_ENCRYPTION_OID, sizeof(SHA512_WITH_RSA_ENCRYPTION_OID))) 02286 { 02287 //SHA-512 with RSA signature algorithm 02288 *certSignAlgo = TLS_SIGN_ALGO_RSA; 02289 *certHashAlgo = TLS_HASH_ALGO_SHA512; 02290 } 02291 #endif 02292 #if (TLS_DSA_SIGN_SUPPORT == ENABLED) 02293 else if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02294 DSA_WITH_SHA1_OID, sizeof(DSA_WITH_SHA1_OID))) 02295 { 02296 //DSA with SHA-1 signature algorithm 02297 *certSignAlgo = TLS_SIGN_ALGO_DSA; 02298 *certHashAlgo = TLS_HASH_ALGO_SHA1; 02299 } 02300 else if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02301 DSA_WITH_SHA224_OID, sizeof(DSA_WITH_SHA224_OID))) 02302 { 02303 //DSA with SHA-224 signature algorithm 02304 *certSignAlgo = TLS_SIGN_ALGO_DSA; 02305 *certHashAlgo = TLS_HASH_ALGO_SHA224; 02306 } 02307 else if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02308 DSA_WITH_SHA256_OID, sizeof(DSA_WITH_SHA256_OID))) 02309 { 02310 //DSA with SHA-256 signature algorithm 02311 *certSignAlgo = TLS_SIGN_ALGO_DSA; 02312 *certHashAlgo = TLS_HASH_ALGO_SHA256; 02313 } 02314 #endif 02315 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED) 02316 else if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02317 ECDSA_WITH_SHA1_OID, sizeof(ECDSA_WITH_SHA1_OID))) 02318 { 02319 //ECDSA with SHA-1 signature algorithm 02320 *certSignAlgo = TLS_SIGN_ALGO_ECDSA; 02321 *certHashAlgo = TLS_HASH_ALGO_SHA1; 02322 } 02323 else if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02324 ECDSA_WITH_SHA224_OID, sizeof(ECDSA_WITH_SHA224_OID))) 02325 { 02326 //ECDSA with SHA-224 signature algorithm 02327 *certSignAlgo = TLS_SIGN_ALGO_ECDSA; 02328 *certHashAlgo = TLS_HASH_ALGO_SHA224; 02329 } 02330 else if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02331 ECDSA_WITH_SHA256_OID, sizeof(ECDSA_WITH_SHA256_OID))) 02332 { 02333 //ECDSA with SHA-256 signature algorithm 02334 *certSignAlgo = TLS_SIGN_ALGO_ECDSA; 02335 *certHashAlgo = TLS_HASH_ALGO_SHA256; 02336 } 02337 else if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02338 ECDSA_WITH_SHA384_OID, sizeof(ECDSA_WITH_SHA384_OID))) 02339 { 02340 //ECDSA with SHA-384 signature algorithm 02341 *certSignAlgo = TLS_SIGN_ALGO_ECDSA; 02342 *certHashAlgo = TLS_HASH_ALGO_SHA384; 02343 } 02344 else if(!oidComp(certInfo->signatureAlgo, certInfo->signatureAlgoLen, 02345 ECDSA_WITH_SHA512_OID, sizeof(ECDSA_WITH_SHA512_OID))) 02346 { 02347 //ECDSA with SHA-512 signature algorithm 02348 *certSignAlgo = TLS_SIGN_ALGO_ECDSA; 02349 *certHashAlgo = TLS_HASH_ALGO_SHA512; 02350 } 02351 #endif 02352 else 02353 { 02354 //The signature algorithm is not supported... 02355 return ERROR_BAD_CERTIFICATE; 02356 } 02357 02358 //X.509 certificate successfully parsed 02359 return NO_ERROR; 02360 } 02361 02362 02363 /** 02364 * @brief Find the specified extension 02365 * @param[in] data Pointer to the list of extensions 02366 * @param[in] length Length in bytes of the list 02367 * @param[in] type Expected extension type 02368 * @return If the specified extension was found, a pointer to the corresponding 02369 * extension is returned. Otherwise NULL pointer is returned 02370 **/ 02371 02372 const TlsExtension *tlsGetExtension(const uint8_t *data, size_t length, uint16_t type) 02373 { 02374 size_t n; 02375 const TlsExtension *extension; 02376 02377 //Sanity check 02378 if(length < 2) 02379 return NULL; 02380 02381 //Retrieve the length of the list 02382 n = LOAD16BE(data); 02383 02384 //Sanity check 02385 if(length < (n + 2)) 02386 return NULL; 02387 02388 //Point to the first extension of the list 02389 data += 2; 02390 02391 //Parse the list of extensions offered by the peer 02392 while(n > 0) 02393 { 02394 //Point to the current extension 02395 extension = (TlsExtension *) data; 02396 02397 //Check the length of the extension 02398 if(n < sizeof(TlsExtension)) 02399 break; 02400 if(n < (sizeof(TlsExtension) + ntohs(extension->length))) 02401 break; 02402 02403 //Check whether the extension type matches the specified one 02404 if(ntohs(extension->type) == type) 02405 return extension; 02406 02407 //Jump to the next extension 02408 data += sizeof(TlsExtension) + ntohs(extension->length); 02409 //Remaining bytes to process 02410 n -= sizeof(TlsExtension) + ntohs(extension->length); 02411 } 02412 02413 //The specified extension type was not found 02414 return NULL; 02415 } 02416 02417 02418 /** 02419 * @brief Convert TLS version to string representation 02420 * @param[in] version Version number 02421 * @return Cipher suite name 02422 **/ 02423 02424 const char_t *tlsGetVersionName(uint16_t version) 02425 { 02426 //TLS versions 02427 static const char_t *label[] = {"SSL 3.0", "TLS 1.0", "TLS 1.1", "TLS 1.2", "Unknown"}; 02428 02429 //Check current version 02430 if(version == SSL_VERSION_3_0) 02431 return label[0]; 02432 else if(version == TLS_VERSION_1_0) 02433 return label[1]; 02434 else if(version == TLS_VERSION_1_1) 02435 return label[2]; 02436 else if(version == TLS_VERSION_1_2) 02437 return label[3]; 02438 else 02439 return label[4]; 02440 } 02441 02442 02443 /** 02444 * @brief Get the hash algorithm that matches the specified identifier 02445 * @param[in] hashAlgoId Hash algorithm identifier 02446 * @return Cipher suite name 02447 **/ 02448 02449 const HashAlgo *tlsGetHashAlgo(uint8_t hashAlgoId) 02450 { 02451 //MD5 hash identifier? 02452 if(hashAlgoId == TLS_HASH_ALGO_MD5) 02453 return MD5_HASH_ALGO; 02454 //SHA-1 hash identifier? 02455 else if(hashAlgoId == TLS_HASH_ALGO_SHA1) 02456 return SHA1_HASH_ALGO; 02457 //SHA-256 hash identifier? 02458 else if(hashAlgoId == TLS_HASH_ALGO_SHA256) 02459 return SHA256_HASH_ALGO; 02460 #if (TLS_SHA224_SUPPORT == ENABLED) 02461 //SHA-224 hash identifier? 02462 else if(hashAlgoId == TLS_HASH_ALGO_SHA224) 02463 return SHA224_HASH_ALGO; 02464 #endif 02465 #if (TLS_SHA384_SUPPORT == ENABLED) 02466 //SHA-384 hash identifier? 02467 else if(hashAlgoId == TLS_HASH_ALGO_SHA384) 02468 return SHA384_HASH_ALGO; 02469 #endif 02470 #if (TLS_SHA512_SUPPORT == ENABLED) 02471 //SHA-512 hash identifier? 02472 else if(hashAlgoId == TLS_HASH_ALGO_SHA512) 02473 return SHA512_HASH_ALGO; 02474 #endif 02475 //Unknown hash identifier? 02476 else 02477 return NULL; 02478 } 02479 02480 02481 /** 02482 * @brief Get the EC domain parameters that match the specified named curve 02483 * @param[in] namedCurve Elliptic curve identifier 02484 * @return Elliptic curve domain parameters 02485 **/ 02486 02487 const EcCurveInfo *tlsGetCurveInfo(uint16_t namedCurve) 02488 { 02489 #if (TLS_ECDH_ANON_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED || \ 02490 TLS_ECDHE_ECDSA_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED) 02491 //Explicit prime elliptic curves are not supported 02492 if(namedCurve == TLS_EC_CURVE_ARBITRARY_EXPLICIT_PRIME) 02493 return NULL; 02494 //Explicit characteristic-2 elliptic curves are not supported 02495 else if(namedCurve == TLS_EC_CURVE_ARBITRARY_EXPLICIT_CHAR2) 02496 return NULL; 02497 #if (TLS_SECP160K1_SUPPORT == ENABLED) 02498 //secp160k1 elliptic curve? 02499 else if(namedCurve == TLS_EC_CURVE_SECP160K1) 02500 return SECP160K1_CURVE; 02501 #endif 02502 #if (TLS_SECP160R1_SUPPORT == ENABLED) 02503 //secp160r1 elliptic curve? 02504 else if(namedCurve == TLS_EC_CURVE_SECP160R1) 02505 return SECP160R1_CURVE; 02506 #endif 02507 #if (TLS_SECP160R2_SUPPORT == ENABLED) 02508 //secp160r2 elliptic curve? 02509 else if(namedCurve == TLS_EC_CURVE_SECP160R2) 02510 return SECP160R2_CURVE; 02511 #endif 02512 #if (TLS_SECP192K1_SUPPORT == ENABLED) 02513 //secp192k1 elliptic curve? 02514 else if(namedCurve == TLS_EC_CURVE_SECP192K1) 02515 return SECP192K1_CURVE; 02516 #endif 02517 #if (TLS_SECP192R1_SUPPORT == ENABLED) 02518 //secp192r1 elliptic curve? 02519 else if(namedCurve == TLS_EC_CURVE_SECP192R1) 02520 return SECP192R1_CURVE; 02521 #endif 02522 #if (TLS_SECP224K1_SUPPORT == ENABLED) 02523 //secp224k1 elliptic curve? 02524 else if(namedCurve == TLS_EC_CURVE_SECP224K1) 02525 return SECP224K1_CURVE; 02526 #endif 02527 #if (TLS_SECP224R1_SUPPORT == ENABLED) 02528 //secp224r1 elliptic curve? 02529 else if(namedCurve == TLS_EC_CURVE_SECP224R1) 02530 return SECP224R1_CURVE; 02531 #endif 02532 #if (TLS_SECP256K1_SUPPORT == ENABLED) 02533 //secp256k1 elliptic curve? 02534 else if(namedCurve == TLS_EC_CURVE_SECP256K1) 02535 return SECP256K1_CURVE; 02536 #endif 02537 #if (TLS_SECP256R1_SUPPORT == ENABLED) 02538 //secp256r1 elliptic curve? 02539 else if(namedCurve == TLS_EC_CURVE_SECP256R1) 02540 return SECP256R1_CURVE; 02541 #endif 02542 #if (TLS_SECP384R1_SUPPORT == ENABLED) 02543 //secp384r1 elliptic curve? 02544 else if(namedCurve == TLS_EC_CURVE_SECP384R1) 02545 return SECP384R1_CURVE; 02546 #endif 02547 #if (TLS_SECP521R1_SUPPORT == ENABLED) 02548 //secp521r1 elliptic curve? 02549 else if(namedCurve == TLS_EC_CURVE_SECP521R1) 02550 return SECP521R1_CURVE; 02551 #endif 02552 #if (TLS_BRAINPOOLP256R1_SUPPORT == ENABLED) 02553 //brainpoolP256r1 elliptic curve? 02554 else if(namedCurve == TLS_EC_CURVE_BRAINPOOLP256R1) 02555 return BRAINPOOLP256R1_CURVE; 02556 #endif 02557 #if (TLS_BRAINPOOLP384R1_SUPPORT == ENABLED) 02558 //brainpoolP384r1 elliptic curve? 02559 else if(namedCurve == TLS_EC_CURVE_BRAINPOOLP384R1) 02560 return BRAINPOOLP384R1_CURVE; 02561 #endif 02562 #if (TLS_BRAINPOOLP512R1_SUPPORT == ENABLED) 02563 //brainpoolP512r1 elliptic curve? 02564 else if(namedCurve == TLS_EC_CURVE_BRAINPOOLP512R1) 02565 return BRAINPOOLP512R1_CURVE; 02566 #endif 02567 //Unknown identifier? 02568 else 02569 return NULL; 02570 #else 02571 //ECC not supported 02572 return NULL; 02573 #endif 02574 } 02575 02576 02577 /** 02578 * @brief Get the named curve that matches the specified OID 02579 * @param[in] oid Object identifier 02580 * @param[in] length OID length 02581 * @return Named curve 02582 **/ 02583 02584 TlsEcNamedCurve tlsGetNamedCurve(const uint8_t *oid, size_t length) 02585 { 02586 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_ECDHE_ECDSA_SUPPORT == ENABLED) 02587 //Make sure the object identifier is valid 02588 if(oid == NULL) 02589 return TLS_EC_CURVE_NONE; 02590 #if (TLS_SECP160K1_SUPPORT == ENABLED) 02591 //secp160k1 elliptic curve? 02592 else if(!oidComp(oid, length, SECP160K1_OID, sizeof(SECP160K1_OID))) 02593 return TLS_EC_CURVE_SECP160K1; 02594 #endif 02595 #if (TLS_SECP160R1_SUPPORT == ENABLED) 02596 //secp160r1 elliptic curve? 02597 else if(!oidComp(oid, length, SECP160R1_OID, sizeof(SECP160R1_OID))) 02598 return TLS_EC_CURVE_SECP160R1; 02599 #endif 02600 #if (TLS_SECP160R2_SUPPORT == ENABLED) 02601 //secp160r2 elliptic curve? 02602 else if(!oidComp(oid, length, SECP160R2_OID, sizeof(SECP160R2_OID))) 02603 return TLS_EC_CURVE_SECP160R2; 02604 #endif 02605 #if (TLS_SECP192K1_SUPPORT == ENABLED) 02606 //secp192k1 elliptic curve? 02607 else if(!oidComp(oid, length, SECP192K1_OID, sizeof(SECP192K1_OID))) 02608 return TLS_EC_CURVE_SECP192K1; 02609 #endif 02610 #if (TLS_SECP192R1_SUPPORT == ENABLED) 02611 //secp192r1 elliptic curve? 02612 else if(!oidComp(oid, length, SECP192R1_OID, sizeof(SECP192R1_OID))) 02613 return TLS_EC_CURVE_SECP192R1; 02614 #endif 02615 #if (TLS_SECP224K1_SUPPORT == ENABLED) 02616 //secp224k1 elliptic curve? 02617 else if(!oidComp(oid, length, SECP224K1_OID, sizeof(SECP224K1_OID))) 02618 return TLS_EC_CURVE_SECP224K1; 02619 #endif 02620 #if (TLS_SECP224R1_SUPPORT == ENABLED) 02621 //secp224r1 elliptic curve? 02622 else if(!oidComp(oid, length, SECP224R1_OID, sizeof(SECP224R1_OID))) 02623 return TLS_EC_CURVE_SECP224R1; 02624 #endif 02625 #if (TLS_SECP256K1_SUPPORT == ENABLED) 02626 //secp256k1 elliptic curve? 02627 else if(!oidComp(oid, length, SECP256K1_OID, sizeof(SECP256K1_OID))) 02628 return TLS_EC_CURVE_SECP256K1; 02629 #endif 02630 #if (TLS_SECP256R1_SUPPORT == ENABLED) 02631 //secp256r1 elliptic curve? 02632 else if(!oidComp(oid, length, SECP256R1_OID, sizeof(SECP256R1_OID))) 02633 return TLS_EC_CURVE_SECP256R1; 02634 #endif 02635 #if (TLS_SECP384R1_SUPPORT == ENABLED) 02636 //secp384r1 elliptic curve? 02637 else if(!oidComp(oid, length, SECP384R1_OID, sizeof(SECP384R1_OID))) 02638 return TLS_EC_CURVE_SECP384R1; 02639 #endif 02640 #if (TLS_SECP521R1_SUPPORT == ENABLED) 02641 //secp521r1 elliptic curve? 02642 else if(!oidComp(oid, length, SECP521R1_OID, sizeof(SECP521R1_OID))) 02643 return TLS_EC_CURVE_SECP521R1; 02644 #endif 02645 #if (TLS_BRAINPOOLP256R1_SUPPORT == ENABLED) 02646 //brainpoolP256r1 elliptic curve? 02647 else if(!oidComp(oid, length, BRAINPOOLP256R1_OID, sizeof(BRAINPOOLP256R1_OID))) 02648 return TLS_EC_CURVE_BRAINPOOLP256R1; 02649 #endif 02650 #if (TLS_BRAINPOOLP384R1_SUPPORT == ENABLED) 02651 //brainpoolP384r1 elliptic curve? 02652 else if(!oidComp(oid, length, BRAINPOOLP384R1_OID, sizeof(BRAINPOOLP384R1_OID))) 02653 return TLS_EC_CURVE_BRAINPOOLP384R1; 02654 #endif 02655 #if (TLS_BRAINPOOLP512R1_SUPPORT == ENABLED) 02656 //brainpoolP512r1 elliptic curve? 02657 else if(!oidComp(oid, length, BRAINPOOLP512R1_OID, sizeof(BRAINPOOLP512R1_OID))) 02658 return TLS_EC_CURVE_BRAINPOOLP512R1; 02659 #endif 02660 //Unknown identifier? 02661 else 02662 return TLS_EC_CURVE_NONE; 02663 #else 02664 //ECC not supported 02665 return TLS_EC_CURVE_NONE; 02666 #endif 02667 } 02668 02669 #endif 02670
Generated on Tue Jul 12 2022 17:10:17 by
1.7.2