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

📄 ipsec_esp_message.c

📁 ipsec PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
📖 第 1 页 / 共 3 页
字号:
            {            ipsec_printf(IPSEC_WARNING_PRINTF, "IPsec: ERROR: ESP packet resize failure after IV removal.\n");            *failReason = ESP_PACKET_RESIZE_ERROR;            return (FALSE);            }        }    *failReason = SA_SPEC_SUCCESS;    return (TRUE);    } /* end ipsec_esp_message_decrypt_and_deserialize_trailer() *//******************************************************************************/BOOL ipsec_esp_message_deserialize_header    (    IPSEC_ESP_MESSAGE* sptr_ipsec_esp_message,    PACKETBUF*         pPacketBuf    )    {    UCHAR *bptr_packet;    UINT header_length;    bptr_packet = packetBufDataGet(pPacketBuf);    if (bptr_packet == NULL)        {        return (FALSE);        }    sptr_ipsec_esp_message->spi = wrSecDeserializeULong (&bptr_packet);    sptr_ipsec_esp_message->esp_sequence_number = wrSecDeserializeULong (&bptr_packet);    /* spi + sequence number */    header_length = LENGTH_OF_SPI_AND_SEQ_FIELDS;    if (packetBufReduceFront(pPacketBuf, header_length) == FALSE)        {        return (FALSE);        }    return (TRUE);    }/******************************************************************************/UINT ipsec_esp_message_serialize_header    (    IPSEC_ESP_MESSAGE* sptr_ipsec_esp_message,    PACKETBUF*         pPacketBuf    )    {    UCHAR *bptr_packet;    UINT header_length;    /* spi + sequence number */    header_length = LENGTH_OF_SPI_AND_SEQ_FIELDS;    bptr_packet = packetBufWritableHeaderGet(pPacketBuf, header_length);    if (bptr_packet == NULL)        {        return (0);        }    wrSecSerializeULong (sptr_ipsec_esp_message->spi, &bptr_packet);    wrSecSerializeULong (sptr_ipsec_esp_message->esp_sequence_number, &bptr_packet);    if (packetBufExtendFront(pPacketBuf, header_length) == FALSE)        {        return (0);        }    return (header_length);    }    /******************************************************************************/#ifndef IPSEC_NO_RANDOM_IV#define IPSEC_RAND_POOL_SIZE 4096LOCAL UCHAR randPool[IPSEC_RAND_POOL_SIZE];LOCAL UINT randPoolIndex = IPSEC_RAND_POOL_SIZE;/******************************************************************************* CBCModeRandIVGet - generate random IV for CBC mode ESP encryption** Generates a random IV for CBC mode encryption. A random pool is maintained* for outgoing IVs. If hardware is available which provides a true RNG, it is* used to fill the pool. If the default pseudo-RNG is all that is available,* this is used to fill the pool, then the pool is encrypted to add more* unpredictability.** NOTE that this routine uses taskLock()/taskUnlock() to make the update of* the pool index atomic. It is possible that a thread may read from the random* pool while it is being refilled by another thread, but this is OK as it's* meant to be random. The taskLock/taskUnlock() calls guarantee that no two* threads will reuse an IV from the pool.** RETURNS: <none>** ERRNO:** NOMANUAL*/LOCAL BOOL CBCModeRandIVGet    (    CIPHER *cipher,   /* cipher object */    UCHAR *IVBuffer,   /* buffer to receive random IV */    UINT IVBufferSize /* in bytes */    )    {    UINT localIndex; /* randPoolIndex is atomically copied here */    UINT ciphertextLength;    UINT cciHMACAlg;    cci_st cciStatus;    BOOL randAvailable;    CIPHER_ESP *cipherESP = (CIPHER_ESP *)cipher;    cciStatus = CCI_SUCCESS;    randAvailable = FALSE;      /* assume the worst */    taskLock ();    localIndex = randPoolIndex; /* MUST update atomically for thread safety! */    randPoolIndex += IVBufferSize;    taskUnlock ();    if (localIndex < IPSEC_RAND_POOL_SIZE)        {        randAvailable = TRUE;        }    else        {        /* Uh oh, not enough random data left -- refill pool */        randPoolIndex = 0;        localIndex = 0;        cciStatus = cciRand (CCI_APP_PROVIDER_ID, randPool, IPSEC_RAND_POOL_SIZE);        if (cciStatus != CCI_SUCCESS)            {            ipsec_printf (IPSEC_ERROR_PRINTF, "== Error replenishing randPool. Future IVs are NOT secure. ==\n");            }        else            {            if (cciIsNative (CCI_APP_PROVIDER_ID, CCI_CLASS_RNG, CCI_RNG_GENERIC) == FALSE)                {                /* non-default provider -- we trust it is a true RNG... */                randAvailable = TRUE;                }            else                {                /* Software RNG -- encrypt the RNG pool */                ciphertextLength = IPSEC_RAND_POOL_SIZE;                /* Temporarily disable HMAC generation -- we just want encryption */                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__);                    }                else                    {                    /* Now encrypt the pool for added obfuscation */                    cciStatus = cipher->encrypt (cipher, randPool, IPSEC_RAND_POOL_SIZE, randPool, &ciphertextLength);                    if (cciStatus != CCI_SUCCESS)                        {                        ipsec_printf (IPSEC_ERROR_PRINTF,                                      "== Error encrypting randPool. Future IVs are NOT secure. ==\n");                        }                    else                        {                        /* Restore HMAC algorithm */                        if( cipherESP->hmacSet(cipherESP,cciHMACAlg) != OK )                            {                            ipsec_printf(IPSEC_ERROR_PRINTF, "== %s: Error restoring HMAC algorithm.\n", __FUNCTION__);                            }                        else                            {                            randAvailable = TRUE;                            }                        }                    }                }            }        }    if (randAvailable == TRUE)        {        memcpy (IVBuffer, &randPool[localIndex], IVBufferSize);        cipher->IVSet (cipher, IVBuffer);        }    return randAvailable;    }  /* end CBCModeRandIVGet() */#endif /* IPSEC_NO_RANDOM_IV *//******************************************************************************/LOCAL void CBCModeIVGenerate    (    CIPHER *cipher,       /* cipher object */    unsigned char *buffer /* where to store IV */    )    {#ifdef IPSEC_NO_RANDOM_IV    /* Old ESP RFC way - just use last block of ciphertext from last packet as IV     * This is now considered insecure, so it is DISABLED by default. */    cipher->IVGet (cipher, buffer);#else    /* Generate random IVs to prevent CBC mode explicit IV attacks     * (see: http://crypto.knu.ac.kr/board/data/process/1053022220/0114_1.pdf),     *       http://www.hut.fi/~anuoppon/espiv.pdf) */    if( CBCModeRandIVGet (cipher, buffer, cipher->IVSizeGet (cipher)) == FALSE )        {        ipsec_printf(IPSEC_ERROR_PRINTF, "== %s: Future IVs are NOT secure. ==\n", __FUNCTION__);        }#endif    return;    } /* end CBCModeIVGenerate() *//******************************************************************************/LOCAL void CTRModeCounterBlockIVExtractAndSet    (    CIPHER *cipher,       /* cipher object */    unsigned char *buffer /* where to store IV */    )    {    AES_CTRBLK *pCounterBlock;    pCounterBlock = (AES_CTRBLK *)(cipher->_pIV);    /* splice in received IV */    pCounterBlock->IV[0] = *(uint32_t *)buffer;    pCounterBlock->IV[1] = *(uint32_t *)(buffer + sizeof (uint32_t));    /* reset counter field */    /* [RFC3686, 4.] Counter must be network order */    pCounterBlock->ctr = htonl (0x00000001L);    /* Tell object we've diddled IV */    cipher->IVSet (cipher, (unsigned char *)pCounterBlock);    return;    } /* end CTRModeCounterBlockIVExtractAndSet() *//******************************************************************************/LOCAL void CTRModeCounterBlockBuild    (    CIPHER *cipher,       /* cipher object */    unsigned char *buffer /* where to store IV */    )    {    AES_CTRBLK *pCounterBlock;    pCounterBlock = (AES_CTRBLK *)(cipher->_pIV);    /* increment IV [RFC3686, 3.1] */    pCounterBlock->IV[1]++;    if (pCounterBlock->IV[1] == 0L)        pCounterBlock->IV[0]++; /* carry for 64-bit CTR */    /* reset counter field */    /* [RFC3686, 4.] Counter must be network order */    pCounterBlock->ctr = htonl (0x00000001L);    /* Tell object we've diddled IV */    cipher->IVSet (cipher, (unsigned char *)pCounterBlock);    /* and finally, put transmitted portion of counter block into outgoing packet */    memcpy (buffer, &(pCounterBlock->IV), sizeof (uint64_t));    return;    } /* end CTRModeCounterBlockBuild() *//******************************************************************************/BOOL ipsec_esp_message_encrypt_and_serialize_trailer    (    IPSEC_ESP_MESSAGE* pESPMessage,    PACKETBUF*         pPacketBuf,    CIPHER*            cipher    )    {    UCHAR *pPacket;     /* pointer to entire packet ([SPI][SEQ][plaintext]) */    UCHAR *pOutgoingIV;    UCHAR *pPlaintext;  /* pointer to plaintext */    UINT plaintextLength;    UCHAR *pCiphertext; /* pointer to ciphertext */    UINT ciphertextLength;    UINT padLength;    UCHAR *pTrailerFields;    UINT IVLength;    UINT maxTrailerLength;    BOOL AESCTRMode;    cci_st cciStatus;    /* 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 */    AESCTRMode = FALSE;    pCiphertext = NULL;    padLength = 0;    pPacket = packetBufDataGet(pPacketBuf);    if (pPacket == NULL)        {        return (FALSE);        }    if ((cipher->cipherGet (cipher) == CCI_CIPHER_AES)            && (cipher->modeGet (cipher) == CCI_MODE_CTR))        {        AESCTRMode = TRUE;        }    /* TODO: Can we adapt code to use MBUF library instead of RWOS generic rw_packet funcs? -rlm */    /* NOTE: packetLength includes SPI and SEQ fields which we are NOT encrypting */    plaintextLength = packetBufDataSizeGet(pPacketBuf) - LENGTH_OF_SPI_AND_SEQ_FIELDS;    /* Ask cipher how much room we need for transmitted portion of IV     * in outgoing packet. */    IVLength = cipher->IVSizeGet (cipher);#ifdef IPSEC_VERBOSE_PACKET_DEBUGGING    printf ("== IVLength = 0x%08x\n", IVLength);    ike_debug_printf_bytes (IKE_ERROR_PRINTF, "== packet before IV insertion:", pPacket,                            packetBufDataSizeGet(pPacketBuf));#endif    if (IVLength > 0)        {        /* resize packet header to make room for IV */        /* NOTE: for AES-CTR mode, CCI treats the whole counter block as its IV,           but we only transmit a portion (the IV field of the counter block)           in the outgoing ESP packet (RFC3686). */        if (AESCTRMode)            {            IVLength = IVLength - IPSEC_AES_CTR_NONCE_SIZE - IPSEC_AES_CTR_CTR_SIZE;            }        /* TODO: Investigate moving all rw_packet() funcs used by this file into         * TODO: local funcs, hopefully inlined. -rlm */        /* NOTE: packetBufWritableHeaderGet() verifies we have enough slack         *       space before the packet to add the IV. Additionally, however,         *       since we're adding stuff before the existing plaintext, the         *       pointer to the buffer is changed (pPacket). */        if ((pPacket = packetBufWritableHeaderGet(pPacketBuf, IVLength)) == NULL)            {            return (FALSE);            }        /* NOTE: Update the meta-info to record the new size and start address         *       of the packet. */        if (packetBufExtendFront(pPacketBuf, IVLength) == FALSE)            {            return (FALSE);            }            /* Move SPI and SEQ fields back to make room for IV */            /* TRACKSPR #89530: bcopy() (and therefore memcpy()) can copy past the end of             * a buffer on MIPS in certain cases. */#if (CPU_FAMILY == MIPS)        memmove (pPacket, pPacket + IVLength, LENGTH_OF_SPI_AND_SEQ_FIELDS);#else        bcopy ((char *)(pPacket + IVLength), (char *)pPacket, LENGTH_OF_SPI_AND_SEQ_FIELDS);#endif

⌨️ 快捷键说明

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