⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipsec_inbound_sa_spec.c

📁 ipsec PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
字号:
/* ipsec_inbound_sa_spec.c - WindNet IPsec and IKE - IPsec 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.  *//*modification history--------------------03l,13jan06,djp  removed rwos dependencies03k,08nov05,rlm  Removed references to rw_packet routines.03j,10aug05,rlm  Mods for single-pass encryption/HMAC with hardware                 acceleration.03i,13apr05,djp   Fixed include paths03h,04Aug03,rks(teamf1) changes in inbound_ah_sa_spec_process. Freeing             ipsec_ah_message in error cases.03g,12jun03,rparkhil added support for STACK_NAME03f,24Apr03,sam(teamf1) renamed ipsec_ipv6_extns_find_transport_protocol to            ipsecIpv6ExtnsTransportProtocolFind03e,18Mar03,rks(teamf1)  removed wncrypto crypto_if.h.03b,17Dec02,mhb(teamf1) Fixed compilation warnings03a,20Sep02,rks(teamf1)	modification for IPv602b,27mar02,rpt   changed "AH/ESP inbound 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 <netinet/in.h>#include "../common/wrSecCommon.h"#include "../sadb/sadb_if.h"#include "../crypto/ipsecDOItoCCI.h"#include "../crypto/cipher.h"#ifdef IPSEC_VERBOSE_PACKET_DEBUGGING#include "../ike/ike_print_routines.h"#endif#include "ipsec_if.h"#include "packetBuf.h"#include "ipsec_print_routines.h"#include "ipsec_ah_message.h"#include "ipsec_esp_message.h"#include "ipsec_tunnel_utilities.h"#if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6)#include "ipsec_ipv6_utilities.h"#endif /* STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) *//* forward declarations */LOCAL BOOL inbound_ipsec_sa_spec_check_if_sequence_number_is_valid    (    INBOUND_IPSEC_SA_SPEC *sptr_inbound_ipsec_sa_spec,    UINT sequence_number,    IPSEC_AUTH_ALGORITHM_ID authentication_type    );LOCAL void inbound_ipsec_sa_spec_update_receive_window    (    INBOUND_IPSEC_SA_SPEC *sptr_inbound_ipsec_sa_spec,    UINT sequence_number    );LOCAL BOOL inbound_ipsec_sa_spec_is_anti_replay_enabled    (    INBOUND_IPSEC_SA_SPEC *sptr_inbound_ipsec_sa_spec    );/******************************************************************************/LOCAL BOOL inbound_ipsec_sa_spec_check_if_sequence_number_is_valid    (    INBOUND_IPSEC_SA_SPEC *sptr_inbound_ipsec_sa_spec,    UINT sequence_number,    IPSEC_AUTH_ALGORITHM_ID authentication_type    )    {    UINT difference;    UINT bit_position;    if (sequence_number == 0)        {        return (FALSE);        }    else if ((authentication_type != AUTH_ALGORITHM_RESERVED) &&             (inbound_ipsec_sa_spec_is_anti_replay_enabled ((INBOUND_IPSEC_SA_SPEC *)sptr_inbound_ipsec_sa_spec)                         == TRUE))        {        if (sequence_number > sptr_inbound_ipsec_sa_spec->last_sequence_number)            {            return (TRUE);            }        else            {            difference = sptr_inbound_ipsec_sa_spec->last_sequence_number - sequence_number;            if (difference >= sptr_inbound_ipsec_sa_spec->anti_replay_window_size)                {                return (FALSE);                }            bit_position = 1 << difference;            if (sptr_inbound_ipsec_sa_spec->replay_bit_map & bit_position)                {                return (FALSE);                }            return (TRUE);            }        }    else        {        return (TRUE);        }    }/******************************************************************************/LOCAL void inbound_ipsec_sa_spec_update_receive_window    (    INBOUND_IPSEC_SA_SPEC *sptr_inbound_ipsec_sa_spec,    UINT sequence_number    )    {    UINT difference;    UINT bit_position;    if (sequence_number > sptr_inbound_ipsec_sa_spec->last_sequence_number)        {        difference = sequence_number - sptr_inbound_ipsec_sa_spec->last_sequence_number;        if (difference < sptr_inbound_ipsec_sa_spec->anti_replay_window_size)            {            sptr_inbound_ipsec_sa_spec->replay_bit_map <<= difference;            sptr_inbound_ipsec_sa_spec->replay_bit_map |= 1;            }        else            {            sptr_inbound_ipsec_sa_spec->replay_bit_map = 1;            }        sptr_inbound_ipsec_sa_spec->last_sequence_number = sequence_number;        }    else        {        difference = sptr_inbound_ipsec_sa_spec->last_sequence_number - sequence_number;        bit_position = 1 << difference;        sptr_inbound_ipsec_sa_spec->replay_bit_map |= bit_position;        }    }/******************************************************************************/LOCAL BOOL inbound_ipsec_sa_spec_is_anti_replay_enabled    (    INBOUND_IPSEC_SA_SPEC *sptr_inbound_ipsec_sa_spec    )    {    return (sptr_inbound_ipsec_sa_spec->anti_replay_enabled);    }/******************************************************************************/SA_SPEC_RET_TYPES inbound_ah_sa_spec_process    (    SA_SPEC *sptr_sa_spec,    IP_VI_MESSAGE *p_ip_message,    SA_BUNDLE *sptr_bundle    )    {    INBOUND_AH_SA_SPEC *sptr_ib_ah_sa_spec;    IPSEC_AH_MESSAGE ipsec_ah_message;    BOOL return_value = FALSE;    IP_VERSION_NUMBER ip_version;    PARAMETER_NOT_USED (sptr_bundle);    sptr_ib_ah_sa_spec = (INBOUND_AH_SA_SPEC *)sptr_sa_spec;    return_value = ipsec_ah_message_construct (&ipsec_ah_message, sptr_ib_ah_sa_spec->authentication_type);    if (return_value == FALSE)        {        return (SA_SPEC_FAIL);        }    if (ipsec_ah_message_deserialize (&ipsec_ah_message, p_ip_message->pPayload) == FALSE)        {        return_value = SA_SPEC_FAIL;        goto inbound_ah_sa_spec_process_error;        }    if (ipsec_ah_message.spi != sptr_ib_ah_sa_spec->parent.spi)        {        return_value = SA_SPEC_FAIL;        goto inbound_ah_sa_spec_process_error;        }    if (inbound_ipsec_sa_spec_check_if_sequence_number_is_valid (            (INBOUND_IPSEC_SA_SPEC *)sptr_ib_ah_sa_spec, ipsec_ah_message.sequence_number,            sptr_ib_ah_sa_spec->authentication_type) == FALSE)        {        return_value = AH_SEQUENCE_ERROR;        goto inbound_ah_sa_spec_process_error;        }    /* Get the context handle*/    if (sptr_ib_ah_sa_spec->context == 0)        {        ipsec_printf (IPSEC_WARNING_PRINTF, "IPsec: Invalid context handle in SA spec\n");        return_value = SA_SPEC_FAIL;        goto inbound_ah_sa_spec_process_error;        }    #ifdef IPSEC_VERBOSE_PACKET_DEBUGGING    ike_debug_printf_bytes (        IKE_ERROR_PRINTF,                           "<ah_inbound_sa_spec_process: payload before authentication>\n",        packetBufDataGet(p_ip_message->pPayload), packetBufDataSizeGet(p_ip_message->pPayload));    #endif    if (ipsec_ah_message_verify (&ipsec_ah_message, p_ip_message, sptr_ib_ah_sa_spec->context) == FALSE)        {        ipsec_printf (IPSEC_ERROR_PRINTF, "IPsec: Failed Authentication !!\n");        return_value = AH_AUTHENTICATION_ERROR;        goto inbound_ah_sa_spec_process_error;        }    if ((sptr_ib_ah_sa_spec->authentication_type != AUTH_ALGORITHM_RESERVED)            && (inbound_ipsec_sa_spec_is_anti_replay_enabled ((INBOUND_IPSEC_SA_SPEC *)sptr_ib_ah_sa_spec) == TRUE))        {        inbound_ipsec_sa_spec_update_receive_window (            (INBOUND_IPSEC_SA_SPEC *)sptr_ib_ah_sa_spec, ipsec_ah_message.sequence_number);        }    /* update IP message */    ip_version = p_ip_message->version;    if (ip_version == IP_V4)        {        ((IP_V4_MESSAGE *)p_ip_message)->transport_protocol = ipsec_ah_message.next_header;        }    #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6)    else if (ip_version == IP_V6)        {        #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6)        UCHAR *bptr_data;        #endif        ((IP_V6_MESSAGE *)p_ip_message)->next_header = ipsec_ah_message.next_header;        ((IP_V6_MESSAGE *)p_ip_message)->transport_protocol = ipsec_ah_message.next_header;        #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6)        bptr_data = packetBufDataGet(p_ip_message->pPayload);        ((IP_V6_MESSAGE *)p_ip_message)->transport_protocol            = ipsecIpv6ExtnsTransportProtocolFind (ipsec_ah_message.next_header, bptr_data);        #endif        }    #endif /* STACK_NAME == STACK_NAME_V4_V6 && defined (INET6) */    else        {        ipsec_printf (IPSEC_WARNING_PRINTF, "IPsec: IP Message: INVALID_VERSION\n");        }    return_value = SA_SPEC_SUCCESS;    inbound_ah_sa_spec_process_error:    ipsec_ah_message_destruct (&ipsec_ah_message);    return (return_value);    } /* end inbound_ah_sa_spec_process() *//******************************************************************************/SA_SPEC_RET_TYPES inbound_esp_sa_spec_process    (    SA_SPEC *sptr_sa_spec,    IP_VI_MESSAGE *p_ip_message,    SA_BUNDLE *sptr_bundle    )    {    INBOUND_ESP_SA_SPEC * sptr_ib_esp_sa_spec;    IPSEC_ESP_MESSAGE ipsec_esp_message;    IP_VERSION_NUMBER ip_version;    SA_SPEC_RET_TYPES     espFailReason;    CIPHER              * cipher;    PARAMETER_NOT_USED (sptr_bundle);    sptr_ib_esp_sa_spec = (INBOUND_ESP_SA_SPEC *)sptr_sa_spec;    ipsec_esp_message_construct (&ipsec_esp_message);    ipsec_esp_message_get_spi_and_sequence_number (&ipsec_esp_message, p_ip_message);    #if defined(IPSEC_VERBOSE_PACKET_DEBUGGING)    printf("====| INCOMING SPI:0x%08x\n", ipsec_esp_message.spi);    printf("====| INCOMING SEQ:0x%08x\n", ipsec_esp_message.esp_sequence_number);    #endif    if (sptr_ib_esp_sa_spec->parent.spi != ipsec_esp_message.spi)        {        return (SA_SPEC_FAIL);        }    if (inbound_ipsec_sa_spec_check_if_sequence_number_is_valid (            (INBOUND_IPSEC_SA_SPEC *)sptr_ib_esp_sa_spec, ipsec_esp_message.esp_sequence_number,            sptr_ib_esp_sa_spec->authentication_type) == FALSE)        {        return (ESP_SEQUENCE_ERROR);        }    ipsec_esp_message_set_crypto_algorithm (&ipsec_esp_message, sptr_ib_esp_sa_spec->crypto_algorithm);    cipher = (CIPHER *) & (sptr_ib_esp_sa_spec->localCipher);    if(ipsec_esp_message_decrypt_and_deserialize_trailer (&ipsec_esp_message,                                                          p_ip_message->pPayload,                                                          cipher,                                                          &espFailReason) != TRUE)        {        return (espFailReason);        }    if (ipsec_esp_message_deserialize_header (&ipsec_esp_message, p_ip_message->pPayload) == FALSE)        {        return (ESP_DECRYPTION_ERROR);        }    if ((sptr_ib_esp_sa_spec->authentication_type != AUTH_ALGORITHM_RESERVED)        && (inbound_ipsec_sa_spec_is_anti_replay_enabled((INBOUND_IPSEC_SA_SPEC *)sptr_ib_esp_sa_spec) == TRUE))        {        inbound_ipsec_sa_spec_update_receive_window (            (INBOUND_IPSEC_SA_SPEC *)sptr_ib_esp_sa_spec, ipsec_esp_message.esp_sequence_number);        }    ip_version = p_ip_message->version;    if (ip_version == IP_V4)        {        ((IP_V4_MESSAGE *)p_ip_message)->transport_protocol = ipsec_esp_message.next_header;        }    else if (ip_version == IP_V6)        {        #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6)        UCHAR *bptr_data;        #endif        ((IP_V6_MESSAGE *)p_ip_message)->next_header = ipsec_esp_message.next_header;        ((IP_V6_MESSAGE *)p_ip_message)->transport_protocol = ipsec_esp_message.next_header;        #if STACK_NAME == STACK_NAME_V4_V6 && defined (INET6)        bptr_data = packetBufDataGet(p_ip_message->pPayload);        ((IP_V6_MESSAGE *)p_ip_message)->transport_protocol            = ipsecIpv6ExtnsTransportProtocolFind (ipsec_esp_message.next_header, bptr_data);        #endif        }    else        {        ipsec_printf (IPSEC_WARNING_PRINTF, "IPsec: IP Message: INVALID_VERSION\n");        }    ipsec_esp_message_destruct (&ipsec_esp_message);    return (SA_SPEC_SUCCESS);    } /* end inbound_esp_sa_spec_process() *//******************************************************************************/SA_SPEC_RET_TYPES inbound_tunnel_sa_spec_process    (    SA_SPEC *sptr_sa_spec,    IP_VI_MESSAGE *p_ip_message,    SA_BUNDLE *sptr_bundle    )    {    /*    ** RFC2401     ** ==============================================    ** Section 5.2 Processing Inbound IP Traffic     **    ** Section 5.2.1 Selecting and Using an SA or SA Bundle    ** ====================================================    ** Mapping the IP datagram to the appropriate SA is simplified because    ** of the presence of the SPI in the AH or ESP header.  Note that the    ** selector checks are made on the inner headers not the outer (tunnel)    ** headers.  The steps followed are:    **    **	   1. Use the packet's destination address (outer IP header),    **		  IPsec protocol, and SPI to look up the SA in the SAD.  If    **		  the SA lookup fails, drop the packet and log/report the    **		  error.    **    **	   2. Use the SA found in (1) to do the IPsec processing, e.g.,    **		  authenticate and decrypt.  This step includes matching the    **		  packet's (Inner Header if tunneled) selectors to the    **		  selectors in the SA.  Local policy determines the    **		  specificity of the SA selectors (single value, list,    **		  range, wildcard).  In general, a packet's source address    **		  MUST match the SA selector value.  However, an ICMP packet    **		  received on a tunnel mode SA may have a source address    **		  other than that bound to the SA and thus such packets    **		  should be permitted as exceptions to this check.  For an    **		  ICMP packet, the selectors from the enclosed problem    **		  packet (the source and destination addresses and ports    **		  should be swapped) should be checked against the selectors    **		  for the SA.  Note that some or all of these selectors may    **		  be inaccessible because of limitations on how many bits of    **		  the problem packet the ICMP packet is allowed to carry or    **		  due to encryption.  See Section 6.    */    PARAMETER_NOT_USED (sptr_bundle);    if (ipsec_deserialize_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 + -