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.
Fork of MiniTLS-GPL by
tls_record.c
00001 /* 00002 MiniTLS - A super trimmed down TLS/SSL Library for embedded devices 00003 Author: Donatien Garnier 00004 Copyright (C) 2013-2014 AppNearMe Ltd 00005 00006 This program is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU General Public License 00008 as published by the Free Software Foundation; either version 2 00009 of the License, or (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 *//** 00020 * \file tls_record.c 00021 * \copyright Copyright (c) AppNearMe Ltd 2013 00022 * \author Donatien Garnier 00023 */ 00024 00025 #define __DEBUG__ 4 00026 #ifndef __MODULE__ 00027 #define __MODULE__ "tls_record.c" 00028 #endif 00029 00030 #include "core/fwk.h" 00031 #include "inc/minitls_config.h" 00032 #include "inc/minitls_errors.h" 00033 #include "tls_record.h" 00034 #include "tls_alert.h" 00035 00036 #include "tls_handshake.h" 00037 #include "tls_socket.h" 00038 00039 #include "socket/socket.h" 00040 00041 #include "crypto/crypto_aes_128_cbc.h" 00042 #include "crypto/crypto_hmac_sha1.h" 00043 00044 static minitls_err_t record_wait_readable(tls_record_t* record); 00045 static minitls_err_t record_wait_writeable(tls_record_t* record); 00046 00047 static minitls_err_t record_socket_read(tls_record_t* record, size_t size); 00048 static minitls_err_t record_socket_write(tls_record_t* record, buffer_t* data); 00049 00050 static minitls_err_t tls_mac_append( const uint8_t* key, tls_content_type_t content_type, tls_protocol_version_t version, 00051 uint64_t sequence_number, buffer_t* buffer ); 00052 static minitls_err_t tls_mac_check( const uint8_t* key, tls_content_type_t content_type, tls_protocol_version_t version, 00053 uint64_t sequence_number, buffer_t* buffer ); 00054 00055 typedef struct __tls_fragment_header 00056 { 00057 tls_content_type_t type; 00058 tls_protocol_version_t version; 00059 uint16_t length; //(MAX 2^14 + 2048 = 18432) 00060 } tls_fragment_header_t; 00061 00062 #define FRAGMENT_HEADER_SIZE 5 00063 00064 #define DEFAULT_READ_TIMEOUT 20000 00065 #define DEFAULT_WRITE_TIMEOUT 20000 00066 00067 minitls_err_t tls_record_init(tls_record_t* record, tls_socket_t* sock, uint8_t* buf, size_t buf_size) 00068 { 00069 00070 record->handshake_done = false; 00071 00072 //Open BSD socket 00073 record->socket_fd = socket_socket(); 00074 if(record->socket_fd < 0) 00075 { 00076 ERR("Could not create socket descriptor"); 00077 return MINITLS_ERR_SOCKET_ERROR; 00078 } 00079 00080 record->read_timeout = DEFAULT_READ_TIMEOUT; 00081 record->write_timeout = DEFAULT_WRITE_TIMEOUT; 00082 00083 if(buf_size >= TLS_DEFAULT_MAX_FRAGMENT_SIZE) 00084 { 00085 record->max_fragment_size = TLS_DEFAULT_MAX_FRAGMENT_SIZE; 00086 } 00087 else if( buf_size >= 4096 + TLS_ENCRYPTION_MAX_OVERHEAD ) 00088 { 00089 record->max_fragment_size = 4096; 00090 } 00091 else if( buf_size >= 2048 + TLS_ENCRYPTION_MAX_OVERHEAD ) 00092 { 00093 record->max_fragment_size = 2048; 00094 } 00095 else if( buf_size >= 1024 + TLS_ENCRYPTION_MAX_OVERHEAD ) 00096 { 00097 record->max_fragment_size = 1024; 00098 } 00099 else if( buf_size >= 512 + TLS_ENCRYPTION_MAX_OVERHEAD ) 00100 { 00101 record->max_fragment_size = 512; 00102 } 00103 else 00104 { 00105 ERR("Buffer is too small"); 00106 return MINITLS_ERR_BUFFER_TOO_SMALL; 00107 } 00108 00109 DBG("Max fragment size: %d bytes", record->max_fragment_size); 00110 00111 if( (buf_size != TLS_DEFAULT_MAX_FRAGMENT_SIZE) 00112 && (buf_size != (record->max_fragment_size + TLS_ENCRYPTION_MAX_OVERHEAD)) ) 00113 { 00114 WARN("Buffer size is not optimum"); 00115 } 00116 00117 //Initialize with oldest protocol version by default (as recommended by RFC 5246's Annex E) 00118 #if MINITLS_CFG_PROTOCOL_SSL_3 00119 record->version.major = SSL_3_VERSION_MAJOR; 00120 record->version.minor = SSL_3_VERSION_MINOR; 00121 #elif MINITLS_CFG_PROTOCOL_TLS_1_0 00122 record->version.major = TLS_1_0_VERSION_MAJOR; 00123 record->version.minor = TLS_1_0_VERSION_MINOR; 00124 #elif MINITLS_CFG_PROTOCOL_TLS_1_1 00125 record->version.major = TLS_1_1_VERSION_MAJOR; 00126 record->version.minor = TLS_1_1_VERSION_MINOR; 00127 #elif MINITLS_CFG_PROTOCOL_TLS_1_2 00128 record->version.major = TLS_1_2_VERSION_MAJOR; 00129 record->version.minor = TLS_1_2_VERSION_MINOR; 00130 #else 00131 #error No SSL/TLS protocol version enabled 00132 #endif 00133 00134 buffer_init(&record->buffer, buf, buf_size); 00135 00136 record->tls_socket = sock; 00137 00138 //Init security 00139 record->security_rx_state = TLS_SECURITY_NONE; 00140 record->security_tx_state = TLS_SECURITY_NONE; 00141 record->security_type = TLS_SECURITY_TYPE_NULL_NULL_NULL; 00142 00143 //Memset keys 00144 memset(&record->client_write_mac_key, 0, TLS_HMAC_SHA1_KEY_SIZE); 00145 memset(&record->server_write_mac_key, 0, TLS_HMAC_SHA1_KEY_SIZE); 00146 memset(&record->client_write_cipher_key, 0, AES_128_KEY_SIZE); 00147 memset(&record->server_write_cipher_key, 0, AES_128_KEY_SIZE); 00148 00149 return MINITLS_OK; 00150 } 00151 00152 void tls_record_set_protocol_version(tls_record_t* record, uint8_t major, uint8_t minor) 00153 { 00154 record->version.major = major; 00155 record->version.minor = minor; 00156 } 00157 00158 void tls_record_get_protocol_version(tls_record_t* record, uint8_t* major, uint8_t* minor) 00159 { 00160 *major = record->version.major; 00161 *minor = record->version.minor; 00162 } 00163 00164 minitls_err_t tls_record_change_cipher_spec(tls_record_t* record, bool tx_nrx) 00165 { 00166 if(tx_nrx) 00167 { 00168 if(record->security_tx_state == TLS_SECURITY_INTIALIZED) 00169 { 00170 record->security_tx_state = TLS_SECURITY_ACTIVE; 00171 return MINITLS_OK; 00172 } 00173 else 00174 { 00175 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; 00176 } 00177 } 00178 else 00179 { 00180 if(record->security_rx_state == TLS_SECURITY_INTIALIZED) 00181 { 00182 record->security_rx_state = TLS_SECURITY_ACTIVE; 00183 return MINITLS_OK; 00184 } 00185 else 00186 { 00187 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; 00188 } 00189 } 00190 } 00191 00192 bool tls_record_is_secure(tls_record_t* record) 00193 { 00194 if( record->security_tx_state != TLS_SECURITY_ACTIVE ) 00195 { 00196 return false; 00197 } 00198 if( record->security_rx_state != TLS_SECURITY_ACTIVE ) 00199 { 00200 return false; 00201 } 00202 return true; 00203 } 00204 00205 minitls_err_t tls_record_connect(tls_record_t* record, const char* hostname, uint16_t port) 00206 { 00207 DBG("Trying to connect to %s:%d", hostname, port); 00208 00209 int r = socket_connect(record->socket_fd, hostname, port); 00210 if(r < 0) 00211 { 00212 socket_close(record->socket_fd); 00213 record->socket_fd = -1; 00214 return MINITLS_ERR_SOCKET_ERROR; 00215 } 00216 00217 return MINITLS_OK; 00218 } 00219 00220 minitls_err_t tls_record_process(tls_record_t* record) 00221 { 00222 //Reset buffer length 00223 buffer_reset(&record->buffer); 00224 00225 //Read header 00226 minitls_err_t ret = record_socket_read(record, FRAGMENT_HEADER_SIZE); 00227 if(ret == MINITLS_ERR_SOCKET_CLOSED) 00228 { 00229 return MINITLS_ERR_SOCKET_CLOSED; 00230 } 00231 else if(ret) 00232 { 00233 ERR("Socket err %d", ret); 00234 tls_alert_send( record, TLS_ALERT_FATAL, INTERNAL_ERROR, &record->buffer); 00235 return ret; 00236 } 00237 00238 //Read version 00239 tls_fragment_header_t header; 00240 00241 header.type = buffer_nu8_read(&record->buffer); 00242 header.version.major = buffer_nu8_read(&record->buffer); 00243 header.version.minor = buffer_nu8_read(&record->buffer); 00244 header.length = buffer_nu16_read(&record->buffer); 00245 00246 #if 1 //TODO how to relax this? 00247 if( (header.version.major != record->version.major) || (header.version.minor != record->version.minor) ) 00248 { 00249 ERR("Version mismatch"); 00250 tls_alert_send( record, TLS_ALERT_FATAL, PROTOCOL_VERSION, &record->buffer); 00251 return MINITLS_ERR_PROTOCOL_VERSION; 00252 } 00253 #endif 00254 //Check content type 00255 //Check that encryption level is OK for this content type 00256 switch( header.type ) 00257 { 00258 //All of these are OK in plain mode 00259 case TLS_CHANGE_CIPHER_SPEC: 00260 case TLS_ALERT: 00261 case TLS_HANDSHAKE: 00262 break; 00263 //This is only acceptable in ciphered mode: 00264 case TLS_APPLICATION_DATA: 00265 if( (!tls_record_is_secure(record)) || (!record->handshake_done) ) 00266 { 00267 tls_alert_send( record, TLS_ALERT_FATAL, INSUFFICIENT_SECURITY, &record->buffer); 00268 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; 00269 } 00270 break; 00271 default: 00272 tls_alert_send( record, TLS_ALERT_FATAL, ILLEGAL_PARAMETER, &record->buffer); 00273 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; 00274 } 00275 00276 //Reset buffer 00277 buffer_reset(&record->buffer); 00278 00279 //Read payload 00280 ret = record_socket_read(record, header.length); 00281 if(ret) 00282 { 00283 ERR("Socket err %d", ret); 00284 tls_alert_send( record, TLS_ALERT_FATAL, INTERNAL_ERROR, &record->buffer); 00285 return ret; 00286 } 00287 00288 if( record->security_rx_state == TLS_SECURITY_ACTIVE ) 00289 { 00290 00291 #if CRYPTO_AES_128 00292 if(record->security_type == TLS_SECURITY_TYPE_AES_128_CBC_SHA) 00293 { 00294 DBG("IV + Ciphertext"); 00295 DBG_BLOCK(buffer_dump(&record->buffer);) 00296 00297 buffer_t buffer_iv_header; 00298 if( (buffer_length(&record->buffer) < 2*AES_128_BLOCK_SIZE) || ( (buffer_length(&record->buffer) % AES_128_BLOCK_SIZE) != 0 ) ) 00299 { 00300 tls_alert_send( record, TLS_ALERT_FATAL, UNEXPECTED_MESSAGE, &record->buffer ); 00301 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; 00302 } 00303 buffer_byref(&buffer_iv_header, buffer_current_read_position(&record->buffer), AES_128_BLOCK_SIZE); //Extract IV vector 00304 buffer_n_discard(&record->buffer, AES_128_BLOCK_SIZE); 00305 00306 //Decrypt message 00307 ret = crypto_aes_128_cbc_decrypt( &record->cipher_rx.aes_128, &buffer_iv_header, &record->buffer ); 00308 if(ret) 00309 { 00310 ERR("Failed to decipher, ret %d", ret); 00311 tls_alert_send( record, TLS_ALERT_FATAL, DECRYPT_ERROR, &record->buffer ); 00312 return ret; 00313 } 00314 00315 DBG("Plaintext + MAC + padding + padding length"); 00316 DBG_BLOCK(buffer_dump(&record->buffer);) 00317 00318 //Check and remove padding 00319 size_t padding_length = *(buffer_current_write_position(&record->buffer) - 1); 00320 00321 if( padding_length + 1 > buffer_length(&record->buffer) ) 00322 { 00323 ERR("Wrong padding length"); 00324 tls_alert_send( record, TLS_ALERT_FATAL, BAD_RECORD_MAC, &record->buffer ); 00325 return MINITLS_ERR_CRYPTO; 00326 } 00327 00328 int p; 00329 //Check each padding byte 00330 for(p = 0; p < padding_length; p++) 00331 { 00332 if( *(buffer_current_write_position(&record->buffer) - 1 - p) != padding_length ) 00333 { 00334 ERR("Wrong padding"); 00335 tls_alert_send( record, TLS_ALERT_FATAL, BAD_RECORD_MAC, &record->buffer ); 00336 return MINITLS_ERR_CRYPTO; 00337 } 00338 } 00339 00340 //Remove trailing padding + padding length 00341 buffer_set_length(&record->buffer, buffer_length(&record->buffer) - 1 - padding_length); 00342 } 00343 else 00344 #endif 00345 #if CRYPTO_ARC4 00346 if(record->security_type == TLS_SECURITY_TYPE_ARC4_SHA) 00347 { 00348 DBG("Ciphertext"); 00349 DBG_BLOCK(buffer_dump(&record->buffer);) 00350 00351 //Decrypt message 00352 crypto_arc4_process( &record->cipher_rx.arc4, &record->buffer ); 00353 } 00354 else 00355 #endif 00356 {} 00357 00358 DBG("Plaintext + MAC"); 00359 DBG_BLOCK(buffer_dump(&record->buffer);) 00360 00361 //Check MAC 00362 ret = tls_mac_check( record->server_write_mac_key, header.type, header.version, record->sequence_number_rx, &record->buffer ); 00363 if(ret) 00364 { 00365 ERR("MAC Check failed, ret %d", ret); 00366 tls_alert_send( record, TLS_ALERT_FATAL, BAD_RECORD_MAC, &record->buffer ); 00367 return ret; 00368 } 00369 00370 DBG("Plaintext"); 00371 DBG_BLOCK(buffer_dump(&record->buffer);) 00372 00373 //Increment seq number 00374 record->sequence_number_rx++; 00375 } 00376 else 00377 { 00378 //No security 00379 } 00380 00381 //Now dispatch depending on content type 00382 switch( header.type ) 00383 { 00384 case TLS_CHANGE_CIPHER_SPEC: 00385 ret = tls_record_change_cipher_spec(record, false); 00386 if(ret) 00387 { 00388 ERR("Invalid change cipher spec request, ret %d", ret); 00389 tls_alert_send( record, TLS_ALERT_FATAL, UNEXPECTED_MESSAGE, &record->buffer ); 00390 return ret; 00391 } 00392 break; 00393 case TLS_ALERT: 00394 ret = tls_alert_process( record, &record->buffer ); 00395 if(ret) 00396 { 00397 tls_record_close(record); 00398 //Close connection in any case 00399 if(ret == MINITLS_ERR_CONNECTION_CLOSED) 00400 { 00401 DBG("Connection closed by remote party"); 00402 return MINITLS_OK; 00403 } 00404 //FIXME Do something 00405 ERR("Alert received, ret %d", ret); 00406 return ret; 00407 } 00408 break; 00409 case TLS_HANDSHAKE: 00410 if(/*(record->tls_socket->handshake != NULL) &&*/ !tls_handshake_is_done(&record->tls_socket->handshake)) 00411 { 00412 ret = tls_handshake_process(&record->tls_socket->handshake, &record->buffer ); 00413 if(ret) 00414 { 00415 ERR("Handshake process returned %d", ret); 00416 //TLS alert already sent by handshake function 00417 tls_handshake_clean(&record->tls_socket->handshake); //Cleanup handshake 00418 //record->tls_socket->handshake = NULL; 00419 return ret; 00420 } 00421 if(tls_handshake_is_done(&record->tls_socket->handshake)) 00422 { 00423 tls_handshake_clean(&record->tls_socket->handshake); //Cleanup handshake 00424 //record->tls_socket->handshake = NULL; 00425 record->handshake_done = true; //Enable application data layer 00426 } 00427 return MINITLS_OK; 00428 } 00429 else 00430 { 00431 ERR("Unexpected handshake message, ret %d", ret); 00432 tls_alert_send( record, TLS_ALERT_FATAL, UNEXPECTED_MESSAGE, &record->buffer ); 00433 return ret; 00434 } 00435 case TLS_APPLICATION_DATA: 00436 //Pass message to socket layer 00437 return tls_socket_readable_callback(record->tls_socket, &record->buffer); 00438 default: 00439 //Has already been checked above 00440 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; 00441 } 00442 00443 return MINITLS_OK; 00444 } 00445 00446 minitls_err_t tls_record_send(tls_record_t* record, tls_content_type_t content_type, buffer_t* payload) 00447 { 00448 minitls_err_t ret; 00449 int padding_item; 00450 /* 00451 struct { 00452 opaque IV[SecurityParameters.record_iv_length]; 00453 block-ciphered struct { 00454 opaque content[TLSCompressed.length]; 00455 opaque MAC[SecurityParameters.mac_length]; 00456 uint8 padding[GenericBlockCipher.padding_length]; 00457 uint8 padding_length; 00458 }; 00459 } GenericBlockCipher; 00460 */ 00461 00462 //Check content type 00463 //Check that encryption level is OK for this content type 00464 switch( content_type ) 00465 { 00466 //All of these are OK in plain mode 00467 case TLS_CHANGE_CIPHER_SPEC: 00468 case TLS_ALERT: 00469 case TLS_HANDSHAKE: 00470 break; 00471 //This is only acceptable in ciphered mode: 00472 case TLS_APPLICATION_DATA: 00473 if( (!tls_record_is_secure(record)) || (!record->handshake_done) ) 00474 { 00475 tls_alert_send( record, TLS_ALERT_FATAL, INSUFFICIENT_SECURITY, &record->buffer); 00476 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; 00477 } 00478 break; 00479 default: 00480 tls_alert_send( record, TLS_ALERT_FATAL, ILLEGAL_PARAMETER, &record->buffer); 00481 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; 00482 } 00483 00484 //Buffer must have enough space to add IV (head) + MAC (tail) + padding (tail) 00485 00486 buffer_t header_iv; 00487 uint8_t header_iv_data[AES_128_BLOCK_SIZE]; 00488 if( record->security_tx_state == TLS_SECURITY_ACTIVE ) 00489 { 00490 //FIXME generate a random IV 00491 00492 DBG("Plaintext"); 00493 DBG_BLOCK(buffer_dump(payload);) 00494 00495 //Compute & append MAC 00496 DBG("Sequence number: %d", record->sequence_number_tx); 00497 ret = tls_mac_append( record->client_write_mac_key, content_type, record->version, record->sequence_number_tx, payload ); 00498 if(ret) 00499 { 00500 ERR("Could not append MAC, ret %d", ret); 00501 return ret; 00502 } 00503 00504 //Increment sequence number 00505 record->sequence_number_tx++; 00506 00507 DBG("Plaintext + MAC"); 00508 DBG_BLOCK(buffer_dump(payload);) 00509 00510 #if CRYPTO_AES_128 00511 if(record->security_type == TLS_SECURITY_TYPE_AES_128_CBC_SHA) 00512 { 00513 00514 //Add padding 00515 size_t padding_length = AES_128_BLOCK_SIZE - (buffer_length(payload) % AES_128_BLOCK_SIZE) - 1; 00516 if(buffer_space(payload) < padding_length) 00517 { 00518 return MINITLS_ERR_BUFFER_TOO_SMALL; 00519 } 00520 00521 for(padding_item = 0; padding_item < padding_length; padding_item++) 00522 { 00523 buffer_nu8_write(payload, padding_length); 00524 } 00525 00526 buffer_nu8_write(payload, padding_length); 00527 00528 DBG("Plaintext + MAC + Padding + Padding Length"); 00529 DBG_BLOCK(buffer_dump(payload);) 00530 00531 buffer_init( &header_iv, header_iv_data, AES_128_BLOCK_SIZE ); 00532 00533 crypto_prng_get(record->tls_socket->minitls->prng, buffer_current_write_position(&header_iv), AES_128_BLOCK_SIZE); 00534 buffer_n_skip(&header_iv, AES_128_BLOCK_SIZE); 00535 00536 //Encrypt message 00537 ret = crypto_aes_128_cbc_encrypt( &record->cipher_tx.aes_128, &header_iv, payload ); 00538 if(ret) 00539 { 00540 ERR("Failed to encipher, ret %d", ret); 00541 return ret; 00542 } 00543 } 00544 else 00545 #endif 00546 #if CRYPTO_ARC4 00547 if(record->security_type == TLS_SECURITY_TYPE_ARC4_SHA) 00548 { 00549 //No IV 00550 buffer_init( &header_iv, NULL, 0 ); //0 Length 00551 00552 //Encrypt message 00553 crypto_arc4_process( &record->cipher_tx.arc4, payload ); 00554 } 00555 else 00556 #endif 00557 {} 00558 00559 DBG("Ciphertext"); 00560 DBG_BLOCK(buffer_dump(payload);) 00561 } 00562 else 00563 { 00564 buffer_init( &header_iv, NULL, 0 ); //0 Length 00565 } 00566 00567 //Now send message header 00568 tls_fragment_header_t header; 00569 header.type = content_type; 00570 header.version.major = record->version.major; 00571 header.version.minor = record->version.minor; 00572 header.length = buffer_length( &header_iv ) + buffer_length(payload); 00573 00574 buffer_t header_fragment; 00575 uint8_t header_fragment_data[FRAGMENT_HEADER_SIZE]; 00576 00577 buffer_init( &header_fragment, header_fragment_data, FRAGMENT_HEADER_SIZE ); 00578 00579 buffer_nu8_write(&header_fragment, header.type); 00580 buffer_nu8_write(&header_fragment, header.version.major); 00581 buffer_nu8_write(&header_fragment, header.version.minor); 00582 buffer_nu16_write(&header_fragment, header.length); 00583 00584 //Send fragment header 00585 ret = record_socket_write(record, &header_fragment); 00586 if(ret) 00587 { 00588 return ret; 00589 } 00590 00591 //Send IV 00592 ret = record_socket_write(record, &header_iv); 00593 if(ret) 00594 { 00595 return ret; 00596 } 00597 00598 //Send payload 00599 ret = record_socket_write(record, payload); 00600 if(ret) 00601 { 00602 return ret; 00603 } 00604 00605 return MINITLS_OK; 00606 } 00607 00608 minitls_err_t tls_record_set_keys(tls_record_t* record, tls_security_type_t security, const uint8_t* client_write_mac_key, const uint8_t* server_write_mac_key, 00609 const uint8_t* client_write_cipher_key, const uint8_t* server_write_cipher_key) 00610 { 00611 if( (security != TLS_SECURITY_TYPE_AES_128_CBC_SHA) && (security != TLS_SECURITY_TYPE_ARC4_SHA) ) 00612 { 00613 return MINITLS_ERR_NOT_IMPLEMENTED; 00614 } 00615 00616 //Copy keys 00617 memcpy(&record->client_write_mac_key, client_write_mac_key, TLS_HMAC_SHA1_KEY_SIZE); 00618 memcpy(&record->server_write_mac_key, server_write_mac_key, TLS_HMAC_SHA1_KEY_SIZE); 00619 memcpy(&record->client_write_cipher_key, client_write_cipher_key, AES_128_KEY_SIZE); //TODO generic key size 00620 memcpy(&record->server_write_cipher_key, server_write_cipher_key, AES_128_KEY_SIZE); 00621 00622 //Intialize cipher 00623 00624 record->sequence_number_tx = 0; 00625 record->sequence_number_rx = 0; 00626 00627 switch(security) 00628 { 00629 #if CRYPTO_AES_128 00630 case TLS_SECURITY_TYPE_AES_128_CBC_SHA: 00631 crypto_aes_128_init(&record->cipher_tx.aes_128, record->client_write_cipher_key, expand_encryption_key); 00632 crypto_aes_128_init(&record->cipher_rx.aes_128, record->server_write_cipher_key, expand_decryption_key); 00633 break; 00634 #endif 00635 #if CRYPTO_ARC4 00636 case TLS_SECURITY_TYPE_ARC4_SHA: 00637 crypto_arc4_init(&record->cipher_tx.arc4, record->client_write_cipher_key, TLS_ARC4_KEY_SIZE ); 00638 crypto_arc4_init(&record->cipher_rx.arc4, record->server_write_cipher_key, TLS_ARC4_KEY_SIZE); 00639 break; 00640 #endif 00641 default: 00642 break; 00643 } 00644 00645 record->security_tx_state = TLS_SECURITY_INTIALIZED; 00646 record->security_rx_state = TLS_SECURITY_INTIALIZED; 00647 record->security_type = security; 00648 00649 return MINITLS_OK; 00650 } 00651 00652 minitls_err_t tls_record_close(tls_record_t* record) 00653 { 00654 if(record->socket_fd < 0) //Already closed 00655 { 00656 return MINITLS_OK; 00657 } 00658 00659 //Don't really care about the return 00660 tls_alert_send(record, TLS_ALERT_WARNING, CLOSE_NOTIFY, &record->buffer); 00661 00662 //Close socket 00663 socket_close(record->socket_fd); 00664 record->socket_fd = -1; 00665 00666 return MINITLS_OK; 00667 } 00668 00669 minitls_err_t tls_record_set_read_timeout(tls_record_t* record, int timeout) 00670 { 00671 record->read_timeout = timeout; 00672 00673 return MINITLS_OK; 00674 } 00675 00676 minitls_err_t tls_record_set_write_timeout(tls_record_t* record, int timeout) 00677 { 00678 record->write_timeout = timeout; 00679 00680 return MINITLS_OK; 00681 } 00682 00683 minitls_err_t record_wait_readable(tls_record_t* record) 00684 { 00685 if(record->socket_fd < 0) 00686 { 00687 return MINITLS_ERR_SOCKET_CLOSED; 00688 } 00689 00690 //Wait for record to be readable 00691 int ret = socket_wait_readable(record->socket_fd, record->read_timeout ); 00692 if( ret < 0 ) 00693 { 00694 //Timeout 00695 return MINITLS_ERR_TIMEOUT; 00696 } 00697 return MINITLS_OK; 00698 } 00699 00700 minitls_err_t record_wait_writeable(tls_record_t* record) 00701 { 00702 if(record->socket_fd < 0) 00703 { 00704 return MINITLS_ERR_SOCKET_CLOSED; 00705 } 00706 00707 //Wait for record to be writeable 00708 int ret = socket_wait_writeable(record->socket_fd, record->write_timeout ); 00709 if( ret < 0 ) 00710 { 00711 //Timeout 00712 return MINITLS_ERR_TIMEOUT; 00713 } 00714 return MINITLS_OK; 00715 } 00716 00717 minitls_err_t record_socket_read(tls_record_t* record, size_t size) 00718 { 00719 minitls_err_t ret; 00720 if(record->socket_fd < 0) 00721 { 00722 return MINITLS_ERR_SOCKET_CLOSED; 00723 } 00724 00725 DBG("Trying to read %d bytes", size); 00726 while(size > 0) 00727 { 00728 //Read Fragment length 00729 if( buffer_space(&record->buffer) < size ) 00730 { 00731 ERR("Won't be able to read packet (%d bytes to read - %d bytes of space)", size, buffer_space(&record->buffer)); 00732 return MINITLS_ERR_BUFFER_TOO_SMALL; 00733 } 00734 00735 ret = record_wait_readable(record); 00736 if(ret) 00737 { 00738 ERR("Timeout"); 00739 return ret; 00740 } 00741 00742 int count = socket_recv(record->socket_fd, buffer_current_write_position(&record->buffer), size /*- buffer_length(&record->buffer)*/); 00743 if( count > 0 ) 00744 { 00745 buffer_n_skip(&record->buffer, count); 00746 size -= count; 00747 } 00748 else if( count == 0 ) 00749 { 00750 WARN("Socket closed"); 00751 return MINITLS_ERR_SOCKET_CLOSED; 00752 } 00753 else 00754 { 00755 ERR("Error (returned %d)", count); 00756 return MINITLS_ERR_SOCKET_ERROR; 00757 } 00758 } 00759 00760 DBG_BLOCK(buffer_dump(&record->buffer);) 00761 00762 return MINITLS_OK; 00763 } 00764 00765 minitls_err_t record_socket_write(tls_record_t* record, buffer_t* data) 00766 { 00767 minitls_err_t ret; 00768 if(record->socket_fd < 0) 00769 { 00770 return MINITLS_ERR_SOCKET_CLOSED; 00771 } 00772 00773 DBG("Trying to write %d bytes", buffer_length(data)); 00774 DBG_BLOCK(buffer_dump(data);) 00775 while(buffer_length(data) > 0) 00776 { 00777 ret = record_wait_writeable(record); 00778 if(ret) 00779 { 00780 ERR("Timeout"); 00781 return ret; 00782 } 00783 00784 int count = socket_send(record->socket_fd, buffer_current_read_position(data), buffer_length(data)); 00785 if( count > 0 ) 00786 { 00787 buffer_n_discard(data, count); 00788 } 00789 else if( count == 0 ) 00790 { 00791 WARN("Socket closed"); 00792 return MINITLS_ERR_SOCKET_CLOSED; 00793 } 00794 else 00795 { 00796 ERR("Error (returned %d)", count); 00797 return MINITLS_ERR_SOCKET_ERROR; 00798 } 00799 } 00800 DBG("Done"); 00801 return MINITLS_OK; 00802 } 00803 00804 00805 minitls_err_t tls_mac_append( const uint8_t* key, tls_content_type_t content_type, tls_protocol_version_t version, 00806 uint64_t sequence_number, buffer_t* buffer ) 00807 { 00808 crypto_hmac_sha1_t mac; 00809 crypto_hmac_sha1_init(&mac, key, TLS_HMAC_SHA1_KEY_SIZE); 00810 00811 if( buffer_space(buffer) < HMAC_SHA1_SIZE ) 00812 { 00813 return MINITLS_ERR_BUFFER_TOO_SMALL; 00814 } 00815 00816 uint8_t header_buf[13]; 00817 buffer_t header; 00818 00819 buffer_init(&header, header_buf, 13); 00820 00821 buffer_nu64_write(&header, sequence_number); 00822 00823 buffer_nu8_write(&header, content_type); 00824 00825 buffer_nu8_write(&header, version.major); 00826 buffer_nu8_write(&header, version.minor); 00827 00828 buffer_nu16_write(&header, buffer_length(buffer)); 00829 00830 crypto_hmac_sha1_update(&mac, header_buf, 13); 00831 crypto_hmac_sha1_update(&mac, buffer_current_read_position(buffer), buffer_length(buffer)); 00832 crypto_hmac_sha1_end(&mac, buffer_current_write_position(buffer)); 00833 buffer_n_skip(buffer, HMAC_SHA1_SIZE); 00834 00835 return MINITLS_OK; 00836 } 00837 00838 minitls_err_t tls_mac_check( const uint8_t* key, tls_content_type_t content_type, tls_protocol_version_t version, 00839 uint64_t sequence_number, buffer_t* buffer ) 00840 { 00841 crypto_hmac_sha1_t mac; 00842 crypto_hmac_sha1_init(&mac, key, TLS_HMAC_SHA1_KEY_SIZE); 00843 00844 if( buffer_length(buffer) < HMAC_SHA1_SIZE ) 00845 { 00846 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; 00847 } 00848 00849 size_t data_offset = buffer_get_read_offset(buffer); 00850 size_t data_length = buffer_length(buffer) - HMAC_SHA1_SIZE; 00851 00852 uint8_t check[HMAC_SHA1_SIZE]; 00853 00854 uint8_t header_buf[13]; 00855 buffer_t header; 00856 00857 buffer_init(&header, header_buf, 13); 00858 00859 buffer_nu64_write(&header, sequence_number); 00860 00861 buffer_nu8_write(&header, content_type); 00862 00863 buffer_nu8_write(&header, version.major); 00864 buffer_nu8_write(&header, version.minor); 00865 00866 buffer_nu16_write(&header, data_length); 00867 00868 crypto_hmac_sha1_update(&mac, header_buf, 13); 00869 crypto_hmac_sha1_update(&mac, buffer_current_read_position(buffer), data_length); 00870 buffer_n_discard(buffer, data_length); 00871 crypto_hmac_sha1_end(&mac, check); 00872 00873 if( memcmp(buffer_current_read_position(buffer), check, HMAC_SHA1_SIZE) != 0 ) 00874 { 00875 ERR("MAC differs; computed MAC was:"); 00876 00877 buffer_t computed_mac; 00878 buffer_byref(&computed_mac, check, HMAC_SHA1_SIZE); 00879 DBG_BLOCK(buffer_dump(&computed_mac);) 00880 00881 return MINITLS_ERR_WRONG_MAC; 00882 } 00883 00884 //Reset buffer position and discard MAC 00885 buffer_set_read_offset(buffer, data_offset); 00886 buffer_set_length(buffer, data_length); 00887 00888 return MINITLS_OK; 00889 } 00890 00891 00892 00893
Generated on Tue Jul 12 2022 19:20:10 by
1.7.2
