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

📄 ipsec_esp_message.c

📁 ipsec PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
📖 第 1 页 / 共 3 页
字号:
        pOutgoingIV = pPacket + LENGTH_OF_SPI_AND_SEQ_FIELDS;        /* Generate transmitted IV and store in ESP packet now, as it is           updated during encryption */        if (AESCTRMode)            {            /* Generate Counter Block */            CTRModeCounterBlockBuild (cipher, pOutgoingIV);#if (defined IPSEC_VERBOSE_PACKET_DEBUGGING || IPSEC_VERBOSE_AES_CTR_DEBUGGING)            ike_debug_printf_bytes (IKE_ERROR_PRINTF,                                    "<AES-CTR Counter Block pre-encryption>:",                                    (unsigned char *)cipher->_pIV, cipher->IVSizeGet (cipher));#endif            }        else            {            CBCModeIVGenerate (cipher, pOutgoingIV);            }        } /* endif (IVLength > 0) */#ifdef IPSEC_VERBOSE_PACKET_DEBUGGING    ike_debug_printf_bytes (IKE_ERROR_PRINTF,                            "== packet with inserted IV:",                            pPacket,                            packetBufDataSizeGet(pPacketBuf));#endif    /* point to start of plaintext */    pPlaintext = pPacket + LENGTH_OF_SPI_AND_SEQ_FIELDS + IVLength;    /* Trailer includes:     * (max. # of padding bytes) + [PAD_LENGTH],[NEXT_MESSAGE] bytes */#ifdef IPSEC_USE_RANDOM_PADSIZE    maxTrailerLength = MAXIMUM_ESP_PAD_LENGTH + LENGTH_OF_PADLEN_AND_NEXTHDR_FIELDS;#else    maxTrailerLength = cipher->blockSizeGet (cipher) + LENGTH_OF_PADLEN_AND_NEXTHDR_FIELDS;#endif    /* To our plaintext packet, add room for:     * - trailer (padding+[PAD_LENGTH],[NEXT_FIELD]); and     * - ESP Auth's digest, if any. */    /* NOTE: packetBufWritableTrailerGet() checks if there is enough slack     *       in the rw_packet struct to give us the space we want; if so, it     *       returns a pointer to the new trailer space. In reality     *       no wrSecAlloc() is done. This just gives us a pointer within the buffer. */    pTrailerFields         = packetBufWritableTrailerGet(pPacketBuf,                                      (maxTrailerLength +                                        cipherESP->hmacDigestSizeGet(cipherESP)));    if (pTrailerFields == NULL)        {        ipsec_printf (IPSEC_ERROR_PRINTF, "IPsec: Failed Encryption (insufficient room for trailer).\n");        return (FALSE);        }    /* pad packet according to RFC2406 algorithm: 0x01,0x02,0x03,... */    padLength = cipher->padding->pad (cipher->padding, pPlaintext, plaintextLength);    /* Padding has been added to plaintext, record the increased length */    plaintextLength = plaintextLength + padLength;    pTrailerFields = pPlaintext + plaintextLength;    wrSecSerializeUChar (padLength, &pTrailerFields);                /* pTrailerFields++ */    wrSecSerializeUChar (pESPMessage->next_header, &pTrailerFields); /* pTrailerFields++ */    plaintextLength = plaintextLength + LENGTH_OF_PADLEN_AND_NEXTHDR_FIELDS;    /* NOTE: packetBufExtendBack() records that we're using some of the     *       slack space at the end of the rw_packet buffer. No wrSecAlloc() is done,     *       this just verifies the additional storage is available and adjusts     *       the meta-info associated with the rw_packet. */    if (packetBufExtendBack(pPacketBuf,                             (padLength + LENGTH_OF_PADLEN_AND_NEXTHDR_FIELDS +                            cipherESP->hmacDigestSizeGet(cipherESP)))         == FALSE)        {        return (FALSE);        }#ifdef IPSEC_VERBOSE_PACKET_DEBUGGING    ike_debug_printf_bytes (IKE_ERROR_PRINTF, "== packet after padding:", pPacket,                            packetBufDataSizeGet(pPacketBuf));    {    char printBuf[512];    ((C_OBJ *)cipher)->toString ((C_OBJ *)cipher, (unsigned char *)printBuf, 512);    printf ("%s\n", printBuf);    }#endif    /* encrypt packet */    /* NOTE: cipher object updates 4th parameter with actual encrypted packet length,             which includes padding. */    /* NOTE: CCI considers pCiphertext and ciphertextLength as     *       IN-OUT parameters so we must set them here.     */    pCiphertext = pPlaintext;    ciphertextLength = plaintextLength;    /* New single-pass interface to encryption/HMAC generation is set up here.     * The single-pass algorithm requires:     * 1) location and size of ciphertext     * 2) location and size of un-encrypted headers     * 3) location and size of destination buffer for (truncated 96-bit) digest.     */    /* ESP Authorization covers ESP Hdr: [SPI | SEQ], [IV], [ESP-PAYLOAD].     * The single-pass algorithm needs a separate pointer to the un-encrypted     * portion; in our case, the header. */    cipherESP->hmacInBufSet(cipherESP, pPacket, LENGTH_OF_SPI_AND_SEQ_FIELDS + IVLength);    /* pTrailerFields points to just beyond what it last wrote -- the PAD_LENGTH     * and NEXT_HEADER fields; thus it points to where we want the Auth data to go. */    cipherESP->hmacDigestBufSet(cipherESP, pTrailerFields);    #ifdef IPSEC_VERBOSE_PACKET_DEBUGGING    {    char printBuf[512];    ((C_OBJ *)cipher)->toString ((C_OBJ *)cipher, (unsigned char *)printBuf, 512);    printf ("%s\n", printBuf);    }    #endif    cciStatus = cipher->encrypt (cipher, pPlaintext, plaintextLength, pCiphertext, &ciphertextLength);    if (cciStatus != CCI_SUCCESS)        {        ipsec_printf (IPSEC_ERROR_PRINTF, "IPsec: Failed Encryption.\n");        return (FALSE);        }    /* We should now have [ESP HDR][ESP PAYLOAD][ESP TRAILER][HMAC Digest].     * However, IPsec uses truncated HMAC digests (96 bits for all algorithms     * as of this writing), so as a final step we chop off the least-significant     * portion. */    if( packetBufReduceBack(pPacketBuf,                            (cipherESP->hmacDigestSizeGet(cipherESP) -                              cipherESP->hmacDigestTruncSizeGet(cipherESP))) == FALSE )        {        return(FALSE);        }#ifdef IPSEC_VERBOSE_PACKET_DEBUGGING    ike_debug_printf_bytes (IKE_ERROR_PRINTF,                            "== packet after encryption:",                            pPacket,                            packetBufDataSizeGet(pPacketBuf));    if (AESCTRMode == TRUE)        {        ike_debug_printf_bytes (IKE_ERROR_PRINTF,                                "<AES-CTR Counter Block post-encryption>:",                                (unsigned char *)cipher->_pIV, cipher->IVSizeGet (cipher));        }#endif    return (TRUE);    }/******************************************************************************/UINT ipsec_esp_message_peek_at_security_parameters_index    (    IP_VI_MESSAGE *p_ip_message    )    {    PACKETBUF* pPacketBuf;    UCHAR*      bptr_packet;    UINT       spi;    pPacketBuf  = p_ip_message->pPayload;    bptr_packet = packetBufDataGet(pPacketBuf);    if (bptr_packet == NULL)        {        return (FALSE);        }    spi = wrSecDeserializeULong (&bptr_packet);    return (spi);    }/******************************************************************************/void ipsec_esp_message_get_spi_and_sequence_number    (    IPSEC_ESP_MESSAGE *sptr_ipsec_esp_message,    IP_VI_MESSAGE *p_ip_message    )    {    PACKETBUF* pPacketBuf;    UCHAR*      bptr_packet;    pPacketBuf  = p_ip_message->pPayload;    bptr_packet = packetBufDataGet(pPacketBuf);    if (bptr_packet != NULL)        {        sptr_ipsec_esp_message->spi = wrSecDeserializeULong (&bptr_packet);        sptr_ipsec_esp_message->esp_sequence_number = wrSecDeserializeULong (&bptr_packet);        }    }/******************************************************************************/void ipsec_esp_message_set_authentication_algorithm    (    IPSEC_ESP_MESSAGE *sptr_ipsec_esp_message,    IPSEC_AUTH_ALGORITHM_ID authentication_type    )    {    sptr_ipsec_esp_message->authentication_type = authentication_type;    }/******************************************************************************/void ipsec_esp_message_set_crypto_algorithm    (    IPSEC_ESP_MESSAGE *sptr_ipsec_esp_message,    IPSEC_ESP_TRANSFORM_ID crypto_algorithm    )    {    sptr_ipsec_esp_message->crypto_algorithm = crypto_algorithm;    }/******************************************************************************* ipsec_decrypt_esp_message - Decrypts the part of the esp packet.** DESCRIPTION : This decrypts the part of the esp packet from a given point *               (third  argument) of a given length.*               (specified in the fourth argument)** RETURNS : TRUE or FALSE.*/BOOL ipsec_decrypt_esp_message    (    SA_BUNDLE *sptr_ib_sa_bundle,    UCHAR *bptr_packet,    UINT packet_length,    UCHAR ** bptr_decrypted_data,    USHORT *decrypted_packet_length,    UINT *padLength,    UCHAR *next_header    )    {    UCHAR *pTrailerFields;    UINT IVLength;    UINT encrypted_packet_length;    UCHAR *bptr_encrypted_packet;    BOOL AESCTRMode;    cci_st cciStatus;    int pad;    INBOUND_ESP_SA_SPEC *sptr_ib_esp_sa_spec;    SA_SPEC *sptr_sa_spec;    CIPHER *cipher;    CIPHER_ESP *cipherESP;    UINT cciHMACAlg;	void *iterator = (void *)NULL;    AESCTRMode = FALSE;	wrSecListScanLock( sptr_ib_sa_bundle->sa_specs );	while ((sptr_sa_spec = wrSecListScan( sptr_ib_sa_bundle->sa_specs,                                           &iterator )) != NULL)        {        if (sptr_sa_spec->type == IPSEC_ESP_PROTOCOL_SPEC)            {            break;            }        }	wrSecListScanUnlock( sptr_ib_sa_bundle->sa_specs );    if (sptr_sa_spec == NULL)        {        return (FALSE);        }    sptr_ib_esp_sa_spec = (INBOUND_ESP_SA_SPEC *)sptr_sa_spec;    cipher = (CIPHER *)(&sptr_ib_esp_sa_spec->localCipher);    cipherESP = (CIPHER_ESP *)cipher;    if ((cipher->cipherGet (cipher) == CCI_CIPHER_AES)            && (cipher->modeGet (cipher) == CCI_MODE_CTR))        {        AESCTRMode = TRUE;        }    /* Temporarily disable HMAC calculation since we just want decryption here */    cciHMACAlg = cipherESP->hmacGet(cipherESP);    if( cipherESP->hmacSet(cipherESP, CCI_HMAC_NONE) != OK )        {        ipsec_printf(IPSEC_ERROR_PRINTF, "== %s: Error setting HMAC algorithm to HMAC_NONE.\n", __FUNCTION__);        return (FALSE);        }    IVLength = cipher->IVSizeGet (cipher);    if (AESCTRMode)        {        IVLength = IVLength - sizeof (UINT) - sizeof (UINT);        /* Extract IV from incoming packet, put into AES cipher counter block */        CTRModeCounterBlockIVExtractAndSet (cipher, bptr_packet + LENGTH_OF_SPI_AND_SEQ_FIELDS);        }    else        {        /* extract iv */        cipher->IVSet (cipher, (bptr_packet + LENGTH_OF_SPI_AND_SEQ_FIELDS));        }    encrypted_packet_length = packet_length - (LENGTH_OF_SPI_AND_SEQ_FIELDS + IVLength);    /* check for alignment */    if ((pad = (packet_length % cipher->blockSizeGet (cipher))) != 0)        {        encrypted_packet_length -= pad;        }    if (encrypted_packet_length <= cipher->blockSizeGet (cipher))        {        return (FALSE);        }    bptr_encrypted_packet = bptr_packet + LENGTH_OF_SPI_AND_SEQ_FIELDS + IVLength;    /* decrypt packet */    cciStatus = cipher->decrypt (cipher, bptr_encrypted_packet, encrypted_packet_length, bptr_encrypted_packet, &encrypted_packet_length);    /* Restore HMAC algorithm used by this SA */    if( cipherESP->hmacSet(cipherESP, cciHMACAlg) != OK )      {      ipsec_printf(IPSEC_ERROR_PRINTF, "== %s: Error restoring HMAC algorithm.\n", __FUNCTION__);      return (FALSE);      }    if (cciStatus != CCI_SUCCESS)        {        return (FALSE);        }    /* deserialize trailer */    pTrailerFields = (bptr_packet + packet_length) - LENGTH_OF_PADLEN_AND_NEXTHDR_FIELDS;    *bptr_decrypted_data = bptr_encrypted_packet;    *padLength = wrSecDeserializeUChar (&pTrailerFields);                          /* pTrailerFields++ */    *decrypted_packet_length = encrypted_packet_length;    *next_header = (IP_TRANSPORT_PROTOCOL)wrSecDeserializeUChar (&pTrailerFields); /* pTrailerFields++ */    return (TRUE);    }/*****************************************************************************/

⌨️ 快捷键说明

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