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

📄 ipsec_esp_message.c

📁 ipsec PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ipsec_esp_message.c - WindNet IPsec and IKE - ESP message 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--------------------03u,13jan06,djp  removed rwos dependencies03t,12jan06,djp  removed rwos dependencies03s,08nov05,rma  Replace RWOS container with wrSecList.03r,08nov05,rlm  Removed references to rw_packet routines.03q,20oct05,rlm  Fix for SPR #114203.03p,19sep05,rlm  Removed obsolete ICV computation functions.03o,23aug05,rlm  Add comments during informal code review.03n,10aug05,rlm  Mods for single-pass encryption/HMAC with hardware                 acceleration.03m,13apr05,djp  Fixed include paths03l,07feb05,rlm  All failed alloca() calls now result in taskSuspend().03k,12nov04,rlm  Cast UCHAR * to char * for calls to bcopy() under diab to                 eliminate warnings.03j,03nov04,rlm  Fixes for AES-CTR mode when compiled with gcc.03i,23jul04,rlm  Added CPU_FAMILY==MIPS check to use memmove() instead of                 bcopy() (SPR #89530).03h,18jun04,rlm  Added optimization for aligned SPI and SEQ numbers to                 ipsec_esp_message_encrypt_and_serialize_trailer(). Also                 renamed variables in said function.03g,16jun04,rlm  Cipher reorg: refactored encrypt and decrypt functions.03f,20jun03,rks(teamf1) removed WRS change for aligned buffer in CCI calls03e,03Jun03,rks(teamf1) fix a bug in ipsec_decrypt_esp_message.                         encrypted_packet_length was getting negative while                        subtracting.03d,15apr03,sam(teamf1) Changes for PMTU support(SPR #86677).03c,18Mar03,rks(teamf1) replaced DES_BLOCK_SIZE with CCI_DES_IV_LENGTH.03c,31Mar03,rparkhil    added padding for NULL encryption03b,07Jan03,teamf1      replaced CCI_GET_DIGEST_LENGTH with cci_ctx_digest_length03a,14Nov02,rks(teamf1) changes for CCI intergration02b,27mar02,rpt   changed ESP function definitions to integrate with enhanced                   crypto interface "crypto_if.h"02a,19mar02,rpt   replaced IP_MESSAGE by IP_VI_MESSAGE in func definitions 01a,19mar02,rpt   Extracted from WindNet IPSec 1.1, added modification history*//******************************************************************************/#include <vxWorks.h>#include <string.h>#include <netinet/in.h>#include <wrn/cci/cci.h>#include "../common/wrSecMem.h"#include "../common/wrSecList.h"#include "../common/wrSecSerialize.h"#include "../crypto/cipher.h"#include "../sadb/sadb_if.h"#ifdef IPSEC_VERBOSE_PACKET_DEBUGGING#include "../ike/ike_print_routines.h"#endif#include "ipsec_if.h"#include "ipsec_esp_message.h"#include "ipsec_print_routines.h"#include "packetBuf.h"/******************************************************************************/LOCAL void CBCModeIVGenerate    (    CIPHER *cipher,       /* cipher object */    unsigned char *buffer /* where to store IV */    );LOCAL void CTRModeCounterBlockIVExtractAndSet    (    CIPHER *cipher,    unsigned char *buffer    );LOCAL void CTRModeCounterBlockBuild    (    CIPHER *cipher,       /* cipher object */    unsigned char *buffer /* where to store IV */    );/******************************************************************************/IPSEC_ESP_MESSAGE *ipsec_esp_message_create    (    void    )    {    IPSEC_ESP_MESSAGE *sptr_ipsec_esp_message;    sptr_ipsec_esp_message = wrSecAlloc (sizeof (IPSEC_ESP_MESSAGE));    if (sptr_ipsec_esp_message == NULL)        {        ipsec_printf_mon (IPSEC_ERROR_PRINTF, "IPsec: Error: ipsec_esp_message_create(): wrSecAlloc failed\n");        return (NULL);        }    return (sptr_ipsec_esp_message);    }/******************************************************************************/void ipsec_esp_message_construct    (    IPSEC_ESP_MESSAGE *sptr_ipsec_esp_message    )    {    if (sptr_ipsec_esp_message == NULL)        {        return;        }    sptr_ipsec_esp_message->esp_sequence_number = 0;    sptr_ipsec_esp_message->spi = 0;    }/******************************************************************************/void ipsec_esp_message_destruct    (    IPSEC_ESP_MESSAGE *sptr_ipsec_esp_message    )    {    if (sptr_ipsec_esp_message == NULL)        {        return;        }    sptr_ipsec_esp_message->esp_sequence_number = 0;    sptr_ipsec_esp_message->spi = 0;    }/******************************************************************************/void ipsec_esp_message_delete    (    IPSEC_ESP_MESSAGE *sptr_ipsec_esp_message    )    {    if (sptr_ipsec_esp_message == NULL)        {        return;        }    wrSecFree (sptr_ipsec_esp_message);    }/******************************************************************************/BOOL ipsec_esp_message_decrypt_and_deserialize_trailer    (    IPSEC_ESP_MESSAGE* sptr_ipsec_esp_message,    PACKETBUF*         pPacketBuf,    CIPHER*            cipher,    SA_SPEC_RET_TYPES* failReason    )    {    UINT ESPPacketLength;    UINT IVLength;    UINT dataToDecryptLength;    uint32_t SPINumber = 0; /* RFC2406, 2.1 */    uint32_t SEQNumber = 0; /* RFC2406, 2.2 */    UCHAR *pESPPacket;       /* [SPI][SEQ][ESP PAYLOAD] */    UCHAR *pESPReceivedIV;    UCHAR *pDataToDecrypt;    UCHAR *pTrailerFields;    BOOL AESCTRMode;    cci_st cciStatus;    BOOL isAligned;    UCHAR padLength; /* RFC2406, 2.5 */    UINT digestLength;    /* Note that 'cipher' and 'cipherESP' point to the SAME object; C doesn't     * understand our pseudo objects, so to access the derived CIPHER_ESP methods     * as well as the base CIPHER methods, it's most convenient to have two pointers.     * If this bugs you, or the compiler, too much, feel free to change it. */    CIPHER_ESP * cipherESP = (CIPHER_ESP *)cipher; /* to avoid casting everywhere */    *failReason = SA_SPEC_FAIL;     /* assume the worst */    AESCTRMode = FALSE;    pESPPacket = packetBufDataGet(pPacketBuf);    if (pESPPacket == NULL)        {        ipsec_printf(IPSEC_ERROR_PRINTF, "IPsec: ERROR: null ESP packet.\n");        *failReason = ESP_NULL_PACKET;        return (FALSE);        }    ESPPacketLength = packetBufDataSizeGet(pPacketBuf);    if ((cipher->cipherGet (cipher) == CCI_CIPHER_AES)            && (cipher->modeGet (cipher) == CCI_MODE_CTR))        {        AESCTRMode = TRUE;        }    /* NOTE: See RFC2406, "ESP", Section 2. for description of the     *       ESP payload format. */    digestLength = cipherESP->hmacDigestTruncSizeGet(cipherESP);    pTrailerFields = (pESPPacket + ESPPacketLength) -                      digestLength - LENGTH_OF_PADLEN_AND_NEXTHDR_FIELDS;    /* extract iv: it resides just beyond the SPI and SEQ fields of packet */    IVLength = cipher->IVSizeGet (cipher);    pESPReceivedIV = pESPPacket + LENGTH_OF_SPI_AND_SEQ_FIELDS;    /* Get IV for cipher (NOTE: AES-CTR mode only transmits the 64-bit IV portion of       its counter block so this value may be adjusted below) */    if (AESCTRMode)        {        /* in AES-CTR mode, only IV portion of counter block is transmitted;                   subtract size of nonce and counter fields. (RFC3686) */        IVLength = IVLength - IPSEC_AES_CTR_NONCE_SIZE - IPSEC_AES_CTR_CTR_SIZE;        /* Extract IV from incoming packet, put into AES cipher counter block */        CTRModeCounterBlockIVExtractAndSet (cipher, pESPReceivedIV);        #if (defined IPSEC_VERBOSE_PACKET_DEBUGGING || IPSEC_VERBOSE_AES_CTR_DEBUGGING)        ike_debug_printf_bytes (IKE_ERROR_PRINTF, "<AES-CTR Counter Block>:", (unsigned char *)cipher->_pIV,                                cipher->IVSizeGet (cipher));        #endif        }    else        {        /* Extract IV from incoming packet, put into CBC-mode cipher's IV */        cipher->IVSet (cipher, pESPReceivedIV);        }/* TODO: Are these pointers constant from packet to packet? (Probably not, but check) -rlm */    cipherESP->hmacInBufSet(cipherESP, pESPPacket, LENGTH_OF_SPI_AND_SEQ_FIELDS + IVLength);    cipherESP->hmacDigestBufSet(cipherESP, pTrailerFields + LENGTH_OF_PADLEN_AND_NEXTHDR_FIELDS);    dataToDecryptLength = ESPPacketLength - LENGTH_OF_SPI_AND_SEQ_FIELDS - IVLength - digestLength;    pDataToDecrypt = pESPReceivedIV + IVLength;#ifdef IPSEC_VERBOSE_PACKET_DEBUGGING    ike_debug_printf_bytes (IKE_ERROR_PRINTF, "== packet before decryption:", pESPPacket, ESPPacketLength);    {    char printBuf[1024];    ((C_OBJ *)cipher)->toString ((C_OBJ *)cipher, (unsigned char *)printBuf, 1024);    printf ("%s\n", printBuf);    }#endif    if ((dataToDecryptLength % cipher->blockSizeGet (cipher)) != 0)        {        ipsec_printf (IPSEC_WARNING_PRINTF,                      "IPsec: ESP decryption FAILED: %s %u-byte boundary\n",                      "Ciphertext is not right-aligned on a",                      cipher->blockSizeGet(cipher));        *failReason = ESP_CIPHERTEXT_ALIGN_ERROR;        return (FALSE);        }    /* decrypt packet */    /* NOTE: this will need to be changed if compressing/expanding algorithms     *       are ever introduced! (The in and out buffers are currently identical) */    cciStatus = cipher->decrypt (cipher, pDataToDecrypt, dataToDecryptLength,                                 pDataToDecrypt, &dataToDecryptLength);    if (cciStatus != CCI_SUCCESS)        {        if( cciStatus == S_cciLib_AUTHENTICATION_ERROR )            {            ipsec_printf(IPSEC_ERROR_PRINTF, "IPsec: ESP Authentication Error.\n");            *failReason = ESP_AUTHENTICATION_ERROR;            }        else            {        ipsec_printf (IPSEC_ERROR_PRINTF, "IPsec: Failed Decryption.\n");            *failReason = ESP_DECRYPTION_ERROR;            }        return (FALSE);        }#ifdef IPSEC_VERBOSE_PACKET_DEBUGGING    ike_debug_printf_bytes (IKE_ERROR_PRINTF, "== packet after decryption:", pESPPacket, ESPPacketLength);        {        char printBuf[512];        ((C_OBJ *)cipher)->toString ((C_OBJ *)cipher, (unsigned char *)printBuf, 512);        printf ("%s\n", printBuf);        }#endif    /* Lose auth info now that we're done with it */    ESPPacketLength -= digestLength; /* HMAC no longer exists as far as we're concerned */    if ( (digestLength > 0) &&         (packetBufReduceBack(pPacketBuf, digestLength) == FALSE) )        {        *failReason = ESP_PACKET_RESIZE_ERROR;        return (FALSE);        }    /* deserialize trailer: [padLength.byte][nextHeader.byte] */    padLength = wrSecDeserializeUChar (&pTrailerFields);                                    /* pTrailerFields++ */    sptr_ipsec_esp_message->next_header = (IP_TRANSPORT_PROTOCOL)wrSecDeserializeUChar (                                                                     &pTrailerFields); /* pTrailerFields++ */#ifndef WRN_SUPPRESS_INBOUND_MONOTONIC_PADDING_CHECK    if (padLength > 0)        {        UCHAR pad_count; /* RFC2406, 2.6 */        UCHAR *pPadding;        pPadding = (pESPPacket + ESPPacketLength) - (padLength + LENGTH_OF_PADLEN_AND_NEXTHDR_FIELDS);        for (pad_count = 1; pad_count <= padLength; ++pad_count)            {            if (*pPadding++ != pad_count)                {                ipsec_printf (IPSEC_WARNING_PRINTF, "IPsec: ESP processing FAILED: %s\n",                              "Padding is not a monotonic sequence 1,2,3....");                *failReason = ESP_PADDING_ERROR;                return (FALSE);                }            }        }#endif /* WRN_SUPPRESS_INBOUND_MONOTONIC_PADDING_CHECK */    /* TODO: call reduce_data_back just once, for PADLEN,NEXTHDR and auth digest? -rlm */    if (packetBufReduceBack(pPacketBuf, padLength + LENGTH_OF_PADLEN_AND_NEXTHDR_FIELDS) == FALSE)        {        ipsec_printf(IPSEC_WARNING_PRINTF, "IPsec: ERROR: ESP packet resize failure after decryption.\n");        *failReason = ESP_PACKET_RESIZE_ERROR;        return (FALSE);        }    if (IVLength > 0)        {        isAligned = ((UINT)(pESPPacket + IVLength) & (sizeof (uint32_t) - 1)) ? FALSE : TRUE;        /* shift SPI and SEQ fields forward by IVLength to delete         * the IV */        if (isAligned)            {            SPINumber = *((uint32_t *)pESPPacket);            SEQNumber = *((uint32_t *)(pESPPacket + LENGTH_OF_SPI_FIELD));            *((uint32_t *)(pESPPacket + IVLength)) = SPINumber;            *((uint32_t *)(pESPPacket + IVLength + LENGTH_OF_SPI_FIELD)) = SEQNumber;            }        else            {            /* TRACKSPR #89530: bcopy() (and therefore memcpy()) can copy past the end of             * a buffer on MIPS in certain cases. */#if (CPU_FAMILY == MIPS)            memmove (pESPPacket + IVLength, pESPPacket, LENGTH_OF_SPI_AND_SEQ_FIELDS);#else            bcopy ((char *)pESPPacket, (char *)(pESPPacket + IVLength), LENGTH_OF_SPI_AND_SEQ_FIELDS);#endif            }        if (packetBufReduceFront(pPacketBuf, IVLength) == FALSE)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -