コード例 #1
0
ファイル: ssl_decode.c プロジェクト: Correlsense/libdssl
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 )
{
	u_char* buf = NULL;
	uint32_t buf_len = len;
	int rc = DSSL_RC_OK;
	int block_size;
	const EVP_CIPHER* c = NULL;


	_ASSERT( stack );
	_ASSERT( stack->sess );
	_ASSERT( stack->cipher );

	rc = ssls_get_decrypt_buffer( stack->sess, &buf, buf_len );
	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_TRACE3( "using cipher %s (mode=%u, block=%u)\n", EVP_CIPHER_name(c), stack->sess->cipher_mode, block_size );
	if( block_size != 1 )
	{
		if( len == 0 || (len % block_size) != 0 )
		{
			return NM_ERROR( DSSL_E_SSL_DECRYPTION_ERROR );
		}
	}

	DEBUG_TRACE_BUF("encrypted", data, len);
	
	if ( EVP_CIPH_GCM_MODE == stack->sess->cipher_mode || EVP_CIPH_CCM_MODE == stack->sess->cipher_mode )
	{
		if ( len < EVP_GCM_TLS_EXPLICIT_IV_LEN )
		{
			return NM_ERROR( DSSL_E_SSL_DECRYPTION_ERROR );
		}

		if ( EVP_CIPH_GCM_MODE == stack->sess->cipher_mode )
		{
			/* set 'explicit_nonce' part from message bytes */
			rc = EVP_CIPHER_CTX_ctrl(stack->cipher, EVP_CTRL_GCM_SET_IV_INV, EVP_GCM_TLS_EXPLICIT_IV_LEN, data);
		}
		else
		{
			/* 4 bytes write_iv, 8 bytes explicit_nonce, 4 bytes counter */
			u_char ccm_nonce[EVP_GCM_TLS_TAG_LEN] = { 0 };		
			rc = EVP_CIPHER_CTX_ctrl(stack->cipher, EVP_CTRL_CCM_GET_TAG, sizeof(ccm_nonce), ccm_nonce);
			if( rc != DSSL_RC_OK ) return rc;
			
			/* overwrite exlicit_nonce part with packet data */
			memcpy(ccm_nonce + 1 + EVP_GCM_TLS_FIXED_IV_LEN, data, EVP_GCM_TLS_EXPLICIT_IV_LEN);
			rc = EVP_CIPHER_CTX_ctrl(stack->cipher, EVP_CTRL_CCM_SET_TAG, sizeof(ccm_nonce), ccm_nonce);
			if( rc != DSSL_RC_OK ) return rc;
		}
		data += EVP_GCM_TLS_EXPLICIT_IV_LEN;
		len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
	}
	rc = EVP_Cipher(stack->cipher, buf, data, len );

	buf_len = len;
	/* strip the padding */
	if( block_size != 1 )
	{
		if( buf[len-1] >= buf_len - 1 ) return NM_ERROR( DSSL_E_SSL_DECRYPTION_ERROR );
		buf_len -= buf[len-1] + 1;
	}
	
	DEBUG_TRACE_BUF("decrypted", buf, buf_len);
	
	/* ignore auth tag, which is 16 (for CCM/GCM) or 8 (for CCM-8) bytes */
	if ( EVP_CIPH_GCM_MODE == stack->sess->cipher_mode || EVP_CIPH_CCM_MODE == stack->sess->cipher_mode )
	{
		if (NULL == stack->sess->dssl_cipher_suite->extra_info)
			buf_len -= EVP_GCM_TLS_TAG_LEN;
		else
			buf_len -= (size_t)stack->sess->dssl_cipher_suite->extra_info;
	}

	*out = buf;
	*out_len = buf_len;

	return DSSL_RC_OK;
}
コード例 #2
0
ファイル: ssl_decode.c プロジェクト: plashchynski/libdssl
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;
}