📄 ipsec_outbound_sa_spec.c
字号:
/* ipsec_outbound_sa_spec.c - Outbound SA spec code *//* * Copyright (c) 2000-2006 Wind River Systems, Inc. * * The right to copy, distribute, modify or otherwise make use * of this software may be licensed only pursuant to the terms * of an applicable Wind River license agreement. *//* Copyright (c) 2002-2003 teamF1, Inc. *//******************************************************************************//*modification history--------------------------------------------------04d,13jan06,djp removed rwos dependencies04c,08nov05,rlm Removed all references to rw_packet routines.04b,10aug05,rlm Mods for single-pass encryption/HMAC with hardware acceleration.04a,03may04,rma Renew PS when sequence_counter rolls over.03e,04Aug03,rks(teamf1) changes in outbound_ah_sa_spec_construct_ah. Freeing sptr_ipsec_ah_message in error cases.03d,18Mar03,rks(teamf1) removed wncrypto crypto_if.h.03c,17Dec02,mhb(teamf1) Fixed compilation warnings03b,14Nov02,rks(teamf1) changes for CCI intergration03a,20Sep02,rks(teamf1) modification for IPv602b,27mar02,rpt changed "AH/ESP outbound process" function definitions to integrate with enhanced crypto interface "crypto_if.h"02a,19mar02,rpt changed func declarations to use IP_VI_MESSAGE instead of IP_MESSAGE. 01a,19mar02,rpt extracted from WindNet IPSec 1.1, added modification history*//******************************************************************************/#include <vxWorks.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <netinet/in.h>#include <wrn/ipsec/ipsecLogger.h>#include "../common/wrSecCommon.h"#include "../sadb/sadb_if.h"#include "../crypto/ipsecDOItoCCI.h"#include "../crypto/cipher.h"#include "../ike/ike_if.h"#include "ipsec_if.h"#include "packetBuf.h"#include "ipsec_print_routines.h"#include "ipsec_logger_util.h"#include "ipsec_ah_message.h"#include "ipsec_esp_message.h"#include "ipsec_tunnel_utilities.h"/******************************************************************************/LOCAL SA_SPEC_RET_TYPES outbound_ah_sa_spec_construct_ah ( OUTBOUND_AH_SA_SPEC *sptr_outbound_ah_sa_spec, IPSEC_AH_MESSAGE *sptr_ipsec_ah_message, IP_VI_MESSAGE *p_ip_message );/******************************************************************************/LOCAL BOOL outbound_ipsec_sa_spec_verify_validity_of_next_sequence_number ( OUTBOUND_IPSEC_SA_SPEC *sptr_outbound_ipsec_sa_spec ) { UINT next_sequence_number_counter; if (sptr_outbound_ipsec_sa_spec->sequence_counter_overflow == FALSE) { next_sequence_number_counter = sptr_outbound_ipsec_sa_spec->sequence_number_counter + 1; if (next_sequence_number_counter == 0) { /* Sequence Counter Overflow here */ sptr_outbound_ipsec_sa_spec->sequence_counter_overflow = TRUE; return (FALSE); } return (TRUE); } else { return (FALSE); } }/******************************************************************************/LOCAL UINT outbound_ipsec_sa_spec_get_next_sequence_number ( OUTBOUND_IPSEC_SA_SPEC *sptr_outbound_ipsec_sa_spec ) { if (sptr_outbound_ipsec_sa_spec->sequence_counter_overflow == FALSE) { ++sptr_outbound_ipsec_sa_spec->sequence_number_counter; if (sptr_outbound_ipsec_sa_spec->sequence_number_counter == 0) { /* Sequence Counter Overflow here */ sptr_outbound_ipsec_sa_spec->sequence_counter_overflow = TRUE; return (0); } return (sptr_outbound_ipsec_sa_spec->sequence_number_counter); } else { return (0); } }/******************************************************************************/SA_SPEC_RET_TYPES outbound_ah_sa_spec_process ( SA_SPEC *sptr_sa_spec, IP_VI_MESSAGE *p_ip_message, SA_BUNDLE *sptr_bundle ) { OUTBOUND_AH_SA_SPEC *sptr_outbound_ah_sa_spec; IPSEC_AH_MESSAGE ipsec_ah_message; IP_VERSION_NUMBER ip_version; BOOL return_value = FALSE; sptr_outbound_ah_sa_spec = (OUTBOUND_AH_SA_SPEC *)sptr_sa_spec; if (outbound_ipsec_sa_spec_verify_validity_of_next_sequence_number ((OUTBOUND_IPSEC_SA_SPEC *)sptr_sa_spec) == FALSE) { #ifdef INCLUDE_LOGGING_SEQUENCE_NUM_OVERFLOW if (ipsecLoggerIsLogEventEnabled (SEQUENCE_NUM_OVERFLOW)) { ipsecEventLogFromSABundle (sptr_bundle, NULL, SEQUENCE_NUM_OVERFLOW, UNDEFINED_REASON); } #endif /* INCLUDE_LOGGING_SEQUENCE_NUM_OVERFLOW */ /* We'll need to renew the PS because the counter has rolled over*/ renewProtectionSuite (sptr_bundle->protection_suite_id, 0); return (AH_SEQUENCE_ERROR); } /* construct, sign and serialize AH message */ return_value = outbound_ah_sa_spec_construct_ah (sptr_outbound_ah_sa_spec, &ipsec_ah_message, p_ip_message); if (return_value != SA_SPEC_SUCCESS) { return (return_value); } /* update IP message */ ip_version = p_ip_message->version; if (ip_version == IP_V4) { ((IP_V4_MESSAGE *)p_ip_message)->transport_protocol = AH_PROTOCOL; } else if (ip_version == IP_V6) { ((IP_V6_MESSAGE *)p_ip_message)->next_header = AH_PROTOCOL; ((IP_V6_MESSAGE *)p_ip_message)->transport_protocol = AH_PROTOCOL; } else { ipsec_printf (IPSEC_WARNING_PRINTF, "IPsec: IP Message: INVALID_VERSION\n"); return (SA_SPEC_FAIL); } return (return_value); }/******************************************************************************/LOCAL SA_SPEC_RET_TYPES outbound_ah_sa_spec_construct_ah ( OUTBOUND_AH_SA_SPEC *sptr_outbound_ah_sa_spec, IPSEC_AH_MESSAGE *sptr_ipsec_ah_message, IP_VI_MESSAGE *p_ip_message ) { IP_VERSION_NUMBER ip_version; BOOL return_value = FALSE; /* construct the AH message */ return_value = ipsec_ah_message_construct (sptr_ipsec_ah_message, sptr_outbound_ah_sa_spec->authentication_type); if (return_value == FALSE) { return (SA_SPEC_FAIL); } ip_version = p_ip_message->version; if (ip_version == IP_V4) { sptr_ipsec_ah_message->next_header = ((IP_V4_MESSAGE *)p_ip_message)->transport_protocol; } else if (ip_version == IP_V6) { sptr_ipsec_ah_message->next_header = ((IP_V6_MESSAGE *)p_ip_message)->next_header; } else { ipsec_printf (IPSEC_WARNING_PRINTF, "IPsec: IP Message: INVALID_VERSION\n"); return_value = SA_SPEC_FAIL; goto outbound_ah_sa_spec_construct_ah_error; } sptr_ipsec_ah_message->spi = sptr_outbound_ah_sa_spec->parent.spi; sptr_ipsec_ah_message->sequence_number = outbound_ipsec_sa_spec_get_next_sequence_number ( (OUTBOUND_IPSEC_SA_SPEC *)sptr_outbound_ah_sa_spec); #ifdef INCLUDE_LOGGING_SEQUENCE_NUM_OVERFLOW if (sptr_ipsec_ah_message->sequence_number == 0) { if (ipsecLoggerIsLogEventEnabled (SEQUENCE_NUM_OVERFLOW)) { ipsecEventLogFromIPMessage (p_ip_message, NULL, SEQUENCE_NUM_OVERFLOW, UNDEFINED_REASON); } } #endif /* INCLUDE_LOGGING_SEQUENCE_NUM_OVERFLOW */ if (sptr_outbound_ah_sa_spec->context == 0) { ipsec_printf (IPSEC_WARNING_PRINTF, "IPsec: Invalid context handle in SA spec\n"); return_value = SA_SPEC_FAIL; goto outbound_ah_sa_spec_construct_ah_error; } /* sign the AH message */ if (ipsec_ah_message_sign (sptr_ipsec_ah_message, p_ip_message, sptr_outbound_ah_sa_spec->context) == FALSE) { ipsec_printf (IPSEC_ERROR_PRINTF, "IPsec: Failed Authentication !!\n"); return_value = AH_AUTHENTICATION_ERROR; goto outbound_ah_sa_spec_construct_ah_error; } /* serialize the AH message */ ipsec_ah_message_serialize (sptr_ipsec_ah_message, p_ip_message->pPayload); return_value = SA_SPEC_SUCCESS; outbound_ah_sa_spec_construct_ah_error: ipsec_ah_message_destruct (sptr_ipsec_ah_message); return (return_value); }/******************************************************************************/SA_SPEC_RET_TYPES outbound_esp_sa_spec_process ( SA_SPEC *sptr_sa_spec, IP_VI_MESSAGE *p_ip_message, SA_BUNDLE *sptr_bundle ) { OUTBOUND_ESP_SA_SPEC *sptr_outbound_esp_sa_spec; IPSEC_ESP_MESSAGE ipsec_esp_message; IP_VERSION_NUMBER ip_version; sptr_outbound_esp_sa_spec = (OUTBOUND_ESP_SA_SPEC *)sptr_sa_spec; ipsec_esp_message_construct (&ipsec_esp_message); if (outbound_ipsec_sa_spec_verify_validity_of_next_sequence_number ((OUTBOUND_IPSEC_SA_SPEC *)sptr_sa_spec) == FALSE) { #ifdef INCLUDE_LOGGING_SEQUENCE_NUM_OVERFLOW if (ipsecLoggerIsLogEventEnabled (SEQUENCE_NUM_OVERFLOW)) { ipsecEventLogFromSABundle (sptr_bundle, NULL, SEQUENCE_NUM_OVERFLOW, UNDEFINED_REASON); } #endif /* INCLUDE_LOGGING_SEQUENCE_NUM_OVERFLOW */ /* We'll need to renew the PS because the counter has rolled over */ renewProtectionSuite (sptr_bundle->protection_suite_id, 0); return (SA_SPEC_FAIL); } ipsec_esp_message.spi = sptr_outbound_esp_sa_spec->parent.spi; ipsec_esp_message.esp_sequence_number = outbound_ipsec_sa_spec_get_next_sequence_number ( (OUTBOUND_IPSEC_SA_SPEC *)sptr_outbound_esp_sa_spec); #if defined(IPSEC_VERBOSE_PACKET_DEBUGGING) printf("====| OUTGOING SPI:0x%08x\n", ipsec_esp_message.spi); printf("====| OUTGOING SEQ:0x%08x\n", ipsec_esp_message.esp_sequence_number); #endif /* IPSEC_VERBOSE_PACKET_DEBUGGING */ #ifdef INCLUDE_LOGGING_SEQUENCE_NUM_OVERFLOW if (ipsec_esp_message.esp_sequence_number == 0) { if (ipsecLoggerIsLogEventEnabled (SEQUENCE_NUM_OVERFLOW)) { ipsecEventLogFromSABundle (sptr_bundle, NULL, SEQUENCE_NUM_OVERFLOW, UNDEFINED_REASON); } } #endif /* INCLUDE_LOGGING_SEQUENCE_NUM_OVERFLOW */ ip_version = p_ip_message->version; if (ip_version == IP_V4) { ipsec_esp_message.next_header = ((IP_V4_MESSAGE *)p_ip_message)->transport_protocol; } else if (ip_version == IP_V6) { ipsec_esp_message.next_header = ((IP_V6_MESSAGE *)p_ip_message)->next_header; } else { ipsec_printf (IPSEC_WARNING_PRINTF, "IPsec: IP Message: INVALID_VERSION\n"); return (SA_SPEC_FAIL); } ipsec_esp_message_serialize_header (&ipsec_esp_message, p_ip_message->pPayload); ipsec_esp_message_set_crypto_algorithm (&ipsec_esp_message, sptr_outbound_esp_sa_spec->crypto_algorithm); ipsec_esp_message_encrypt_and_serialize_trailer (&ipsec_esp_message, p_ip_message->pPayload, (CIPHER *)&sptr_outbound_esp_sa_spec->localCipher);#if 0 /* FIXME: -rlm: Shouldn't we *always* set the outbound sa_spec's auth alg? */ if( sptr_outbound_esp_sa_spec->authentication_type != AUTH_ALGORITHM_RESERVED) {#endif /* -rlm */ ipsec_esp_message_set_authentication_algorithm ( &ipsec_esp_message, sptr_outbound_esp_sa_spec->authentication_type);#if 0 /* -rlm */ }#endif /* -rlm */ /* update IP message */ if (ip_version == IP_V4) { ((IP_V4_MESSAGE *)p_ip_message)->transport_protocol = ESP_PROTOCOL; } else { ((IP_V6_MESSAGE *)p_ip_message)->next_header = ESP_PROTOCOL; ((IP_V6_MESSAGE *)p_ip_message)->transport_protocol = ESP_PROTOCOL; } ipsec_esp_message_destruct (&ipsec_esp_message); return (SA_SPEC_SUCCESS); }/******************************************************************************/SA_SPEC_RET_TYPES outbound_tunnel_sa_spec_process ( SA_SPEC *sptr_sa_spec, IP_VI_MESSAGE *p_ip_message, SA_BUNDLE *sptr_bundle ) { PARAMETER_NOT_USED (sptr_bundle); if (ipsec_tunnel_manager_serialize_inner_ip_header (p_ip_message) == FALSE) { return (SA_SPEC_FAIL); } if (ipsec_serialize_tunnel_message (sptr_sa_spec, p_ip_message) == FALSE) { return (SA_SPEC_FAIL); } return (SA_SPEC_SUCCESS); }/******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -