BOOL HAL_CONFIG_BLOCK::IsGoodData() const { DEBUG_TRACE1( TRACE_CONFIG, "read Size=%5d\r\n", Size ); // what is the blob's CRC UINT32 CRC = SUPPORT_ComputeCRC( Data(), Size, 0 ); DEBUG_TRACE1( TRACE_CONFIG, "calc blob CRC=0x%08x\r\n", CRC ); // this indicates that this record has been marked as invalid, but still allows the helper to move // to the next record. if(CRC != DataCRC) { return FALSE; } return TRUE; }
UINT32 Stack_MaxUsed() { // this is the value we check for stack overruns const UINT32 StackCheckVal = 0xBAADF00D; size_t size = (size_t)&StackTop - (size_t)&StackBottom; UINT32* ptr = (UINT32*)&StackBottom; DEBUG_TRACE1(TRACE_ALWAYS, "Stack Max = %d\r\n", size); while(*ptr == StackCheckVal) { size -= 4; ptr++; } DEBUG_TRACE1(TRACE_ALWAYS, "Stack Used = %d\r\n", size); return size; }
int ssls_decode_master_secret( DSSL_Session* sess ) { EVP_MD *md; DSSL_CipherSuite* suite = NULL; switch( sess->version ) { case SSL3_VERSION: return ssl3_PRF( sess->PMS, SSL_MAX_MASTER_KEY_LENGTH, sess->client_random, SSL3_RANDOM_SIZE, sess->server_random, SSL3_RANDOM_SIZE, sess->master_secret, sizeof( sess->master_secret ) ); case TLS1_VERSION: return tls1_PRF( sess->PMS, SSL_MAX_MASTER_KEY_LENGTH, "master secret", sess->client_random, SSL3_RANDOM_SIZE, sess->server_random, SSL3_RANDOM_SIZE, sess->master_secret, sizeof( sess->master_secret ) ); default: DEBUG_TRACE1("ssls_decode_master_secret - version: 0x%02X\n", sess->version); if (sess->version == TLS1_1_VERSION) { DEBUG_TRACE0("ssls_decode_master_secret - supported for 1.1\n"); return tls1_PRF( sess->PMS, SSL_MAX_MASTER_KEY_LENGTH, "master secret", sess->client_random, SSL3_RANDOM_SIZE, sess->server_random, SSL3_RANDOM_SIZE, sess->master_secret, sizeof( sess->master_secret ) ); } else if (sess->version == TLS1_2_VERSION) { DEBUG_TRACE0("ssls_decode_master_secret - supported for 1.2\n"); /* suite = DSSL_GetSSL3CipherSuite( sess->cipher_suite ); md=EVP_get_digestbyname(suite->digest); */ return tls12_PRF( "SHA256"/*suite->digest*/, sess->PMS, SSL_MAX_MASTER_KEY_LENGTH, "master secret", sess->client_random, SSL3_RANDOM_SIZE, sess->server_random, SSL3_RANDOM_SIZE, sess->master_secret, sizeof( sess->master_secret ) ); } else { DEBUG_TRACE0("ssls_decode_master_secret - DSSL_E_NOT_IMPL\n"); return NM_ERROR( DSSL_E_NOT_IMPL ); } } }
BOOL HAL_CONFIG_BLOCK::IsGoodBlock() const { if(Signature != c_Version_V2) { return FALSE; } DEBUG_TRACE2( TRACE_CONFIG, "read header CRC=0x%08x at %08x\r\n", HeaderCRC, (size_t)this ); // what is the header's CRC UINT32 CRC = SUPPORT_ComputeCRC( ((UINT8*)&DataCRC), sizeof(*this) - offsetof(HAL_CONFIG_BLOCK,DataCRC), c_Seed ); DEBUG_TRACE1(TRACE_CONFIG, "calc header CRC=0x%08x\r\n", CRC); if(CRC != HeaderCRC) { DEBUG_TRACE3( TRACE_ALWAYS, "FAILED HEADER CRC at %08x: 0x%08x != 0x%08x\r\n", (size_t)this, CRC, HeaderCRC ); return FALSE; } return TRUE; }
int ssl3_record_layer_decoder( void* decoder_stack, NM_PacketDir dir, u_char* data, uint32_t len, uint32_t* processed ) { int rc = DSSL_E_UNSPECIFIED_ERROR; uint32_t recLen = 0, totalRecLen = 0; uint8_t record_type = 0; dssl_decoder_stack* stack = (dssl_decoder_stack*) decoder_stack; dssl_decoder* next_decoder = NULL; int decrypt_buffer_aquired = 0; int decompress_buffer_aquired = 0; _ASSERT( stack ); _ASSERT( processed ); _ASSERT( stack->sess ); if( stack->state > SS_Established ) { #ifdef NM_TRACE_SSL_RECORD DEBUG_TRACE1( "[!]Unexpected SSL record after %s", ( (stack->state == SS_FatalAlert) ? "fatal alert" : "close_notify alert") ); #endif return NM_ERROR( DSSL_E_SSL_UNEXPECTED_TRANSMISSION ); } /* special case for a first client hello */ if( stack->sess->version == 0 ) { _ASSERT( dir == ePacketDirFromClient ); rc = ssl_decode_first_client_hello( stack->sess, data, len, processed ); return rc; } if( len < SSL3_HEADER_LEN ) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); if( data[1] != 3) return NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR ); /* Decode record type */ record_type = data[0]; totalRecLen = recLen = MAKE_UINT16( data[3], data[4] ); data += SSL3_HEADER_LEN; len -= SSL3_HEADER_LEN; #ifdef NM_TRACE_SSL_RECORD DEBUG_TRACE3( "\n==>Decoding SSL v3 Record from %s, type: %d, len: %d\n{\n", ((dir == ePacketDirFromClient)?"client":"server"), (int) record_type, (int) recLen ); #endif rc = DSSL_RC_OK; if( len < recLen ) { rc = DSSL_RC_WOULD_BLOCK; } if( rc == DSSL_RC_OK && stack->cipher ) { rc = ssl_decrypt_record( stack, data, recLen, &data, &recLen, &decrypt_buffer_aquired ); } /* check if the record length is still within bounds (failed decryption, etc) */ if( rc == DSSL_RC_OK && (recLen > RFC_2246_MAX_COMPRESSED_LENGTH || recLen > len || (stack->sess->version < TLS1_2_VERSION && stack->md && recLen < EVP_MD_size(stack->md))) ) { rc = NM_ERROR(DSSL_E_SSL_INVALID_RECORD_LENGTH); } if( rc == DSSL_RC_OK && stack->md ) { u_char mac[EVP_MAX_MD_SIZE*2]; u_char* rec_mac = NULL; int l = EVP_MD_size( stack->md ); int ivl = EVP_CIPHER_iv_length( stack->cipher->cipher ); if ( EVP_CIPH_CBC_MODE == stack->sess->cipher_mode || EVP_CIPH_STREAM_CIPHER == stack->sess->cipher_mode ) recLen -= l; rec_mac = data+recLen; memset(mac, 0, sizeof(mac) ); /* TLS 1.1 and later: remove explicit IV for non-stream ciphers */ if ( EVP_CIPH_CBC_MODE == stack->sess->cipher_mode ) { if (stack->sess->version >= TLS1_1_VERSION ) { if (ivl <= recLen) { recLen -= ivl; data += ivl; } } } /* AEAD ciphers have no mac */ if ( EVP_CIPH_CBC_MODE == stack->sess->cipher_mode || EVP_CIPH_STREAM_CIPHER == stack->sess->cipher_mode ) { rc = stack->sess->caclulate_mac_proc( stack, record_type, data, recLen, mac ); if( rc == DSSL_RC_OK ) { rc = memcmp( mac, rec_mac, l ) == 0 ? DSSL_RC_OK : NM_ERROR( DSSL_E_SSL_INVALID_MAC ); } } } if( rc == DSSL_RC_OK && stack->compression_method != 0 ) { rc = ssl_decompress_record( stack, data, recLen, &data, &recLen, &decompress_buffer_aquired ); } DEBUG_TRACE_BUF("decompressed", data, recLen); if( rc == DSSL_RC_OK ) { switch( record_type ) { case SSL3_RT_HANDSHAKE: next_decoder = &stack->dhandshake; break; case SSL3_RT_CHANGE_CIPHER_SPEC: next_decoder = &stack->dcss; break; case SSL3_RT_APPLICATION_DATA: next_decoder = &stack->dappdata; break; case SSL3_RT_ALERT: next_decoder = &stack->dalert; break; default: rc = NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR ); } } if( rc == DSSL_RC_OK ) { _ASSERT( next_decoder != NULL ); rc = dssl_decoder_process( next_decoder, dir, data, recLen ); } if( rc == DSSL_RC_OK ) { *processed = totalRecLen + SSL3_HEADER_LEN; } if( decrypt_buffer_aquired ) { ssls_release_decrypt_buffer( stack->sess ); } if( decompress_buffer_aquired ) { ssls_release_decompress_buffer( stack->sess ); } #ifdef NM_TRACE_SSL_RECORD DEBUG_TRACE1( "\n} rc: %d\n", (int) rc); #endif if( stack->state == SS_SeenCloseNotify ) { stack->sess->flags |= SSF_CLOSE_NOTIFY_RECEIVED; } else if ( stack->state == SS_FatalAlert ) { stack->sess->flags |= SSF_FATAL_ALERT_RECEIVED; } return rc; }
static int ssl_decrypt_record( dssl_decoder_stack* stack, u_char* data, uint32_t len, u_char** out, uint32_t* out_len, int *buffer_aquired,int *block_size ) { u_char* buf = NULL; uint32_t buf_len = len; int rc = DSSL_RC_OK; const EVP_CIPHER* c = NULL; int func_ret = 0; int i = 0; DEBUG_TRACE3("ssl_decrypt_record - len: %d, out_len: %d, buffer_aquired: %d\n", len, *out_len, buffer_aquired); _ASSERT( stack ); _ASSERT( stack->sess ); _ASSERT( stack->cipher ); rc = ssls_get_decrypt_buffer( stack->sess, &buf, buf_len ); DEBUG_TRACE1("ssl_decrypt_record - calling ssls_get_decrypt_buffer ended. ret: %d\n", rc); // test //memset(buf, 0x77, DSSL_MAX_COMPRESSED_LENGTH); /* for (i = 0; i < 128; i++) { printf("ssl_decrypt_record(1) - buf[%d]: 0x%02X, data: 0x%02X\n", i, buf[i], data[i]); } */ if( rc != DSSL_RC_OK ) return rc; *buffer_aquired = 1; c = EVP_CIPHER_CTX_cipher( stack->cipher ); *block_size = EVP_CIPHER_block_size( c ); DEBUG_TRACE1("ssl_decrypt_record - calling EVP_CIPHER_block_size ended. ret: %d\n", *block_size); if( *block_size != 1 ) { if( len == 0 || (len % *block_size) != 0 ) { DEBUG_TRACE0("ssl_decrypt_record - DSSL_E_SSL_DECRYPTION_ERROR(after EVP_CIPHER_block_size)\n"); return NM_ERROR( DSSL_E_SSL_DECRYPTION_ERROR ); } } func_ret = EVP_Cipher(stack->cipher, buf, data, len ); DEBUG_TRACE1("ssl_decrypt_record - calling EVP_Cipher ret: %d\n", func_ret); buf_len = len; DEBUG_TRACE1("ssl_decrypt_record - buf_len: %d\n", buf_len); /* for (i = 0; i < 128; i++) { printf("ssl_decrypt_record(2) - buf[%d]: 0x%02X, data: 0x%02X\n", i, buf[i], data[i]); } */ /* strip the padding */ if( *block_size > 1 ) { if( buf[len-1] >= buf_len - 1 ) { DEBUG_TRACE0("ssl_decrypt_record - DSSL_E_SSL_DECRYPTION_ERROR(after EVP_Cipher)\n"); return NM_ERROR( DSSL_E_SSL_DECRYPTION_ERROR ); } buf_len -= buf[len-1] + 1; } *out = buf; *out_len = buf_len; return DSSL_RC_OK; }
int ssl3_record_layer_decoder( void* decoder_stack, NM_PacketDir dir, u_char* data, uint32_t len, uint32_t* processed ) { int rc = DSSL_E_UNSPECIFIED_ERROR; uint32_t recLen = 0, totalRecLen = 0; uint8_t record_type = 0; dssl_decoder_stack* stack = (dssl_decoder_stack*) decoder_stack; dssl_decoder* next_decoder = NULL; int decrypt_buffer_aquired = 0; int decompress_buffer_aquired = 0; int i = 0; char * data2 = NULL; uint32_t recLen2 = 0; int block_size = 0; DEBUG_TRACE1("ssl_record_layer_decoder - start. len: %d\n", len); _ASSERT( stack ); _ASSERT( processed ); _ASSERT( stack->sess ); /* for (i=0; i < len; i++) { printf("0x%02X ", data[i]); } */ if( stack->state > SS_Established ) { #ifdef NM_TRACE_SSL_RECORD DEBUG_TRACE1( "[!]Unexpected SSL record after %s", ( (stack->state == SS_FatalAlert) ? "fatal alert" : "close_notify alert") ); #endif return NM_ERROR( DSSL_E_SSL_UNEXPECTED_TRANSMISSION ); } /* special case for a first client hello */ DEBUG_TRACE1("ssl_record_layer_decoder - version: 0x%02X\n", stack->sess->version); if( stack->sess->version == 0 ) { _ASSERT( dir == ePacketDirFromClient ); rc = ssl_decode_first_client_hello( stack->sess, data, len, processed ); return rc; } if( len < SSL3_HEADER_LEN ) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); if( data[1] != 3) return NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR ); /* Decode record type */ record_type = data[0]; totalRecLen = recLen = MAKE_UINT16( data[3], data[4] ); DEBUG_TRACE1("ssl_record_layer_decoder - record_type: %d\n", record_type); DEBUG_TRACE1("ssl_record_layer_decoder - recLen: %d\n", recLen); /* for (i = 0; i < 128; i++) { printf("ssl_tls_record_layer_decoder - data before skip header size [%d]: %d\n", i, data[i]); } */ data += SSL3_HEADER_LEN; len -= SSL3_HEADER_LEN; DEBUG_TRACE1("ssl_record_layer_decoder - len after header adjustments: %d\n", len); /* for (i=0; i < len; i++) { printf("0x%02X ", data[i]); } */ #ifdef NM_TRACE_SSL_RECORD DEBUG_TRACE2( "\n==>Decoding SSL v3 Record, type: %d, len: %d\n{\n", (int) record_type, (int) recLen ); #endif rc = DSSL_RC_OK; if( len < recLen ) { rc = DSSL_RC_WOULD_BLOCK; DEBUG_TRACE0("ssl_tls_record_layer_decoder - rc is DSSL_RC_WOULD_BLOCK\n"); } if( rc == DSSL_RC_OK && stack->cipher ) { rc = ssl_decrypt_record( stack, data, recLen, &data, &recLen, &decrypt_buffer_aquired,&block_size ); DEBUG_TRACE1("ssl_record_layer_decoder - ssl_decrypt_record ret: %d\n", rc); } /* check if the record length is still within bounds (failed decryption, etc) */ if( rc == DSSL_RC_OK && (recLen > RFC_2246_MAX_COMPRESSED_LENGTH || recLen > len || (stack->md && recLen < EVP_MD_size(stack->md))) ) { rc = NM_ERROR(DSSL_E_SSL_INVALID_RECORD_LENGTH); } if( rc == DSSL_RC_OK && stack->md ) { u_char mac[EVP_MAX_MD_SIZE]; u_char* rec_mac = NULL; DEBUG_TRACE1("ssl_record_layer_decoder - data using len: %d\n", len); /* for (i=0; i < len; i++) { printf("0x%02X ", data[i]); } */ recLen -= EVP_MD_size( stack->md ); rec_mac = data+recLen; memset(mac, 0, sizeof(mac) ); // Fix - skip iv for TLS 1.1 DEBUG_TRACE1("ssl_record_layer_decoder - stack->version: 0x%02X\n", stack->version); DEBUG_TRACE1("ssl_record_layer_decoder - block_size: %d\n", block_size); if (stack->version > TLS1_VERSION && block_size > 1) { DEBUG_TRACE0("ssl_record_layer_decoder - activated fix for TLS 1.1 (skip 16 bytes)\n"); data2 = data + block_size; recLen2 = recLen - block_size; rc = stack->sess->caclulate_mac_proc( stack, record_type, data2, recLen2, mac ); } else { rc = stack->sess->caclulate_mac_proc( stack, record_type, data, recLen, mac ); } DEBUG_TRACE1("ssl_record_layer_decoder - caclulate_mac_proc result: %d\n", rc); if( rc == DSSL_RC_OK ) { DEBUG_TRACE1("ssl_record_layer_decoder - caclulate_mac_proc memcmp size(i.e. EVP_MD_size(stack->md)): %d\n", EVP_MD_size(stack->md)); DEBUG_TRACE0("ssl_record_layer_decoder - mac vs. rec_mac:\n"); if (IsDebugEnabled()) { for (i=0; i < EVP_MD_size(stack->md); i++) { DEBUG_TRACE2("0x%02X vs. 0x%02X\n", mac[i], rec_mac[i]); } } rc = memcmp( mac, rec_mac, EVP_MD_size(stack->md) ) == 0 ? DSSL_RC_OK : NM_ERROR( DSSL_E_SSL_INVALID_MAC ); } } if( rc == DSSL_RC_OK && stack->compression_method != 0 ) { rc = ssl_decompress_record( stack, data, recLen, &data, &recLen, &decompress_buffer_aquired ); DEBUG_TRACE1("ssl_record_layer_decoder - ssl_decompress_record call ended. rc: %d\n", rc); } if( rc == DSSL_RC_OK ) { DEBUG_TRACE1("ssl_record_layer_decoder - record_type: %d\n", record_type); switch( record_type ) { case SSL3_RT_HANDSHAKE: DEBUG_TRACE0("ssl_record_layer_decoder - SSL3_RT_HANDSHAKE\n"); next_decoder = &stack->dhandshake; break; case SSL3_RT_CHANGE_CIPHER_SPEC: DEBUG_TRACE0("ssl_record_layer_decoder - SSL3_RT_CHANGE_CIPHER_SPEC\n"); next_decoder = &stack->dcss; break; case SSL3_RT_APPLICATION_DATA: DEBUG_TRACE0("ssl_record_layer_decoder - SSL3_RT_APPLICATION_DATA\n"); next_decoder = &stack->dappdata; break; case SSL3_RT_ALERT: DEBUG_TRACE0("ssl_record_layer_decoder - SSL3_RT_ALERT\n"); next_decoder = &stack->dalert; break; default: DEBUG_TRACE0("ssl_record_layer_decoder - record_type not found\n"); rc = NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR ); } } if( rc == DSSL_RC_OK ) { _ASSERT( next_decoder != NULL ); DEBUG_TRACE1("ssl_record_layer_decoder - calling dssl_decoder_process. handler is: %x\n", next_decoder->handler); // Fix - for TLS 1.1 continue if (data2 == NULL) rc = dssl_decoder_process( next_decoder, dir, data, recLen ); else rc = dssl_decoder_process( next_decoder, dir, data2, recLen2 ); DEBUG_TRACE1("ssl_record_layer_decoder - dssl_decoder_process ret: %d\n", rc); } if( rc == DSSL_RC_OK ) { *processed = totalRecLen + SSL3_HEADER_LEN; } if( decrypt_buffer_aquired ) { ssls_release_decrypt_buffer( stack->sess ); } if( decompress_buffer_aquired ) { ssls_release_decompress_buffer( stack->sess ); } #ifdef NM_TRACE_SSL_RECORD DEBUG_TRACE1( "\n} rc: %d\n", (int) rc); #endif if( stack->state == SS_SeenCloseNotify ) { stack->sess->flags |= SSF_CLOSE_NOTIFY_RECEIVED; } else if ( stack->state == SS_FatalAlert ) { stack->sess->flags |= SSF_FATAL_ALERT_RECEIVED; } DEBUG_TRACE1("ssl_record_layer_decoder - end. rc = %d\n", rc); return rc; }
int ssls_generate_keys( DSSL_Session* sess ) { DSSL_CipherSuite* suite = NULL; const EVP_CIPHER* c = NULL; const EVP_MD* digest = NULL; u_char* c_mac = NULL; u_char* c_wk = NULL; u_char* c_iv = NULL; u_char* s_mac = NULL; u_char* s_wk = NULL; u_char* s_iv = NULL; u_char export_iv_block[EVP_MAX_IV_LENGTH*2]; u_char export_c_wk[EVP_MAX_KEY_LENGTH]; u_char export_s_wk[EVP_MAX_KEY_LENGTH]; u_char keyblock[ TLS_MAX_KEYBLOCK_LEN ]; uint32_t keyblock_len = 0; uint32_t iv_len = 0; uint32_t wk_len = 0; uint32_t digest_len = 0; EVP_CIPHER_CTX* c_cipher = NULL; EVP_CIPHER_CTX* s_cipher = NULL; int rc = DSSL_RC_OK; _ASSERT( sess->c_dec.compression_data_new == NULL ); _ASSERT( sess->s_dec.compression_data_new == NULL ); _ASSERT( sess->c_dec.compression_method_new == 0 ); _ASSERT( sess->s_dec.compression_method_new == 0 ); /* set new compression algorithm */ if( sess->compression_method != 0 ) { sess->s_dec.compression_method_new = sess->compression_method; sess->c_dec.compression_method_new = sess->compression_method; dssl_compr_init( sess->s_dec.compression_method_new, &sess->s_dec.compression_data_new ); dssl_compr_init( sess->c_dec.compression_method_new, &sess->c_dec.compression_data_new ); } if( sess->c_dec.cipher_new != NULL ) { // _ASSERT( FALSE ); EVP_CIPHER_CTX_cleanup( sess->c_dec.cipher_new ); free( sess->c_dec.cipher_new ); sess->c_dec.cipher_new = NULL; } if( sess->s_dec.cipher_new != NULL ) { // _ASSERT( FALSE ); EVP_CIPHER_CTX_cleanup( sess->s_dec.cipher_new ); free( sess->s_dec.cipher_new ); sess->s_dec.cipher_new = NULL; } suite = DSSL_GetSSL3CipherSuite( sess->cipher_suite ); if( !suite ) { DEBUG_TRACE0("ssls_generate_keys - failed to find cipher suite\n"); return NM_ERROR( DSSL_E_SSL_CANNOT_DECRYPT ); } if (suite->enc != NULL && strlen(suite->enc) < 32) strcpy(sess->cipher_encoding, suite->enc); if (suite->digest != NULL && strlen(suite->digest) < 32) strcpy(sess->cipher_digest, suite->digest); c = EVP_get_cipherbyname( suite->enc ); digest = EVP_get_digestbyname( suite->digest ); /* calculate key length and IV length */ if( c != NULL ) { if( DSSL_CipherSuiteExportable( suite ) ) { wk_len = suite->export_key_bits / 8; } else { wk_len = EVP_CIPHER_key_length( c ); } iv_len = EVP_CIPHER_iv_length( c ); } if( digest != NULL ) digest_len = EVP_MD_size( digest ); /* calculate total keyblock length */ keyblock_len = (wk_len + digest_len + iv_len)*2; if( !keyblock_len ) return DSSL_RC_OK; if( sess->version == TLS1_VERSION || sess->version == TLS1_1_VERSION) { DEBUG_TRACE0("ssls_generate_keys - calling tls1_PRF\n"); rc = tls1_PRF( sess->master_secret, sizeof( sess->master_secret ), "key expansion", sess->server_random, SSL3_RANDOM_SIZE, sess->client_random, SSL3_RANDOM_SIZE, keyblock, keyblock_len ); } else if( sess->version == TLS1_2_VERSION) { DEBUG_TRACE0("ssls_generate_keys - calling tls12_PRF\n"); rc = tls12_PRF( "SHA256"/*sess->cipher_digest*/, sess->master_secret, sizeof( sess->master_secret ), "key expansion", sess->server_random, SSL3_RANDOM_SIZE, sess->client_random, SSL3_RANDOM_SIZE, keyblock, keyblock_len ); } else { DEBUG_TRACE0("ssls_generate_keys - calling ssl3_PRF\n"); rc = ssl3_PRF( sess->master_secret, sizeof( sess->master_secret ), sess->server_random, SSL3_RANDOM_SIZE, sess->client_random, SSL3_RANDOM_SIZE, keyblock, keyblock_len ); } /* init keying material pointers */ if( rc == DSSL_RC_OK ) { u_char* p = keyblock; if( digest_len ) { c_mac = p; p+= digest_len; s_mac = p; p+= digest_len; } if( c != NULL ) { c_wk = p; p+= wk_len; s_wk = p; p+= wk_len; /* generate final server and client write keys for exportable ciphers */ if( DSSL_CipherSuiteExportable( suite ) ) { int final_wk_len = EVP_CIPHER_key_length( c ); if( sess->version == TLS1_VERSION || sess->version == TLS1_1_VERSION ) { DEBUG_TRACE0("ssls_generate_keys - calling tls1_PRF (2)\n"); tls1_PRF( c_wk, wk_len, "client write key", sess->client_random, SSL3_RANDOM_SIZE, sess->server_random, SSL3_RANDOM_SIZE, export_c_wk, final_wk_len ); tls1_PRF( s_wk, wk_len, "server write key", sess->client_random, SSL3_RANDOM_SIZE, sess->server_random, SSL3_RANDOM_SIZE, export_s_wk, final_wk_len ); } else if( sess->version == TLS1_2_VERSION) { DEBUG_TRACE1("ssls_generate_keys - calling tls12_PRF (2) - sess->cipher_digest: %s\n", sess->cipher_digest); tls12_PRF( "SHA256"/*sess->cipher_digest*/,c_wk, wk_len, "client write key", sess->client_random, SSL3_RANDOM_SIZE, sess->server_random, SSL3_RANDOM_SIZE, export_c_wk, final_wk_len ); tls12_PRF( "SHA256"/*sess->cipher_digest*/,s_wk, wk_len, "server write key", sess->client_random, SSL3_RANDOM_SIZE, sess->server_random, SSL3_RANDOM_SIZE, export_s_wk, final_wk_len ); } else { MD5_CTX md5; DEBUG_TRACE0("ssls_generate_keys - MD5_CTX handling\n"); _ASSERT( sess->version == SSL3_VERSION ); MD5_Init( &md5 ); MD5_Update( &md5, c_wk, wk_len ); MD5_Update( &md5, sess->client_random, SSL3_RANDOM_SIZE ); MD5_Update( &md5, sess->server_random, SSL3_RANDOM_SIZE ); MD5_Final( export_c_wk, &md5 ); MD5_Init( &md5 ); MD5_Update( &md5, s_wk, wk_len ); MD5_Update( &md5, sess->server_random, SSL3_RANDOM_SIZE ); MD5_Update( &md5, sess->client_random, SSL3_RANDOM_SIZE ); MD5_Final( export_s_wk, &md5 ); } c_wk = export_c_wk; s_wk = export_s_wk; wk_len = final_wk_len; } } if( iv_len ) { if( DSSL_CipherSuiteExportable( suite ) ) { if( sess->version == TLS1_VERSION || sess->version == TLS1_1_VERSION ) { DEBUG_TRACE0("ssls_generate_keys - calling tls1_PRF (3)\n"); tls1_PRF( NULL, 0, "IV block", sess->client_random, SSL3_RANDOM_SIZE, sess->server_random, SSL3_RANDOM_SIZE, export_iv_block, iv_len*2 ); } else if( sess->version == TLS1_2_VERSION) { DEBUG_TRACE1("ssls_generate_keys - calling tls12_PRF (3) - sess->cipher_digest: %s\n", sess->cipher_digest); tls12_PRF( "SHA256"/*sess->cipher_digest*/, NULL, 0, "IV block", sess->client_random, SSL3_RANDOM_SIZE, sess->server_random, SSL3_RANDOM_SIZE, export_iv_block, iv_len*2 ); } else { MD5_CTX md5; DEBUG_TRACE0("ssls_generate_keys - MD5_CTX handling (2)\n"); _ASSERT( sess->version == SSL3_VERSION ); MD5_Init( &md5 ); MD5_Update( &md5, sess->client_random, SSL3_RANDOM_SIZE ); MD5_Update( &md5, sess->server_random, SSL3_RANDOM_SIZE ); MD5_Final( export_iv_block, &md5 ); MD5_Init( &md5 ); MD5_Update( &md5, sess->server_random, SSL3_RANDOM_SIZE ); MD5_Update( &md5, sess->client_random, SSL3_RANDOM_SIZE ); MD5_Final( export_iv_block + iv_len, &md5 ); } c_iv = export_iv_block; s_iv = export_iv_block + iv_len; } else { c_iv = p; p+= iv_len; s_iv = p; p+= iv_len; } } else { c_iv = s_iv = NULL; } } /* create ciphers */ if( c != NULL && rc == DSSL_RC_OK ) { c_cipher = (EVP_CIPHER_CTX*) malloc( sizeof(EVP_CIPHER_CTX) ); s_cipher = (EVP_CIPHER_CTX*) malloc( sizeof(EVP_CIPHER_CTX) ); if( !c_cipher || !s_cipher ) { rc = NM_ERROR( DSSL_E_OUT_OF_MEMORY ); } } /* init ciphers */ if( c != NULL && rc == DSSL_RC_OK ) { DEBUG_TRACE0("ssls_generate_keys - EVP_CIPHER_CTX_init\n"); EVP_CIPHER_CTX_init( c_cipher ); EVP_CipherInit( c_cipher, c, c_wk, c_iv, 0 ); EVP_CIPHER_CTX_init( s_cipher ); EVP_CipherInit( s_cipher, c, s_wk, s_iv, 0 ); } else { DEBUG_TRACE0("ssls_generate_keys - not calling EVP_CIPHER_CTX_init\n"); } /* set session data */ if( rc == DSSL_RC_OK ) { _ASSERT( sess->c_dec.cipher_new == NULL ); _ASSERT( sess->s_dec.cipher_new == NULL ); sess->c_dec.cipher_new = c_cipher; c_cipher = NULL; sess->s_dec.cipher_new = s_cipher; s_cipher = NULL; if( digest ) { DEBUG_TRACE1("ssls_generate_keys - identified digest. len: %d\n", digest_len); _ASSERT( EVP_MD_size( digest ) == (int)digest_len ); sess->c_dec.md_new = digest; sess->s_dec.md_new = digest; memcpy( sess->c_dec.mac_key_new, c_mac, digest_len ); memcpy( sess->s_dec.mac_key_new, s_mac, digest_len ); } } /* cleanup */ OPENSSL_cleanse( keyblock, keyblock_len ); if( c_cipher ) { free( c_cipher ); c_cipher = NULL; } if( s_cipher ) { free( c_cipher ); c_cipher = NULL; } return rc; }
/* ========== Handshake decoding function ========== */ int ssl3_decode_handshake_record( dssl_decoder_stack* stack, NM_PacketDir dir, u_char* data, uint32_t len, uint32_t* processed ) { int rc = DSSL_E_UNSPECIFIED_ERROR; uint32_t recLen = 0; u_char hs_type = 0; u_char* org_data = data; DSSL_Session* sess = stack->sess; _ASSERT( processed != NULL ); _ASSERT((sess->flags & SSF_SSLV2_CHALLENGE) == 0); if( sess->version == 0 ) { return ssl_decode_first_client_hello( sess, data, len, processed ); } if( len < SSL3_HANDSHAKE_HEADER_LEN ) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); DEBUG_TRACE_BUF("handshake", data, len); recLen = (((int32_t)data[1]) << 16) | (((int32_t)data[2]) << 8) | data[3]; hs_type = data[0]; data += SSL3_HANDSHAKE_HEADER_LEN; len -= SSL3_HANDSHAKE_HEADER_LEN; if( len < recLen )return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); #ifdef NM_TRACE_SSL_HANDSHAKE DEBUG_TRACE2( "===>Decoding SSL v3 handshake: %s len: %d...", SSL3_HandshakeTypeToString( hs_type ), (int) recLen ); #endif switch( hs_type ) { case SSL3_MT_HELLO_REQUEST: rc = ssl3_decode_dummy( sess, data, recLen ); break; case SSL3_MT_CLIENT_HELLO: rc = ssl3_decode_client_hello( sess, data, recLen ); break; case SSL3_MT_SERVER_HELLO: stack->state = SS_SeenServerHello; rc = ssl3_decode_server_hello( sess, data, recLen ); break; case SSL3_MT_CERTIFICATE: if( dir == ePacketDirFromServer ) { rc = ssl3_decode_server_certificate( sess, data, recLen ); } else { rc = ssl3_decode_dummy( sess, data, recLen ); } break; case SSL3_MT_SERVER_DONE: rc = ssl3_decode_dummy( sess, data, recLen ); break; case SSL3_MT_CLIENT_KEY_EXCHANGE: rc = ssl3_decode_client_key_exchange( sess, data, recLen ); break; case SSL3_MT_FINISHED: rc = (*sess->decode_finished_proc)( sess, dir, data, recLen ); if( rc == DSSL_RC_OK ) { stack->state = SS_Established; ssls_handshake_done( sess ); } break; case SSL3_MT_CERTIFICATE_STATUS: rc = ssl3_decode_dummy( sess, data, recLen ); break; case SSL3_MT_SERVER_KEY_EXCHANGE: /*at this point it is clear that the session is not decryptable due to ephemeral keys usage.*/ rc = NM_ERROR( DSSL_E_SSL_CANNOT_DECRYPT_EPHEMERAL ); break; case SSL3_MT_CERTIFICATE_REQUEST: /* TODO: track CertificateRequest- client certificate / certificate verify */ rc = ssl3_decode_dummy( sess, data, recLen ); break; case SSL3_MT_CERTIFICATE_VERIFY: /* TODO: track CertificateRequest- client certificate / certificate verify */ rc = ssl3_decode_dummy( sess, data, recLen ); break; case SSL3_MT_NEWSESSION_TICKET: rc = ssl3_decode_new_session_ticket( sess, data, recLen ); break; default: rc = NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR ); break; } if( rc == DSSL_RC_OK ) { *processed = recLen + SSL3_HANDSHAKE_HEADER_LEN; if( hs_type == SSL3_MT_CLIENT_HELLO ) { ssl3_init_handshake_digests( sess ); } if( hs_type != SSL3_MT_HELLO_REQUEST ) { ssl3_update_handshake_digests( sess, org_data, *processed ); } } #ifdef NM_TRACE_SSL_HANDSHAKE if( rc == DSSL_RC_OK ) { DEBUG_TRACE0( "OK\n" ); } else { DEBUG_TRACE1( "Error! (%d)\n", (int)rc ); } #endif return rc; }
int main(void) { #if PLATFORM_ARM_OS_PORT ClrThreadId = osThreadGetId(); #endif BootstrapCode_GPIO(); HAL_Time_Initialize(); HAL_Initialize(); #if !defined(BUILD_RTM) DEBUG_TRACE4( STREAM_LCD, ".NetMF v%d.%d.%d.%d\r\n", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION); DEBUG_TRACE3(TRACE_ALWAYS, "%s, Build Date:\r\n\t%s %s\r\n", HalName, __DATE__, __TIME__); #if defined(__GNUC__) DEBUG_TRACE1(TRACE_ALWAYS, "GNU Compiler version %d\r\n", __GNUC__); #else DEBUG_TRACE1(TRACE_ALWAYS, "ARM Compiler version %d\r\n", __ARMCC_VERSION); #endif UINT8* BaseAddress; UINT32 SizeInBytes; HeapLocation( BaseAddress, SizeInBytes ); memset ( BaseAddress, 0, SizeInBytes ); debug_printf("\f"); debug_printf("%-15s\r\n", HalName); debug_printf("%-15s\r\n", "Build Date:"); debug_printf(" %-13s\r\n", __DATE__); debug_printf(" %-13s\r\n", __TIME__); #endif // !defined(BUILD_RTM) /***********************************************************************************/ { #if defined(FIQ_SAMPLING_PROFILER) FIQ_Profiler_Init(); #endif } // the runtime is by default using a watchdog Watchdog_GetSetTimeout ( WATCHDOG_TIMEOUT , TRUE ); Watchdog_GetSetBehavior( WATCHDOG_BEHAVIOR, TRUE ); Watchdog_GetSetEnabled ( WATCHDOG_ENABLE, TRUE ); // HAL initialization completed. Interrupts are enabled. Jump to the Application routine ApplicationEntryPoint(); debug_printf("main exited!!???. Halting CPU\r\n"); #if defined(BUILD_RTM) CPU_Reset(); #else CPU_Halt(); #endif return -1; }
/* ========== SSL 2 Handshake Protocol Decoder ========== */ int ssl2_decode_handshake( DSSL_Session* sess, NM_PacketDir dir, u_char* data, uint32_t len, uint32_t* processed ) { int rc = DSSL_RC_OK; int hs_type = 0; _ASSERT( processed ); _ASSERT( data ); if( len < 1 ) { return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); } hs_type = data[0]; data += 1; len -= 1; #ifdef NM_TRACE_SSL_HANDSHAKE DEBUG_TRACE1( "\n===>Decoding SSL v2 handshake message: %s", SSL2_HandshakeTypeToString( hs_type ) ); #endif /* check the packet direction */ switch(hs_type) { case SSL2_MT_CLIENT_HELLO: case SSL2_MT_CLIENT_MASTER_KEY: case SSL2_MT_CLIENT_FINISHED: case SSL2_MT_CLIENT_CERTIFICATE: if( dir != ePacketDirFromClient ) { rc = NM_ERROR( DSSL_E_SSL_UNEXPECTED_TRANSMISSION ); } break; case SSL2_MT_SERVER_HELLO: case SSL2_MT_SERVER_VERIFY: case SSL2_MT_SERVER_FINISHED: if( dir != ePacketDirFromServer ) { rc = NM_ERROR( DSSL_E_SSL_UNEXPECTED_TRANSMISSION ); } break; } if( rc == DSSL_RC_OK ) { switch( hs_type ) { case SSL2_MT_ERROR: rc = ssl2_decode_error( sess, data, len, processed ); break; case SSL2_MT_CLIENT_HELLO: rc = ssl2_decode_client_hello( sess, data, len, processed ); break; case SSL2_MT_SERVER_HELLO: sess->s_dec.state = SS_SeenServerHello; rc = ssl2_decode_server_hello( sess, data, len, processed ); break; case SSL2_MT_CLIENT_MASTER_KEY: rc = ssl2_decode_client_master_key( sess, data, len, processed ); break; case SSL2_MT_CLIENT_FINISHED: rc = ssl2_decode_client_finished( sess, data, len, processed ); break; case SSL2_MT_SERVER_VERIFY: rc = ssl2_decode_server_verify( sess, data, len, processed ); break; case SSL2_MT_SERVER_FINISHED: rc = ssl2_decode_server_finished( sess, data, len, processed ); break; case SSL2_MT_CLIENT_CERTIFICATE: case SSL2_MT_REQUEST_CERTIFICATE: /*just eat it */ *processed = len; rc = DSSL_RC_OK; break; default: rc = NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR ); break; } if( rc == DSSL_RC_OK ) { *processed += 1; } } return rc; }