[][openwrt][mt7988][crypto][EIP197 DDK Porting]
[Description]
Add eip197 DDK(Driver Development Kit) and firmware
to eip197 package(crypto-eip)
eip197 DDK v5.6.1
eip197b-iew firmware v3.5
[Release-log]
N/A
Change-Id: I662327ecfbdac69742bf0b50362d7c28fc06372b
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7895272
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder.c
new file mode 100644
index 0000000..84401f4
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder.c
@@ -0,0 +1,1720 @@
+/* sa_builder.c
+ *
+ * Main implementation file of the EIP-96 SA builder.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "sa_builder.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#include "basic_defs.h"
+#include "log.h"
+#include "sa_builder_internal.h"
+
+#ifdef SAB_AUTO_TOKEN_CONTEXT_GENERATION
+#include "token_builder.h"
+#endif
+
+#if defined(SAB_ENABLE_IPSEC_EXTENDED) || defined(SAB_ENABLE_BASIC_EXTENDED)
+#include "sa_builder_extended_internal.h"
+#include "firmware_eip207_api_flow_cs.h"
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+#if defined(SAB_ENABLE_IPSEC_EXTENDED) || defined(SAB_ENABLE_SSLTLS_EXTENDED)
+unsigned int LargeTransformOffset = SAB_LARGE_TRANSFORM_OFFSET;
+#else
+#define LargeTransformOffset 16
+#endif
+
+/*----------------------------------------------------------------------------
+ * SABuilderLib_CopyKeyMat
+ *
+ * Copy a key into the SA.
+ *
+ * Destination_p (input)
+ * Destination (word-aligned) of the SA record.
+ *
+ * offset (input)
+ * Word offset of the key in the SA record where it must be stored.
+ *
+ * Source_p (input)
+ * Source (byte aligned) of the data.
+ *
+ * KeyByteCount (input)
+ * Size of the key in bytes.
+ *
+ * Destination_p is allowed to be a null pointer, in which case no key
+ * will be written.
+ */
+void
+SABuilderLib_CopyKeyMat(
+ uint32_t * const Destination_p,
+ const unsigned int offset,
+ const uint8_t * const Source_p,
+ const unsigned int KeyByteCount)
+{
+ uint32_t *dst = Destination_p + offset;
+ const uint8_t *src = Source_p;
+ unsigned int i,j;
+ uint32_t w;
+ if (Destination_p == NULL)
+ return;
+ for(i=0; i < KeyByteCount / sizeof(uint32_t); i++)
+ {
+ w=0;
+ for(j=0; j<sizeof(uint32_t); j++)
+ w=(w>>8)|(*src++ << 24);
+ *dst++ = w;
+ }
+ if ((KeyByteCount % sizeof(uint32_t)) != 0)
+ {
+ w=0;
+ for(j=0; j<KeyByteCount % sizeof(uint32_t); j++)
+ {
+ w = w | (*src++ << (j*8));
+ }
+ *dst++ = w;
+ }
+}
+
+
+/*----------------------------------------------------------------------------
+ * SABuilderLib_CopyKeyMatSwap
+ *
+ * Copy a key into the SA with the words byte-swapped.
+ *
+ * Destination_p (input)
+ * Destination (word-aligned) to store the data.
+ *
+ * offset (input)
+ * Word offset of the key in the SA record where it must be stored.
+ *
+ * Source_p (input)
+ * Source (byte aligned) of the data.
+ *
+ * KeyByteCount (input)
+ * Size of the key in bytes.
+ *
+ * Destination_p is allowed to be a null pointer, in which case no key
+ * will be written.
+ */
+void
+SABuilderLib_CopyKeyMatSwap(
+ uint32_t * const Destination_p,
+ const unsigned int offset,
+ const uint8_t * const Source_p,
+ const unsigned int KeyByteCount)
+{
+ uint32_t *dst = Destination_p + offset;
+ const uint8_t *src = Source_p;
+ unsigned int i,j;
+ uint32_t w;
+
+ if (Destination_p == NULL)
+ return;
+
+ for(i=0; i < KeyByteCount / sizeof(uint32_t); i++)
+ {
+ w=0;
+
+ for(j=0; j<sizeof(uint32_t); j++)
+ w=(w<<8)|(*src++);
+
+ *dst++ = w;
+ }
+ if ((KeyByteCount % sizeof(uint32_t)) != 0)
+ {
+ w=0;
+ for(j=0; j<KeyByteCount % sizeof(uint32_t); j++)
+ {
+ w = w | (*src++ << (24 - j*8));
+ }
+ *dst++ = w;
+ }
+}
+
+
+/*----------------------------------------------------------------------------
+ * SABuilderLib_ZeroFill
+ *
+ * Fill an area in the SA with zero bytes.
+ *
+ * Destination_p (input)
+ * Destination (word-aligned) of the SA record.
+ *
+ * offset (input)
+ * Word offset of the area in the SA that must be zero-filled.
+ *
+ * ByteCount (input)
+ * Number of bytes to write.
+ *
+ * Destination_p is allowed to be a null pointer, in which case no zeroes
+ * will be written.
+ */
+void
+SABuilderLib_ZeroFill(
+ uint32_t * const Destination_p,
+ const unsigned int offset,
+ const unsigned int ByteCount)
+{
+ uint32_t *dst = Destination_p + offset;
+ unsigned int i;
+ if (Destination_p == NULL)
+ return;
+ for(i=0; i < (ByteCount + sizeof(uint32_t) - 1) / sizeof(uint32_t); i++)
+ {
+ *dst++ = 0;
+ }
+}
+
+#ifdef SAB_ARC4_STATE_IN_SA
+/*----------------------------------------------------------------------------
+ * SABuilder_AlignForARc4State
+ *
+ * Align CurrentOffset to the alignment as specified by
+ * SAB_ARC4_STATE_ALIGN_BYTE_COUNT
+ */
+static unsigned int
+SABuilder_AlignForARc4State(
+ unsigned int CurrentOffset)
+{
+#if SAB_ARC4_STATE_ALIGN_BYTE_COUNT <= 4
+ return CurrentOffset;
+#else
+ uint32_t AlignMask = (SAB_ARC4_STATE_ALIGN_BYTE_COUNT >> 2) - 1;
+ return (CurrentOffset + AlignMask) & ~AlignMask;
+#endif
+}
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetCipherKeys
+ *
+ * Fill in cipher keys and associated command word fields in SA.
+ *
+ * SAParams_p (input)
+ * The SA parameters structure from which the SA is derived.
+ *
+ * SAState_p (input, output)
+ * Variables containing information about the SA being generated.
+ *
+ * SABuffer_p (input, output).
+ * The buffer in which the SA is built. If NULL, no SA will be built, but
+ * state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ * the buffer arguments is a null pointer while the corresponding buffer
+ * would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ * is not supported on the hardware for which this SA builder
+ * is configured.
+ */
+static SABuilder_Status_t
+SABuilder_SetCipherKeys(
+ SABuilder_Params_t *const SAParams_p,
+ SABuilder_State_t * const SAState_p,
+ uint32_t * const SABuffer_p)
+{
+ /* Fill in crypto-algorithm specific parameters */
+ switch (SAParams_p->CryptoAlgo)
+ {
+ case SAB_CRYPTO_NULL: /* Null crypto, do nothing */
+ break;
+#ifdef SAB_ENABLE_CRYPTO_3DES
+ case SAB_CRYPTO_DES:
+ SAState_p->CipherKeyWords = 2;
+ SAState_p->IVWords = 2;
+ SAState_p->CW0 |= SAB_CW0_CRYPTO_DES;
+ break;
+ case SAB_CRYPTO_3DES:
+ SAState_p->CipherKeyWords = 6;
+ SAState_p->IVWords = 2;
+ SAState_p->CW0 |= SAB_CW0_CRYPTO_3DES;
+ break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_AES
+ case SAB_CRYPTO_AES:
+ switch (SAParams_p->KeyByteCount)
+ {
+ case 16:
+ SAState_p->CW0 |= SAB_CW0_CRYPTO_AES_128;
+ SAState_p->CipherKeyWords = 4;
+ break;
+ case 24:
+ SAState_p->CW0 |= SAB_CW0_CRYPTO_AES_192;
+ SAState_p->CipherKeyWords = 6;
+ break;
+ case 32:
+ SAState_p->CW0 |= SAB_CW0_CRYPTO_AES_256;
+ SAState_p->CipherKeyWords = 8;
+ break;
+ default:
+ LOG_CRIT("SABuilder: Bad key size for AES.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ SAState_p->IVWords = 4;
+ break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_ARCFOUR
+ case SAB_CRYPTO_ARCFOUR:
+ SAState_p->CW0 |= SAB_CW0_CRYPTO_ARC4;
+ if (SAParams_p->KeyByteCount < 5 ||
+ SAParams_p->KeyByteCount > 16)
+ {
+ LOG_CRIT("SABuilder: Bad key size for ARCFOUR.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ SAState_p->CW1 |= SAParams_p->KeyByteCount;
+ SAState_p->CipherKeyWords =
+ ((unsigned int)SAParams_p->KeyByteCount + sizeof(uint32_t) - 1) /
+ sizeof(uint32_t);
+
+ if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_STATELESS)
+ {
+ SAState_p->ARC4State = true;
+ SAState_p->CW1 |= SAB_CW1_ARC4_IJ_PTR | SAB_CW1_ARC4_STATE_SEL |
+ SAB_CW1_CRYPTO_STORE;
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_SM4
+ case SAB_CRYPTO_SM4:
+ SAState_p->CipherKeyWords = 4;
+ SAState_p->IVWords = 4;
+ SAState_p->CW0 |= SAB_CW0_CRYPTO_SM4;
+ break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_BC0
+ case SAB_CRYPTO_BC0:
+ SAState_p->CipherKeyWords = 8;
+ SAState_p->IVWords = 4;
+ SAState_p->CW0 |= SAB_CW0_CRYPTO_BC0 +
+ ((SAParams_p->CryptoParameter & 0x3) << 17) ;
+ SAState_p->CW1 |= SAB_CW1_EXT_CIPHER_SET;
+ break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_KASUMI
+ case SAB_CRYPTO_KASUMI:
+ SAState_p->CipherKeyWords = 4;
+ SAState_p->IVWords = 0;
+ SAState_p->CW0 |= SAB_CW0_CRYPTO_KASUMI;
+ break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_SNOW
+ case SAB_CRYPTO_SNOW:
+ SAState_p->CipherKeyWords = 4;
+ SAState_p->IVWords = 4;
+ SAState_p->CW0 |= SAB_CW0_CRYPTO_SNOW;
+ break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_ZUC
+ case SAB_CRYPTO_ZUC:
+ SAState_p->CipherKeyWords = 4;
+ SAState_p->IVWords = 4;
+ SAState_p->CW0 |= SAB_CW0_CRYPTO_ZUC;
+ break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_CHACHAPOLY
+ case SAB_CRYPTO_CHACHA20:
+ SAState_p->CW0 |= SAB_CW0_CRYPTO_CHACHA20;
+ switch (SAParams_p->KeyByteCount)
+ {
+ case 16:
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA128;
+ SAState_p->CipherKeyWords = 4;
+ break;
+ case 32:
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA256;
+ SAState_p->CipherKeyWords = 8;
+ break;
+ default:
+ LOG_CRIT("SABuilder: Bad key size for Chacha20.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ break;
+#endif
+ default:
+ LOG_CRIT("SABuilder: Unsupported crypto algorithm\n");
+ return SAB_UNSUPPORTED_FEATURE;
+ }
+
+ /* Check block cipher length against provided key */
+ if (SAParams_p->CryptoAlgo != SAB_CRYPTO_ARCFOUR &&
+ SAState_p->CipherKeyWords*sizeof(uint32_t) != SAParams_p->KeyByteCount)
+ {
+ LOG_CRIT("SABuilder: Bad cipher key size..\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+#ifdef SAB_STRICT_ARGS_CHECK
+ if ( SAState_p->CipherKeyWords > 0 && SAParams_p->Key_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer for Key_p.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+
+#ifdef SAB_ENABLE_CRYPTO_CHACHAPOLY
+ if (SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20 &&
+ SAParams_p->KeyByteCount == 16)
+ {
+ /* Copy the key twice for 128-bit Chacha20 */
+ SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+ SAParams_p->Key_p, SAParams_p->KeyByteCount);
+ SAState_p->CurrentOffset += SAState_p->CipherKeyWords;
+ }
+#endif
+ /* Copy the cipher key */
+ SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+ SAParams_p->Key_p, SAParams_p->KeyByteCount);
+
+ if (SAParams_p->CryptoAlgo == SAB_CRYPTO_ARCFOUR)
+ SAState_p->CurrentOffset += 4; /* Always use 4 words for key in ARC4*/
+ else
+ SAState_p->CurrentOffset += SAState_p->CipherKeyWords;
+
+ /* Check that wireless algorithms are not used with authentication */
+ if ((SAParams_p->CryptoAlgo == SAB_CRYPTO_KASUMI ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_SNOW ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_ZUC) &&
+ SAParams_p->AuthAlgo != SAB_AUTH_NULL)
+ {
+ LOG_CRIT("SABuilder: "
+ "Crypto algorithm cannot be combined with authentication.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* Handle feedback modes */
+ if (SAParams_p->CryptoAlgo == SAB_CRYPTO_DES ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_3DES ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_AES ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_SM4 ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_BC0)
+ {
+ switch (SAParams_p->CryptoMode)
+ {
+ case SAB_CRYPTO_MODE_ECB:
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_ECB;
+ SAState_p->IVWords = 0;
+ break;
+ case SAB_CRYPTO_MODE_CBC:
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CBC;
+ break;
+ case SAB_CRYPTO_MODE_CFB:
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CFB;
+ break;
+ case SAB_CRYPTO_MODE_OFB:
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_OFB;
+ break;
+ case SAB_CRYPTO_MODE_CTR:
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR;
+ break;
+ case SAB_CRYPTO_MODE_ICM:
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_ICM;
+ break;
+ case SAB_CRYPTO_MODE_CCM:
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR_LOAD;
+ if (SAParams_p->AuthAlgo != SAB_AUTH_AES_CCM)
+ {
+ LOG_CRIT("SABuilder: crypto CCM requires auth CCM.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ break;
+ case SAB_CRYPTO_MODE_GCM:
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR;
+ if (SAParams_p->AuthAlgo != SAB_AUTH_AES_GCM)
+ {
+ LOG_CRIT("SABuilder: crypto GCM requires auth GCM.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ break;
+ case SAB_CRYPTO_MODE_GMAC:
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR;
+ if (SAParams_p->AuthAlgo != SAB_AUTH_AES_GMAC)
+ {
+ LOG_CRIT("SABuilder: crypto GMAC requires auth GMAC.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ break;
+#ifdef SAB_ENABLE_CRYPTO_XTS
+ case SAB_CRYPTO_MODE_XTS:
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_XTS;
+ if (SAParams_p->AuthAlgo != SAB_AUTH_NULL)
+ {
+ LOG_CRIT("SABuilder: crypto AES-XTS requires auth NULL.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ break;
+ case SAB_CRYPTO_MODE_XTS_STATEFUL:
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_XTS | SAB_CW1_XTS_STATEFUL;
+ if (SAParams_p->AuthAlgo != SAB_AUTH_NULL)
+ {
+ LOG_CRIT("SABuilder: crypto AES-XTS requires auth NULL.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ break;
+#endif
+ default:
+ LOG_CRIT("SABuilder: Invalid crypto mode.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ }
+ else if (SAParams_p->CryptoAlgo == SAB_CRYPTO_KASUMI ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_SNOW ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_ZUC)
+ {
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_F8 ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_UEA2 ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_EEA3)
+
+ {
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_F8_UEA;
+ }
+ else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_BASIC ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_ECB)
+ {
+ // Do nothing.
+ }
+ else
+ {
+ LOG_CRIT("SABuilder: Invalid crypto mode for wireless .\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ }
+
+#ifdef SAB_ENABLE_CRYPTO_CHACHAPOLY
+ else if (SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+ {
+ SAState_p->IVWords = 4;
+ if (SAParams_p->AuthAlgo == SAB_AUTH_POLY1305 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_POLY1305)
+ {
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA_CTR32 |
+ SAB_CW1_CRYPTO_AEAD;
+ }
+ else if (SAParams_p->AuthAlgo == SAB_AUTH_NULL)
+ {
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CHACHA_CTR64)
+ {
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA_CTR64;
+ }
+ else
+ {
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CHACHA_CTR32;
+ }
+ }
+ else
+ {
+ LOG_CRIT("SABuilder: Invalid authentication mode for Chacha20 .\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ }
+#endif
+
+ /* The following crypto modes can only be used with AES */
+ if ( (SAParams_p->CryptoMode==SAB_CRYPTO_MODE_CCM ||
+ SAParams_p->CryptoMode==SAB_CRYPTO_MODE_GCM ||
+ SAParams_p->CryptoMode==SAB_CRYPTO_MODE_GMAC ||
+ SAParams_p->CryptoMode==SAB_CRYPTO_MODE_XTS ||
+ SAParams_p->CryptoMode==SAB_CRYPTO_MODE_XTS_STATEFUL) &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_AES)
+ {
+ LOG_CRIT("SABuilder: crypto mode requires AES.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ /* The following crypto modes can only be used with AES or SM4 */
+ if ( (SAParams_p->CryptoMode==SAB_CRYPTO_MODE_CTR ||
+ SAParams_p->CryptoMode==SAB_CRYPTO_MODE_ICM) &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_AES &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_SM4 &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_BC0)
+ {
+ LOG_CRIT("SABuilder: crypto mode requires AES or SM4.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ return SAB_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetAuthSizeAndMode
+ *
+ * Determine the size of the authentication keys and set the required mode
+ * bits in the control words.
+ *
+ * SAParams_p (input)
+ * The SA parameters structure from which the SA is derived.
+ *
+ * SAState_p (input, output)
+ * Variables containing information about the SA being generated.
+ *
+ * Auth1Words_p (output)
+ * The number of 32-bit words of the first authentication key.
+ *
+ * Auth2Words_p (output)
+ * The number of 32-bit words of the second authentication key.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ * the buffer arguments is a null pointer while the corresponding buffer
+ * would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ * is not supported on the hardware for which this SA builder
+ * is configured.
+ */
+static SABuilder_Status_t
+SABuilder_SetAuthSizeAndMode(
+ SABuilder_Params_t *const SAParams_p,
+ SABuilder_State_t * const SAState_p,
+ uint32_t * const Auth1Words_p,
+ uint32_t * const Auth2Words_p)
+{
+ unsigned int Auth1Words = 0;
+ unsigned int Auth2Words = 0;
+
+ switch (SAParams_p->AuthAlgo)
+ {
+ case SAB_AUTH_NULL:
+ break;
+#ifdef SAB_ENABLE_AUTH_MD5
+ case SAB_AUTH_HASH_MD5:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HASH_MD5;
+ if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+ SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+ {
+ SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+ Auth1Words = 4;
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA1
+ case SAB_AUTH_HASH_SHA1:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA1;
+ if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+ SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+ {
+ SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+ Auth1Words = 5;
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA2_256
+ case SAB_AUTH_HASH_SHA2_224:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA2_224;
+ if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+ SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+ {
+ SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+ Auth1Words = 8;
+ }
+ break;
+ case SAB_AUTH_HASH_SHA2_256:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA2_256;
+ if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+ SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+ {
+ SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+ Auth1Words = 8;
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA2_512
+ case SAB_AUTH_HASH_SHA2_384:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA2_384;
+ if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+ SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+ {
+ SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+ Auth1Words = 16;
+ }
+ break;
+ case SAB_AUTH_HASH_SHA2_512:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA2_512;
+ if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+ SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+ {
+ SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+ Auth1Words = 16;
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA3
+ case SAB_AUTH_HASH_SHA3_224:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA3_224;
+ if ((SAParams_p->flags & SAB_FLAG_HASH_SAVE) != 0)
+ {
+ Auth1Words = 36;
+ }
+ break;
+ case SAB_AUTH_HASH_SHA3_256:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA3_256;
+ if ((SAParams_p->flags & SAB_FLAG_HASH_SAVE) != 0)
+ {
+ Auth1Words = 34;
+ }
+ break;
+ case SAB_AUTH_HASH_SHA3_384:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA3_384;
+ if ((SAParams_p->flags & SAB_FLAG_HASH_SAVE) != 0)
+ {
+ Auth1Words = 26;
+ }
+ break;
+ case SAB_AUTH_HASH_SHA3_512:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SHA3_512;
+ if ((SAParams_p->flags & SAB_FLAG_HASH_SAVE) != 0)
+ {
+ Auth1Words = 18;
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SM3
+ case SAB_AUTH_HASH_SM3:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HASH_SM3;
+ if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+ SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+ {
+ SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+ Auth1Words = 8;
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_AUTH_MD5
+ case SAB_AUTH_SSLMAC_MD5:
+ case SAB_AUTH_HMAC_MD5:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_MD5;
+ Auth1Words = 4;
+ Auth2Words = 4;
+ break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA1
+ case SAB_AUTH_SSLMAC_SHA1:
+ SAState_p->CW0 |= SAB_CW0_AUTH_SSLMAC_SHA1;
+ Auth1Words = 5;
+ break;
+ case SAB_AUTH_HMAC_SHA1:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA1;
+ Auth1Words = 5;
+ Auth2Words = 5;
+ break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA2_256
+ case SAB_AUTH_HMAC_SHA2_224:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA2_224;
+ Auth1Words = 8;
+ Auth2Words = 8;
+ break;
+ case SAB_AUTH_HMAC_SHA2_256:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA2_256;
+ Auth1Words = 8;
+ Auth2Words = 8;
+ break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA2_512
+ case SAB_AUTH_HMAC_SHA2_384:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA2_384;
+ Auth1Words = 16;
+ Auth2Words = 16;
+ break;
+ case SAB_AUTH_HMAC_SHA2_512:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA2_512;
+ Auth1Words = 16;
+ Auth2Words = 16;
+ break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SHA3
+ case SAB_AUTH_KEYED_HASH_SHA3_224:
+ SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_SHA3_224;
+ SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+ Auth1Words = 36;
+ break;
+ case SAB_AUTH_KEYED_HASH_SHA3_256:
+ SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_SHA3_256;
+ SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+ Auth1Words = 34;
+ break;
+ case SAB_AUTH_KEYED_HASH_SHA3_384:
+ SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_SHA3_384;
+ SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+ Auth1Words = 26;
+ break;
+ case SAB_AUTH_KEYED_HASH_SHA3_512:
+ SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_SHA3_512;
+ SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+ Auth1Words = 18;
+ break;
+ case SAB_AUTH_HMAC_SHA3_224:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA3_224;
+ Auth1Words = 36;
+ break;
+ case SAB_AUTH_HMAC_SHA3_256:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA3_256;
+ Auth1Words = 34;
+ break;
+ case SAB_AUTH_HMAC_SHA3_384:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA3_384;
+ Auth1Words = 26;
+ break;
+ case SAB_AUTH_HMAC_SHA3_512:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SHA3_512;
+ Auth1Words = 18;
+ break;
+#endif
+#ifdef SAB_ENABLE_AUTH_SM3
+ case SAB_AUTH_HMAC_SM3:
+ SAState_p->CW0 |= SAB_CW0_AUTH_HMAC_SM3;
+ Auth1Words = 8;
+ Auth2Words = 8;
+ break;
+#endif
+ case SAB_AUTH_AES_XCBC_MAC:
+ case SAB_AUTH_AES_CMAC_128:
+ SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_128;
+ Auth1Words = 4;
+ Auth2Words = 4;
+ break;
+ case SAB_AUTH_AES_CMAC_192:
+ SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_192;
+ Auth1Words = 6;
+ Auth2Words = 4;
+ break;
+ case SAB_AUTH_AES_CMAC_256:
+ SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_256;
+ Auth1Words = 8;
+ Auth2Words = 4;
+ break;
+ case SAB_AUTH_AES_CCM:
+ if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CCM)
+ {
+ LOG_CRIT("SABuilder: auth CCM requires crypto CCM.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ switch (SAParams_p->KeyByteCount)
+ {
+ case 16:
+ Auth1Words = 4;
+ SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_128;
+ break;
+ case 24:
+ Auth1Words = 6;
+ SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_192;
+ break;
+ case 32:
+ Auth1Words = 8;
+ SAState_p->CW0 |= SAB_CW0_AUTH_CMAC_256;
+ break;
+ }
+ Auth2Words = 4;
+ SAState_p->CW1 |= SAB_CW1_ENCRYPT_HASHRES;
+ break;
+#ifdef SAB_ENABLE_CRYPTO_GCM
+ case SAB_AUTH_AES_GCM:
+ if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GCM)
+ {
+ LOG_CRIT("SABuilder: auth GCM requires crypto GCM.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ SAState_p->CW0 |= SAB_CW0_AUTH_GHASH;
+ Auth1Words = 4;
+ SAState_p->CW1 |= SAB_CW1_ENCRYPT_HASHRES;
+ break;
+ case SAB_AUTH_AES_GMAC:
+ if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GMAC)
+ {
+ LOG_CRIT("SABuilder: auth GMAC requires crypto GMAC.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ SAState_p->CW0 |= SAB_CW0_AUTH_GHASH;
+ Auth1Words = 4;
+ SAState_p->CW1 |= SAB_CW1_ENCRYPT_HASHRES;
+ break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_KASUMI
+ case SAB_AUTH_KASUMI_F9:
+ if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+ {
+ LOG_CRIT("SABuilder: auth KASUMI requires crypto NULL.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ Auth1Words = 4;
+ SAState_p->CW0 |= SAB_CW0_AUTH_KASUMI_F9;
+ break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_SNOW
+ case SAB_AUTH_SNOW_UIA2:
+ if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+ {
+ LOG_CRIT("SABuilder: auth SNOW requires crypto NULL.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ Auth1Words = 4;
+ SAState_p->CW0 |= SAB_CW0_AUTH_SNOW_UIA2;
+ break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_ZUC
+ case SAB_AUTH_ZUC_EIA3:
+ if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+ {
+ LOG_CRIT("SABuilder: auth ZUC requires crypto NULL.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ Auth1Words = 4;
+ SAState_p->CW0 |= SAB_CW0_AUTH_ZUC_EIA3;
+ break;
+#endif
+#ifdef SAB_ENABLE_CRYPTO_CHACHAPOLY
+ case SAB_AUTH_KEYED_HASH_POLY1305:
+ if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+ {
+ LOG_CRIT("SABuilder: auth keyed Poly1305 requires crypto NULL.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ if ((SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+ SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+ {
+ SAState_p->CW0 |= SAB_CW0_HASH_LOAD_DIGEST;
+ Auth1Words = 4;
+ Auth2Words = 8;
+ }
+ else
+ {
+ Auth1Words = 8;
+ }
+ SAState_p->CW0 |= SAB_CW0_AUTH_KEYED_HASH_POLY1305;
+ break;
+ case SAB_AUTH_POLY1305:
+ if (SAParams_p->CryptoAlgo != SAB_CRYPTO_CHACHA20)
+ {
+ LOG_CRIT("SABuilder: auth Poly1305 requires crypto Chacha20.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ SAState_p->CW0 |= SAB_CW0_AUTH_POLY1305;
+ SAState_p->CW1 |= SAB_CW1_IV_CTR|SAB_CW1_CRYPTO_MODE_CHACHA_POLY_OTK;
+ SAState_p->CW1 |= SAB_CW1_ENCRYPT_HASHRES;
+ break;
+#endif
+ default:
+ LOG_CRIT("SABuilder: Unsupported authentication algorithm\n");
+ return SAB_UNSUPPORTED_FEATURE;
+ }
+
+ *Auth1Words_p = Auth1Words;
+ *Auth2Words_p = Auth2Words;
+ return SAB_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetAuthKeys
+ *
+ * Fill in authentication keys and associated command word fields in SA.
+ *
+ * SAParams_p (input)
+ * The SA parameters structure from which the SA is derived.
+ *
+ * SAState_p (input, output)
+ * Variables containing information about the SA being generated.
+ *
+ * SABuffer_p (input, output).
+ * The buffer in which the SA is built. If NULL, no SA will be built, but
+ * state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ * the buffer arguments is a null pointer while the corresponding buffer
+ * would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ * is not supported on the hardware for which this SA builder
+ * is configured.
+ */
+static SABuilder_Status_t
+SABuilder_SetAuthKeys(
+ SABuilder_Params_t *const SAParams_p,
+ SABuilder_State_t * const SAState_p,
+ uint32_t * const SABuffer_p)
+{
+ unsigned int Auth1Words = 0;
+ unsigned int Auth2Words = 0;
+ SABuilder_Status_t Rc;
+
+ Rc = SABuilder_SetAuthSizeAndMode(SAParams_p,
+ SAState_p,
+ &Auth1Words,
+ &Auth2Words);
+ if (Rc != SAB_STATUS_OK)
+ {
+ return Rc;
+ }
+
+ /* Now copy the authentication keys, if applicable */
+ if (SAParams_p->AuthAlgo == SAB_AUTH_AES_CCM)
+ {
+ SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
+ SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset, 32);
+ /* Fill zero blocks for the XCBC MAC subkeys */
+ SAState_p->CurrentOffset += 8;
+ SABuilderLib_CopyKeyMatSwap(SABuffer_p, SAState_p->CurrentOffset,
+ SAParams_p->Key_p,
+ SAParams_p->KeyByteCount);
+ SAState_p->CurrentOffset += SAState_p->CipherKeyWords;
+
+ if (SAState_p->CipherKeyWords == 6)
+ {
+ SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset, 8);
+ SAState_p->CurrentOffset += 2; /* Pad key to 256 bits for CCM-192*/
+ }
+ }
+ else if (SAParams_p->AuthAlgo == SAB_AUTH_AES_XCBC_MAC ||
+ SAParams_p->AuthAlgo == SAB_AUTH_AES_CMAC_128 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_AES_CMAC_192 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_AES_CMAC_256)
+ {
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p->AuthKey1_p == NULL ||
+ SAParams_p->AuthKey2_p == NULL ||
+ SAParams_p->AuthKey3_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer AuthKey supplied\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
+ SABuilderLib_CopyKeyMatSwap(SABuffer_p, SAState_p->CurrentOffset,
+ SAParams_p->AuthKey2_p,
+ 4 * sizeof(uint32_t));
+ SABuilderLib_CopyKeyMatSwap(SABuffer_p, SAState_p->CurrentOffset + 4,
+ SAParams_p->AuthKey3_p,
+ 4 * sizeof(uint32_t));
+ SABuilderLib_CopyKeyMatSwap(SABuffer_p, SAState_p->CurrentOffset + 8,
+ SAParams_p->AuthKey1_p,
+ Auth1Words * sizeof(uint32_t));
+ SAState_p->CurrentOffset += 8 + Auth1Words;
+ if (Auth1Words == 6)
+ {
+ SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset, 8);
+ SAState_p->CurrentOffset += 2; /* Pad key to 256 bits for CMAC-192*/
+ }
+ }
+#ifdef SAB_ENABLE_AUTH_SHA3
+ else if (SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA3_224 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA3_256 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA3_384 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA3_512 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_224 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_256 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_384 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_512 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_HMAC_SHA3_224 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_HMAC_SHA3_256 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_HMAC_SHA3_384 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_HMAC_SHA3_512)
+ {
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (Auth1Words > 0)
+ {
+ if (SAParams_p->AuthKey1_p == NULL &&
+ SAParams_p->AuthKeyByteCount > 0)
+ {
+ LOG_CRIT("SABuilder: NULL pointer AuthKey supplied\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ if (SAParams_p->AuthKeyByteCount > Auth1Words * sizeof(uint32_t))
+ {
+ LOG_CRIT("SABuilder: Authentication key too long\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
+ SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset,
+ Auth1Words * sizeof(uint32_t));
+
+ SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+ SAParams_p->AuthKey1_p,
+ SAParams_p->AuthKeyByteCount);
+
+ SAState_p->CurrentOffset += Auth1Words;
+
+ if (SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_224 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_256 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_384 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_KEYED_HASH_SHA3_512)
+ {
+ if (SAParams_p->AuthKeyByteCount <
+ Auth1Words * sizeof(uint32_t))
+ {
+ // Put the key length in last byte of key if it is smaller
+ // than the maximum.
+ SAState_p->CW1 |= SAB_CW1_DIGEST_CNT;
+ if (SABuffer_p != NULL)
+ {
+ SABuffer_p[SAState_p->CurrentOffset - 1] |=
+ (SAParams_p->AuthKeyByteCount << 24);
+ }
+ }
+ }
+ }
+ }
+#endif
+ else if(Auth1Words > 0 && Auth2Words > 0 &&
+ SAParams_p->AuthKey1_p == NULL && SAParams_p->AuthKey2_p == NULL)
+ {
+ /* HMAC precomputes not given, allow later computation of
+ precomputes. */
+ SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
+ SAParams_p->OffsetDigest1 = SAState_p->CurrentOffset + Auth1Words;
+ SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset,
+ (Auth1Words + Auth2Words) * sizeof(uint32_t));
+ SAState_p->CurrentOffset += Auth1Words + Auth2Words;
+ }
+ else
+ {
+ if (Auth1Words > 0)
+ {
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p->AuthKey1_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer AuthKey supplied\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SAParams_p->OffsetDigest0 = SAState_p->CurrentOffset;
+ SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+ SAParams_p->AuthKey1_p,
+ Auth1Words * sizeof(uint32_t));
+ SAState_p->CurrentOffset += Auth1Words;
+
+ if (SAParams_p->AuthAlgo == SAB_AUTH_SSLMAC_SHA1)
+ { /* both inner and outer digest fields must be set, even though
+ only one is used. */
+ SABuilderLib_ZeroFill(SABuffer_p, SAState_p->CurrentOffset,
+ Auth1Words * sizeof(uint32_t));
+ SAState_p->CurrentOffset += Auth1Words;
+ }
+ }
+ if (Auth2Words > 0)
+ {
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p->AuthKey2_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer AuthKey supplied\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SAParams_p->OffsetDigest1 = SAState_p->CurrentOffset;
+ SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+ SAParams_p->AuthKey2_p,
+ Auth2Words * sizeof(uint32_t));
+ SAState_p->CurrentOffset += Auth2Words;
+ }
+ }
+
+ return SAB_STATUS_OK;
+}
+
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_GetSizes
+ *
+ * Compute the required sizes in 32-bit words of any of up to three memory
+ * areas used by the SA.
+ *
+ * SAParams_p (input)
+ * Pointer to the SA parameters structure.
+ *
+ * SAWord32Count_p (output)
+ * The size of the normal SA buffer.
+ *
+ * SAStateWord32Count_p (output)
+ * The size of any SA state record.
+ *
+ * ARC4StateWord32Count_p (output) T
+ * The size of any ARCFOUR state buffer (output).
+ *
+ * When the SA state record or ARCFOUR state buffer are not required by
+ * the packet engine for this transform, the corresponding size outputs
+ * are returned as zero. The Security-IP-96 never requires these buffers
+ *
+ * If any of the output parameters is a null pointer,
+ * the corresponding size will not be returned.
+ *
+ * The SAParams_p structure must be fully filled in: it must have the
+ * same contents as it would have when SABuilder_BuildSA is called.
+ * This function calls the same routines as SABuilder_BuildSA, but with
+ * null pointers instead of the SA pointer, so no actual SA will be built.
+ * These functions are only called to obtain the length of the SA.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when the record referenced by SAParams_p is invalid,
+ */
+SABuilder_Status_t
+SABuilder_GetSizes(
+ SABuilder_Params_t *const SAParams_p,
+ unsigned int *const SAWord32Count_p,
+ unsigned int *const SAStateWord32Count_p,
+ unsigned int *const ARC4StateWord32Count_p)
+{
+ SABuilder_State_t SAState;
+ int rc;
+
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p == NULL)
+ {
+ LOG_CRIT("SABuilder_GetSizes: NULL pointer SAParams_p supplied\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+
+ SAState.CurrentOffset = 2; /* Count Control words 0 and 1 */
+ SAState.CW0 = 0;
+ SAState.CW1 = 0;
+ SAState.CipherKeyWords = 0;
+ SAState.IVWords = 0;
+ SAState.ARC4State = false;
+ SAState.fLarge = false;
+ SAState.fLargeMask = false;
+
+ rc = SABuilder_SetCipherKeys(SAParams_p, &SAState, NULL);
+ if (rc != SAB_STATUS_OK)
+ return rc;
+
+ rc = SABuilder_SetAuthKeys(SAParams_p, &SAState, NULL);
+ if (rc != SAB_STATUS_OK)
+ return rc;
+
+ switch ( SAParams_p->protocol)
+ {
+#ifdef SAB_ENABLE_PROTO_BASIC
+ case SAB_PROTO_BASIC:
+ {
+ rc = SABuilder_SetBasicParams(SAParams_p, &SAState, NULL);
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_PROTO_IPSEC
+ case SAB_PROTO_IPSEC:
+ {
+ rc = SABuilder_SetIPsecParams(SAParams_p, &SAState, NULL);
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_PROTO_SSLTLS
+ case SAB_PROTO_SSLTLS:
+ {
+ rc = SABuilder_SetSSLTLSParams(SAParams_p, &SAState, NULL);
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_PROTO_SRTP
+ case SAB_PROTO_SRTP:
+ {
+ rc = SABuilder_SetSRTPParams(SAParams_p, &SAState, NULL);
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_PROTO_MACSEC
+ case SAB_PROTO_MACSEC:
+ {
+ rc = SABuilder_SetMACsecParams(SAParams_p, &SAState, NULL);
+ }
+ break;
+#endif
+ default:
+ LOG_CRIT("SABuilder_GetSizes: unsupported protocol\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ if (rc != SAB_STATUS_OK)
+ return rc;
+
+ if (SAState.ARC4State)
+ {
+ SAState.CurrentOffset += 2; /* Count IJ pointer and ARC4 State */
+ }
+
+ if (SAState.CurrentOffset == 2)
+ {
+ SAState.CurrentOffset += 1;
+ /* Make sure to have at least one non-context word */
+ }
+
+#ifdef SAB_ENABLE_FIXED_RECORD_SIZE
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+#ifdef SAB_ENABLE_IPSEC_EXTENDED
+ /* It is possible that a record will have to be
+ large because of options used by firmware, so determine if the record
+ needs to be large. */
+ if (SAParams_p->protocol == SAB_PROTO_IPSEC)
+ {
+ SABuilder_Status_t res;
+ res = SABuilder_SetExtendedIPsecParams(SAParams_p,
+ &SAState,
+ NULL);
+ if (res != SAB_STATUS_OK)
+ return res;
+ }
+#endif
+#ifdef SAB_ENABLE_DTLS_EXTENDED
+ if (SAParams_p->protocol == SAB_PROTO_SSLTLS)
+ {
+ SABuilder_Status_t res;
+ res = SABuilder_SetExtendedDTLSParams(SAParams_p, &SAState, NULL);
+ if (res != SAB_STATUS_OK)
+ return res;
+ }
+#endif
+#ifdef SAB_ENABLE_MACSEC_EXTENDED
+ if (SAParams_p->protocol == SAB_PROTO_MACSEC)
+ {
+ SABuilder_Status_t res;
+ res = SABuilder_SetExtendedMACsecParams(SAParams_p,
+ &SAState,
+ NULL);
+ if (res != SAB_STATUS_OK)
+ return res;
+ }
+#endif
+#ifdef SAB_ENABLE_BASIC_EXTENDED
+ if (SAParams_p->protocol == SAB_PROTO_BASIC)
+ {
+ SABuilder_Status_t res;
+ res = SABuilder_SetExtendedBasicParams(SAParams_p,
+ &SAState,
+ NULL);
+ if (res != SAB_STATUS_OK)
+ return res;
+ }
+#endif
+ if (SAParams_p->OffsetSeqNum <= SAB_SEQNUM_LO_FIX_OFFSET &&
+ !SAState.fLarge)
+ {
+ SAState.CurrentOffset = SAB_RECORD_WORD_COUNT;
+ }
+ else if (SAState.CurrentOffset <= SAB_RECORD_WORD_COUNT + LargeTransformOffset)
+ {
+ SAState.CurrentOffset = SAB_RECORD_WORD_COUNT + LargeTransformOffset;
+ }
+ else
+ {
+ LOG_CRIT("SABuilder_GetSizes: SA filled beyond record size.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#else
+ if (SAState.CurrentOffset > SAB_RECORD_WORD_COUNT)
+ {
+ LOG_CRIT("SABuilder_GetSizes: SA filled beyond record size.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ SAState.CurrentOffset = SAB_RECORD_WORD_COUNT;
+ /* Make the SA record a fixed size for engines that have
+ record caches */
+#endif
+#endif
+
+ if (SAStateWord32Count_p != NULL)
+ *SAStateWord32Count_p = 0;
+
+#ifdef SAB_ARC4_STATE_IN_SA
+ if (ARC4StateWord32Count_p != NULL)
+ *ARC4StateWord32Count_p = 0;
+ if (SAState.ARC4State)
+ {
+ if (SAParams_p->OffsetARC4StateRecord > 0)
+ {
+ if (SAParams_p->OffsetARC4StateRecord < SAState.CurrentOffset)
+ {
+ LOG_CRIT("SABuilder_GetSizes: OffsetARC4StateRecord too low\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ SAState.CurrentOffset = SAParams_p->OffsetARC4StateRecord + 64;
+ }
+ else
+ {
+ SAState.CurrentOffset =
+ SABuilder_AlignForARc4State(SAState.CurrentOffset);
+ SAState.CurrentOffset += 64;
+ }
+ }
+#else
+ if (ARC4StateWord32Count_p != NULL)
+ {
+ if (SAState.ARC4State)
+ {
+ *ARC4StateWord32Count_p = 64;
+ }
+ else
+ {
+ *ARC4StateWord32Count_p = 0;
+ }
+ }
+#endif
+#ifdef SAB_AUTO_TOKEN_CONTEXT_GENERATION
+ {
+ TokenBuilder_Status_t rc;
+ unsigned int ContextSize;
+ rc = TokenBuilder_GetContextSize(SAParams_p, &ContextSize);
+ if (rc != TKB_STATUS_OK)
+ {
+ return SAB_ERROR;
+ }
+ SAState.CurrentOffset += ContextSize;
+ }
+#endif
+ if (SAWord32Count_p != NULL)
+ *SAWord32Count_p = SAState.CurrentOffset;
+
+ return SAB_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * SABuilder_BuildSA
+ *
+ * Construct the SA record for the operation described in SAParams_p in
+ * up to three memory buffers.
+ *
+ * SAParams_p (input)
+ * Pointer to the SA parameters structure.
+ *
+ * SABuffer_p (output)
+ * Pointer to the the normal SA buffer.
+ *
+ * SAStateBuffer_p (output)
+ * Pointer to the SA state record buffer.
+ *
+ * ARC4StateBuffer_p (output)
+ * Pointer to the ARCFOUR state buffer.
+ *
+ * Each of the Buffer arguments must point to a word-aligned
+ * memory buffer whose size in words is at least equal to the
+ * corresponding size parameter returned by SABuilder_GetSizes().
+ *
+ * If any of the three buffers is not required for the SA (the
+ * corresponding size in SABuilder_GetSizes() is 0), the corresponding
+ * Buffer arguments to this function may be a null pointer.
+ * The Security-IP-96 never requires these buffers.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ * the buffer arguments is a null pointer while the corresponding buffer
+ * would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ * is not supported on the hardware for which this SA builder
+ * is configured.
+ */
+SABuilder_Status_t
+SABuilder_BuildSA(
+ SABuilder_Params_t * const SAParams_p,
+ uint32_t *const SABuffer_p,
+ uint32_t *const SAStateBuffer_p,
+ uint32_t *const ARC4StateBuffer_p)
+{
+ SABuilder_State_t SAState;
+ int rc;
+
+ IDENTIFIER_NOT_USED(SAStateBuffer_p);
+ IDENTIFIER_NOT_USED(ARC4StateBuffer_p);
+
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p == NULL || SABuffer_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer parameter supplied.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+
+ SAState.CurrentOffset = 2; /* Count Control words 0 and 1 */
+ SAState.CW0 = 0;
+ SAState.CW1 = 0;
+ SAState.CipherKeyWords = 0;
+ SAState.IVWords = 0;
+ SAState.ARC4State = false;
+ SAState.fLarge = false;
+ SAState.fLargeMask = false;
+
+ rc = SABuilder_SetCipherKeys(SAParams_p, &SAState, SABuffer_p);
+ if (rc != SAB_STATUS_OK)
+ return rc;
+
+ rc = SABuilder_SetAuthKeys(SAParams_p, &SAState, SABuffer_p);
+ if (rc != SAB_STATUS_OK)
+ return rc;
+
+ switch ( SAParams_p->protocol)
+ {
+#ifdef SAB_ENABLE_PROTO_BASIC
+ case SAB_PROTO_BASIC:
+ {
+ rc = SABuilder_SetBasicParams(SAParams_p, &SAState, SABuffer_p);
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_PROTO_IPSEC
+ case SAB_PROTO_IPSEC:
+ {
+ rc = SABuilder_SetIPsecParams(SAParams_p, &SAState, SABuffer_p);
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_PROTO_SSLTLS
+ case SAB_PROTO_SSLTLS:
+ {
+ rc = SABuilder_SetSSLTLSParams(SAParams_p, &SAState, SABuffer_p);
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_PROTO_SRTP
+ case SAB_PROTO_SRTP:
+ {
+ rc = SABuilder_SetSRTPParams(SAParams_p, &SAState, SABuffer_p);
+ }
+ break;
+#endif
+#ifdef SAB_ENABLE_PROTO_MACSEC
+ case SAB_PROTO_MACSEC:
+ {
+ rc = SABuilder_SetMACsecParams(SAParams_p, &SAState, SABuffer_p);
+ }
+ break;
+#endif
+ default:
+ LOG_CRIT("SABuilder_BuildSA: unsupported protocol\n");
+ return SAB_UNSUPPORTED_FEATURE;
+ }
+ if (rc != SAB_STATUS_OK)
+ return rc;
+
+#ifdef SAB_ENABLE_FIXED_RECORD_SIZE
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+ if (SAParams_p->OffsetSeqNum > SAB_SEQNUM_LO_FIX_OFFSET)
+ SAState.fLarge = true;
+#endif
+#endif
+
+ if (SAState.ARC4State)
+ {
+ unsigned int ARC4Offset = 0;
+#ifdef SAB_ARC4_STATE_IN_SA
+ if (SAParams_p->OffsetARC4StateRecord > 0)
+ {
+ ARC4Offset = SAParams_p->OffsetARC4StateRecord;
+ }
+ else
+ {
+#ifdef SAB_ENABLE_FIXED_RECORD_SIZE
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+ if (SAState.fLarge)
+ {
+ ARC4Offset = SAB_RECORD_WORD_COUNT + LargeTransformOffset;
+ }
+ else
+#else
+ {
+ ARC4Offset = SAB_RECORD_WORD_COUNT;
+ }
+#endif
+#else
+ ARC4Offset = SAState.CurrentOffset + 2;
+#endif
+ ARC4Offset = SABuilder_AlignForARc4State(ARC4Offset);
+ }
+#endif
+ SABuffer_p[SAState.CurrentOffset] = ARC4Offset * sizeof(uint32_t);
+ SABuffer_p[SAState.CurrentOffset + 1] = 0;
+
+ if ( (SAParams_p->flags & SAB_FLAG_ARC4_STATE_LOAD) != 0)
+ {
+ /* Load the ARC4 state when building the SA.
+ Nonce_p[0] is the 'i' variable and
+ Nonce_p[1] is the 'j' variable.
+ IV_p points to the 256-byte state array.
+ The SA Builder will not fill in the ARC4 state pointer. */
+ if (SAParams_p->Nonce_p != NULL)
+ {
+ SABuffer_p[SAState.CurrentOffset + 1] =
+ ((SAParams_p->Nonce_p[0] + 1) & 0xff) |
+ (SAParams_p->Nonce_p[1]<<8);
+ }
+ if(SAParams_p->IV_p != NULL)
+ {
+#ifdef SAB_ARC4_STATE_IN_SA
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ (SAParams_p->OffsetARC4StateRecord >0 ?
+ SAParams_p->OffsetARC4StateRecord :
+ ARC4Offset),
+ SAParams_p->IV_p,
+ 256);
+
+#else
+ SABuilderLib_CopyKeyMat(ARC4StateBuffer_p,
+ 0,
+ SAParams_p->IV_p,
+ 256);
+#endif
+ }
+
+ }
+
+ SAParams_p->OffsetIJPtr = SAState.CurrentOffset + 1;
+ SAParams_p->OffsetARC4State = SAState.CurrentOffset;
+
+ SAState.CurrentOffset += 2; /* Count IJ pointer and ARC4 State */
+ }
+
+ if (SAState.CurrentOffset == 2)
+ {
+ SABuffer_p[SAState.CurrentOffset++] = 0;
+ /* Make sure to have at least one non-context word */
+ }
+
+ if (!SAState.fLargeMask)
+ SAState.CW0 |= (SAState.CurrentOffset - 2) << 8;
+ else
+ SAState.CW0 |= (SAState.CurrentOffset == 66)? 0x0200 : 0x0300;
+
+ SABuffer_p[0] = SAState.CW0;
+ SABuffer_p[1] = SAState.CW1;
+
+ SAParams_p->CW0 = SAState.CW0;
+ SAParams_p->CW1 = SAState.CW1;
+
+#ifdef SAB_ENABLE_IPSEC_EXTENDED
+ if (SAParams_p->protocol == SAB_PROTO_IPSEC)
+ {
+ SABuilder_Status_t res;
+ res = SABuilder_SetExtendedIPsecParams(SAParams_p,
+ &SAState,
+ SABuffer_p);
+ if (res != SAB_STATUS_OK)
+ return res;
+ }
+#endif
+#ifdef SAB_ENABLE_DTLS_EXTENDED
+ if (SAParams_p->protocol == SAB_PROTO_SSLTLS)
+ {
+ SABuilder_Status_t res;
+ res = SABuilder_SetExtendedDTLSParams(SAParams_p, &SAState, SABuffer_p);
+ if (res != SAB_STATUS_OK)
+ return res;
+ }
+#endif
+#ifdef SAB_ENABLE_MACSEC_EXTENDED
+ if (SAParams_p->protocol == SAB_PROTO_MACSEC)
+ {
+ SABuilder_Status_t res;
+ res = SABuilder_SetExtendedMACsecParams(SAParams_p,
+ &SAState,
+ SABuffer_p);
+ if (res != SAB_STATUS_OK)
+ return res;
+ }
+#endif
+#ifdef SAB_ENABLE_BASIC_EXTENDED
+ if (SAParams_p->protocol == SAB_PROTO_BASIC)
+ {
+ SABuilder_Status_t res;
+ res = SABuilder_SetExtendedBasicParams(SAParams_p,
+ &SAState,
+ SABuffer_p);
+ if (res != SAB_STATUS_OK)
+ return res;
+ }
+#endif
+
+#ifdef SAB_ENABLE_FIXED_RECORD_SIZE
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+ if (SAState.fLarge)
+ {
+ SABuffer_p[0] |= SAB_CW0_SW_IS_LARGE;
+#ifdef SAB_ENABLE_IPSEC_EXTENDED
+ /* Must be set independent of protocol */
+ if ((SAParams_p->flags & SAB_FLAG_REDIRECT) != 0)
+ {
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET +
+ LargeTransformOffset] |=
+ BIT_11 | ((SAParams_p->RedirectInterface & MASK_4_BITS) << 12);
+ }
+#endif
+ SAState.CurrentOffset = SAB_RECORD_WORD_COUNT + LargeTransformOffset;
+ }
+ else
+ {
+#ifdef SAB_ENABLE_IPSEC_EXTENDED
+ /* Must be set independent of protocol */
+ if ((SAParams_p->flags & SAB_FLAG_REDIRECT) != 0)
+ {
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET] |=
+ BIT_11 | ((SAParams_p->RedirectInterface & MASK_4_BITS) << 12);
+ }
+#endif
+ SAState.CurrentOffset = SAB_RECORD_WORD_COUNT;
+ }
+#endif
+#endif
+
+#ifdef SAB_AUTO_TOKEN_CONTEXT_GENERATION
+ {
+ TokenBuilder_Status_t rc;
+ void *TokenContext_p = (void*)&SABuffer_p[SAState.CurrentOffset];
+ rc = TokenBuilder_BuildContext(SAParams_p, TokenContext_p);
+ if (rc != TKB_STATUS_OK)
+ {
+ return SAB_ERROR;
+ }
+ }
+#endif
+
+
+ return SAB_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetLargeTransformOffset();
+ */
+SABuilder_Status_t
+SABuilder_SetLargeTransformOffset(
+ unsigned int Offset)
+{
+#if defined(SAB_ENABLE_IPSEC_EXTENDED) || defined(SAB_ENABLE_SSLTLS_EXTENDED)
+ LargeTransformOffset = Offset;
+ return SAB_STATUS_OK;
+#else
+ IDENTIFIER_NOT_USED(Offset);
+ return SAB_UNSUPPORTED_FEATURE;
+#endif
+}
+
+/* end of file sa_builder.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_basic.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_basic.c
new file mode 100644
index 0000000..256e341
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_basic.c
@@ -0,0 +1,444 @@
+/* sa_builder_basic.c
+ *
+ * Basic Crypto/hash specific functions (for initialization of
+ * SABuilder_Params_t structures and for building the Basic Crypto/hash
+ * specific part of an SA).
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "sa_builder_basic.h"
+#include "sa_builder_internal.h" /* SABuilder_SetBasicParams */
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#include "basic_defs.h"
+#include "log.h"
+
+#ifdef SAB_ENABLE_PROTO_BASIC
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_Basic
+ *
+ * This function initializes the SABuilder_Params_t data structure and
+ * its SABuilder_Params_Basic_t extension with sensible defaults for
+ * basic crypto and hash processing.
+ *
+ * SAParams_p (output)
+ * Pointer to SA parameter structure to be filled in.
+ *
+ * SAParamsBasic_p (output)
+ * Pointer to Basic parameter extension to be filled in
+ *
+ * direction (input)
+ * Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Both the crypto and the authentication algorithm are initialized to
+ * NULL. Either the cipher algorithm or the authentication algorithm
+ * or both can be set to one of the supported algorithms for
+ * basic crypto or basic hash or HMAC. If they are both left at NULL. the
+ * SA will be a bypass SA. The crypto mode and IV source
+ * can be specified as well. Any required keys have to be specified
+ * as well.
+ *
+ * Both the SAParams_p and SAParamsBasic_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsBasic_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ * or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_Basic(
+ SABuilder_Params_t * const SAParams_p,
+ SABuilder_Params_Basic_t * const SAParamsBasic_p,
+ const SABuilder_Direction_t direction)
+{
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p == NULL || SAParamsBasic_p == NULL)
+ {
+ LOG_CRIT("SABuilder_Init_Basic: NULL pointer parameter supplied.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if (direction != SAB_DIRECTION_OUTBOUND &&
+ direction != SAB_DIRECTION_INBOUND)
+ {
+ LOG_CRIT("SABuilder_Init_Basic: Invalid direction.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+
+ SAParams_p->protocol = SAB_PROTO_BASIC;
+ SAParams_p->direction = direction;
+ SAParams_p->ProtocolExtension_p = (void*)SAParamsBasic_p;
+ SAParams_p->flags = 0;
+ SAParams_p->RedirectInterface = 0;
+
+ SAParams_p->CryptoAlgo = SAB_CRYPTO_NULL;
+ SAParams_p->CryptoMode = SAB_CRYPTO_MODE_CBC;
+ SAParams_p->IVSrc = SAB_IV_SRC_DEFAULT;
+ SAParams_p->CryptoParameter = 0;
+ SAParams_p->KeyByteCount = 0;
+ SAParams_p->Key_p = NULL;
+ SAParams_p->IV_p = NULL;
+ SAParams_p->Nonce_p = NULL;
+
+ SAParams_p->AuthAlgo = SAB_AUTH_NULL;
+ SAParams_p->AuthKey1_p = NULL;
+ SAParams_p->AuthKey2_p = NULL;
+ SAParams_p->AuthKey3_p = NULL;
+ SAParams_p->AuthKeyByteCount = 0;
+
+ SAParams_p->OffsetARC4StateRecord = 0;
+ SAParams_p->CW0 = 0;
+ SAParams_p->CW1 = 0;
+ SAParams_p->OffsetDigest0 = 0;
+ SAParams_p->OffsetDigest1 = 0;
+ SAParams_p->OffsetSeqNum = 0;
+ SAParams_p->OffsetSeqMask = 0;
+ SAParams_p->OffsetIV = 0;
+ SAParams_p->OffsetIJPtr = 0;
+ SAParams_p->OffsetARC4State = 0;
+ SAParams_p->SeqNumWord32Count = 0;
+ SAParams_p->SeqMaskWord32Count = 0;
+ SAParams_p->IVWord32Count = 0;
+
+ SAParamsBasic_p->BasicFlags = 0;
+ SAParamsBasic_p->DigestBlockCount = 0;
+ SAParamsBasic_p->ICVByteCount = 0;
+
+ SAParamsBasic_p->fresh = 0;
+ SAParamsBasic_p->bearer = 0;
+ SAParamsBasic_p->direction = 0;
+
+ SAParamsBasic_p->ContextRef = 0;
+ return SAB_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetBasicParams
+ *
+ * Fill in Basic Crypto and hash-specific extensions into the SA.
+ *
+ * SAParams_p (input)
+ * The SA parameters structure from which the SA is derived.
+ *
+ * SAState_p (input, output)
+ * Variables containing information about the SA being generated.
+ *
+ * SABuffer_p (input, output).
+ * The buffer in which the SA is built. If NULL, no SA will be built, but
+ * state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ * the buffer arguments is a null pointer while the corresponding buffer
+ * would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ * is not supported on the hardware for which this SA builder
+ * is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetBasicParams(
+ SABuilder_Params_t *const SAParams_p,
+ SABuilder_State_t * const SAState_p,
+ uint32_t * const SABuffer_p)
+{
+ SABuilder_Params_Basic_t *SAParamsBasic_p;
+ SAParamsBasic_p = (SABuilder_Params_Basic_t *)
+ (SAParams_p->ProtocolExtension_p);
+
+ if (SAParamsBasic_p == NULL)
+ {
+ LOG_CRIT("SABuilder: Basic extension pointer is null\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if (SAParamsBasic_p->direction > 1 ||
+ SAParamsBasic_p->bearer > 32)
+ {
+ LOG_CRIT("SABuilder: Illegal value for bearer or direction\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* Use one of the classic hash algorithms, possibly with
+ encryption */
+ if ((SAParams_p->AuthAlgo == SAB_AUTH_HASH_MD5 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA1 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA2_224 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA2_256 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA2_384 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_HASH_SHA2_512 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_HASH_SM3) &&
+ (SAParams_p->flags & (SAB_FLAG_HASH_LOAD|SAB_FLAG_HASH_SAVE|
+ SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+ {
+ /* We are doing basic hash (no HMAC) with storing the state.*/
+ SAState_p->CW1 |= SAB_CW1_HASH_STORE | SAB_CW1_DIGEST_CNT;
+ if(SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] =
+ SAParamsBasic_p->DigestBlockCount;
+ SAState_p->CurrentOffset += 1;
+ }
+ else if (SAParams_p->AuthAlgo != SAB_AUTH_NULL &&
+ (SAParams_p->flags & (SAB_FLAG_HASH_SAVE)) != 0)
+ {
+ SAState_p->CW1 |= SAB_CW1_HASH_STORE;
+ }
+
+ if ((SAParams_p->AuthAlgo == SAB_AUTH_KASUMI_F9 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_SNOW_UIA2 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_ZUC_EIA3) &&
+ SAParamsBasic_p->direction != 0)
+ {
+ SAState_p->CW1 |= SAB_CW1_WIRELESS_DIR;
+ }
+
+ if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+ {
+ /* We are now doing basic encryption/decryption,
+ possibly with hash.*/
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ if (SAParams_p->AuthAlgo == SAB_AUTH_NULL)
+ SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT;
+ else if (SAParams_p->AuthAlgo==SAB_AUTH_AES_CCM ||
+ SAParams_p->AuthAlgo==SAB_AUTH_AES_GMAC)
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_ENCRYPT;
+ else if ( (SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_ENCRYPT;
+ else
+ SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT_HASH;
+ else
+ if (SAParams_p->AuthAlgo == SAB_AUTH_NULL)
+ SAState_p->CW0 |= SAB_CW0_TOP_DECRYPT;
+ else if (SAParams_p->AuthAlgo==SAB_AUTH_AES_CCM)
+ SAState_p->CW0 |= SAB_CW0_TOP_DECRYPT_HASH;
+ else if ( (SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+ {
+ SAState_p->CW0 |= SAB_CW0_TOP_DECRYPT_HASH;
+ SAState_p->CW1 |= SAB_CW1_PREPKT_OP;
+ SAState_p->CW1 |= SAB_CW1_PAD_TLS;
+ }
+ else
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_DECRYPT;
+
+ /* Check for prohibited algorithms and crypto modes. */
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CFB1 ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CFB8)
+ {
+ LOG_CRIT("SABuilder: crypto algorithm/mode not supported\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* Reject crypto modes other than CBC for ENCRYPT_AFTER_HASH */
+ if ( (SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0 &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CBC)
+ {
+ LOG_CRIT("SABuilder: crypto algorithm/mode not supported for encrypt after hash\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_XTS ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_XTS_STATEFUL)
+ { /* For AES-XTS, extract Key2 from Nonce_p parameter,
+ same size as the primary AES key. */
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p->Nonce_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer Key 2.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->Nonce_p,
+ SAParams_p->KeyByteCount);
+ SAState_p->CurrentOffset+=SAState_p->CipherKeyWords;
+ }
+
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_F8 ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_UEA2 ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_EEA3)
+ {
+ SAParams_p->IVSrc = SAB_IV_SRC_TOKEN;
+ }
+ else if (SAParams_p->CryptoAlgo != SAB_CRYPTO_ARCFOUR &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_ECB &&
+ !(SAParams_p->CryptoAlgo==SAB_CRYPTO_KASUMI &&
+ SAParams_p->CryptoMode==SAB_CRYPTO_MODE_BASIC))
+ {
+ /* For ARCFOUR and block ciphers in ECB mode and
+ Basic Kasumi we do not have an IV */
+ if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT)
+ SAParams_p->IVSrc = SAB_IV_SRC_INPUT;
+
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CTR ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GMAC ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM)
+ {
+ if (SAParams_p->IVSrc == SAB_IV_SRC_TOKEN)
+ {
+ SAState_p->CW1 &= ~0x7; // Clear crypto mode (CTR);
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR_LOAD;
+ /* When the CTR mode IV is loaded from token, then
+ load all four IV words, including block counter */
+ }
+ else
+ { /* else add nonce to SA */
+ SAState_p->CW1 |= SAB_CW1_IV0;
+
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p->Nonce_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer nonce.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+ {
+ if (SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] =
+ (SAParams_p->Nonce_p[0] << 8) |
+ (SAParams_p->Nonce_p[1] << 16) |
+ (SAParams_p->Nonce_p[2] << 24) | SAB_CCM_FLAG_L4;
+ }
+ else
+ {
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->Nonce_p, sizeof(uint32_t));
+ }
+ SAState_p->CurrentOffset +=1;
+ }
+
+ if (SAParams_p->IVSrc == SAB_IV_SRC_SA)
+ {
+ SAState_p->CW1 |= SAB_CW1_IV_CTR |
+ SAB_CW1_IV1 |
+ SAB_CW1_IV2;
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p->IV_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer IV.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SAParams_p->OffsetIV = SAState_p->CurrentOffset;
+ SAParams_p->IVWord32Count = 2;
+
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->IV_p, 8);
+ SAState_p->CurrentOffset += 2;
+ }
+ else
+ {
+ SAState_p->CW1 |= SAB_CW1_IV_CTR;
+ }
+
+ if (SAParams_p->IVSrc != SAB_IV_SRC_TOKEN &&
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+ {
+ /* Add 0 counter field (IV3) */
+ SAState_p->CW1 |= SAB_CW1_IV3;
+ if(SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] = 0;
+ SAState_p->CurrentOffset+=1;
+ }
+ }
+ else
+ {
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_ICM)
+ {
+ SAState_p->CW1 &= ~0x7; // Clear crypto mode (CTR or ICM);
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR_LOAD;
+ /* When the CTR mode IV is loaded from token, then
+ load all four IV words, including block counter */
+ }
+
+ SAState_p->CW1 |= SAB_CW1_IV_FULL;
+ if (SAParams_p->IVSrc == SAB_IV_SRC_SA)
+ {
+ SAState_p->CW1 |= SAB_CW1_IV0 | SAB_CW1_IV1;
+ if(SAState_p->IVWords == 4)
+ SAState_p->CW1 |= SAB_CW1_IV2 | SAB_CW1_IV3;
+
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p->IV_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer IV.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SAParams_p->OffsetIV = SAState_p->CurrentOffset;
+ SAParams_p->IVWord32Count = SAState_p->IVWords;
+
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->IV_p,
+ SAState_p->IVWords * sizeof(uint32_t));
+ SAState_p->CurrentOffset += SAState_p->IVWords;
+ if (SAParams_p->CryptoAlgo == SAB_CRYPTO_DES ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_3DES ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_AES ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_SM4 ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_BC0)
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_STORE;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Bypass operation or authenticate-only,
+ use inbound direction when verifying */
+ if (SAParams_p->AuthAlgo == SAB_AUTH_NULL)
+ SAState_p->CW0 |= SAB_CW0_TOP_NULL_OUT;
+ else if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_EXTRACT_ICV) !=0)
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_IN;
+ else
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_OUT;
+ }
+
+ return SAB_STATUS_OK;
+}
+
+#endif /* SAB_ENABLE_PROTO_BASIC */
+
+/* end of file sa_builder_basic.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_basic.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_basic.c
new file mode 100644
index 0000000..236a8ba
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_basic.c
@@ -0,0 +1,406 @@
+/* sa_builder_extended_basic.c
+ *
+ * Basic opaeration specific functions (for initialization of
+ * SABuilder_Params_t structures and for building the Basic specific
+ * part of an SA) in the Extended use case.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#ifdef SAB_ENABLE_BASIC_EXTENDED
+#include "sa_builder_extended_internal.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "basic_defs.h"
+#include "log.h"
+#include "sa_builder_internal.h" /* SABuilder_SetBasicParams */
+#include "sa_builder_basic.h"
+
+#include "firmware_eip207_api_cs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetExtendedBasicParams
+ *
+ * Fill in Basic-specific extensions into the SA.for Extended.
+ *
+ * SAParams_p (input)
+ * The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ * Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ * The buffer in which the SA is built. If NULL, no SA will be built, but
+ * state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ * the buffer arguments is a null pointer while the corresponding buffer
+ * would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ * is not supported on the hardware for which this SA builder
+ * is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetExtendedBasicParams(SABuilder_Params_t *const SAParams_p,
+ SABuilder_State_t * const SAState_p,
+ uint32_t * const SABuffer_p)
+{
+ SABuilder_Params_Basic_t *SAParamsBasic_p =
+ (SABuilder_Params_Basic_t *)(SAParams_p->ProtocolExtension_p);
+
+ IDENTIFIER_NOT_USED(SAState_p);
+
+#ifdef FIRMWARE_EIP207_CS_TR_IV_WORD_OFFSET
+ /* These operations are specific to PDCP firmware */
+ if (SAParams_p->AuthAlgo == SAB_AUTH_SNOW_UIA2 ||
+ SAParams_p->AuthAlgo == SAB_AUTH_KASUMI_F9)
+ {
+ if(SABuffer_p != NULL)
+ SABuffer_p[FIRMWARE_EIP207_CS_TR_IV_WORD_OFFSET] =
+ SAParamsBasic_p->fresh;
+ }
+#endif
+#ifdef FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET
+ /* These operations are specific to non-PDCP firmware */
+ if ((SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_ARCFOUR &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_CHACHA20 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_NULL &&
+ SAParams_p->AuthAlgo != SAB_AUTH_AES_GCM &&
+ SAParams_p->AuthAlgo != SAB_AUTH_AES_GMAC &&
+ SAParams_p->AuthAlgo != SAB_AUTH_AES_CCM) ||
+ (SAParams_p->CryptoAlgo == SAB_CRYPTO_NULL &&
+ SAParams_p->AuthAlgo == SAB_AUTH_NULL))
+ {
+ /* Only combined crypto + hash and not AES-GCM/AES-GMAC/AES-CCM are
+ supported */
+ uint32_t TokenHeaderWord = SAB_HEADER_DEFAULT;
+ SABuilder_ESPProtocol_t ESPProto;
+ SABuilder_HeaderProtocol_t HeaderProto;
+ uint8_t PadBlockByteCount = 1;
+ uint8_t IVByteCount = 0;
+ uint8_t ICVByteCount = 0;
+ uint32_t flags = 0;
+ uint32_t VerifyInstructionWord, CtxInstructionWord;
+ uint32_t IVInstructionWord = 0;
+
+ if (SAParams_p->CryptoAlgo == SAB_CRYPTO_NULL)
+ {
+ ESPProto = SAB_ESP_PROTO_NONE;
+ if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_XFRM_API) != 0)
+
+ HeaderProto = SAB_HDR_BASIC_IN_NO_PAD;
+ else
+ HeaderProto = SAB_HDR_BYPASS;
+ VerifyInstructionWord = SAB_VERIFY_NONE;
+ }
+ else
+ {
+ if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+ {
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ ESPProto = SAB_BASIC_PROTO_OUT_HASHENC;
+ HeaderProto = SAB_HDR_BASIC_OUT_TPAD;
+ }
+ else
+ {
+ ESPProto = SAB_BASIC_PROTO_IN_DECHASH;
+ TokenHeaderWord |= SAB_HEADER_PAD_VERIFY;
+ HeaderProto = SAB_HDR_BASIC_IN_PAD;
+ }
+ }
+ else
+ {
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ ESPProto = SAB_BASIC_PROTO_OUT_ENCHASH;
+ HeaderProto = SAB_HDR_BASIC_OUT_ZPAD;
+ }
+ else
+ {
+ ESPProto = SAB_BASIC_PROTO_IN_HASHDEC;
+ HeaderProto = SAB_HDR_BASIC_IN_NO_PAD;
+ }
+ }
+
+ if ((SAParams_p->flags & SAB_FLAG_SUPPRESS_HEADER) == 0)
+ flags |= BIT_29;
+
+ switch(SAParams_p->CryptoAlgo)
+ {
+ case SAB_CRYPTO_DES:
+ case SAB_CRYPTO_3DES:
+ IVByteCount = 8;
+ PadBlockByteCount = 8;
+ break;
+ case SAB_CRYPTO_AES:
+ case SAB_CRYPTO_SM4:
+ case SAB_CRYPTO_BC0:
+ IVByteCount = 16;
+ PadBlockByteCount = 16;
+ break;
+ default:
+ LOG_CRIT("SABuilder_BuildSA: unsupported crypto algorithm\n");
+ return SAB_UNSUPPORTED_FEATURE;
+ }
+
+ switch(SAParams_p->CryptoMode)
+ {
+ case SAB_CRYPTO_MODE_ECB:
+ IVByteCount = 0;
+ IVInstructionWord = 0x20000004; /* NOP instruction */
+ break;
+ case SAB_CRYPTO_MODE_CBC:
+ if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT ||
+ SAParams_p->IVSrc == SAB_IV_SRC_INPUT)
+ {
+ IVInstructionWord = SA_RETR_HASH_IV0 + IVByteCount;
+ }
+ else
+ {
+ IVInstructionWord = SA_INS_NONE_IV0 + IVByteCount;
+ IVByteCount = 0;
+ }
+ if (SAParams_p->IVSrc == SAB_IV_SRC_PRNG)
+ TokenHeaderWord |= SAB_HEADER_IV_PRNG;
+ if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+ {
+ IVInstructionWord |= BIT_25|BIT_24; /* IV to output & hash */
+ }
+ if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+ {
+ IVInstructionWord &= ~BIT_25; /* Do not hash IV for HASHENC */
+ }
+ break;
+ case SAB_CRYPTO_MODE_CTR:
+ IVByteCount = 8;
+ PadBlockByteCount = 1;
+ if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT ||
+ SAParams_p->IVSrc == SAB_IV_SRC_INPUT)
+ {
+ IVInstructionWord = SA_RETR_HASH_IV1 + IVByteCount;
+ }
+ else
+ {
+ IVInstructionWord = SA_INS_NONE_IV1 + IVByteCount;
+ IVByteCount = 0;
+ }
+ if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+ {
+ IVInstructionWord |= BIT_25|BIT_24; /* IV to output & hash */
+ }
+ break;
+ case SAB_CRYPTO_MODE_ICM:
+ IVByteCount = 16;
+ PadBlockByteCount = 1;
+ if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT ||
+ SAParams_p->IVSrc == SAB_IV_SRC_INPUT)
+ {
+ IVInstructionWord = SA_RETR_HASH_IV0 + IVByteCount;
+ }
+ else
+ {
+ IVInstructionWord = SA_INS_NONE_IV0 + IVByteCount;
+ IVByteCount = 0;
+ }
+ if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+ {
+ IVInstructionWord |= BIT_25|BIT_24; /* IV to output & hash */
+ }
+ break;
+ default:
+ LOG_CRIT("SABuilder_BuildSA: unsupported crypto mode\n");
+ return SAB_UNSUPPORTED_FEATURE;
+ }
+
+ switch(SAParams_p->AuthAlgo)
+ {
+ case SAB_AUTH_HASH_MD5:
+ case SAB_AUTH_SSLMAC_MD5:
+ case SAB_AUTH_HMAC_MD5:
+ ICVByteCount = 16;
+ break;
+ case SAB_AUTH_HASH_SHA1:
+ case SAB_AUTH_SSLMAC_SHA1:
+ case SAB_AUTH_HMAC_SHA1:
+ ICVByteCount = 20;
+ break;
+ case SAB_AUTH_HASH_SHA3_224:
+ case SAB_AUTH_KEYED_HASH_SHA3_224:
+ case SAB_AUTH_HMAC_SHA3_224:
+ ICVByteCount = 28;
+ break;
+ case SAB_AUTH_HASH_SHA2_224:
+ case SAB_AUTH_HMAC_SHA2_224:
+ case SAB_AUTH_HASH_SHA2_256:
+ case SAB_AUTH_HMAC_SHA2_256:
+ case SAB_AUTH_HMAC_SM3:
+ case SAB_AUTH_HASH_SM3:
+ case SAB_AUTH_HASH_SHA3_256:
+ case SAB_AUTH_KEYED_HASH_SHA3_256:
+ case SAB_AUTH_HMAC_SHA3_256:
+ ICVByteCount = 32;
+ break;
+ case SAB_AUTH_HASH_SHA3_384:
+ case SAB_AUTH_KEYED_HASH_SHA3_384:
+ case SAB_AUTH_HMAC_SHA3_384:
+ ICVByteCount = 48;
+ break;
+ case SAB_AUTH_HASH_SHA2_384:
+ case SAB_AUTH_HMAC_SHA2_384:
+ if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+ ICVByteCount = 48;
+ else
+ ICVByteCount = 64;
+ break;
+ case SAB_AUTH_HASH_SHA3_512:
+ case SAB_AUTH_KEYED_HASH_SHA3_512:
+ case SAB_AUTH_HMAC_SHA3_512:
+ case SAB_AUTH_HASH_SHA2_512:
+ case SAB_AUTH_HMAC_SHA2_512:
+ ICVByteCount = 64;
+ break;
+ case SAB_AUTH_AES_XCBC_MAC:
+ case SAB_AUTH_AES_CMAC_128:
+ case SAB_AUTH_AES_CMAC_192:
+ case SAB_AUTH_AES_CMAC_256:
+ ICVByteCount = 16;
+ break;
+ default:
+ LOG_CRIT("SABuilder_BuildSA: unsupported authentication algorithm\n");
+ return SAB_UNSUPPORTED_FEATURE;
+ }
+ if (SAParamsBasic_p->ICVByteCount != 0 &&
+ SAParamsBasic_p->ICVByteCount < ICVByteCount)
+ ICVByteCount = SAParamsBasic_p->ICVByteCount;
+
+ /* Take care of the VERIFY and CTX token instructions */
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ VerifyInstructionWord = SAB_VERIFY_NONE;
+ }
+ else
+ {
+ if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+ {
+ VerifyInstructionWord = SAB_VERIFY_PAD;
+ }
+ else
+ {
+ VerifyInstructionWord = SAB_VERIFY_NONE;
+ }
+ VerifyInstructionWord += SAB_VERIFY_BIT_H + ICVByteCount;
+ }
+ }
+
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+ if (SAState_p->fLarge)
+ {
+ CtxInstructionWord = SAB_CTX_NONE + FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT + LargeTransformOffset - 1;
+ }
+ else
+#endif
+ {
+ CtxInstructionWord = SAB_CTX_NONE + FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT - 1;
+ }
+
+ /* Write all parameters to their respective offsets */
+ if (SABuffer_p != NULL)
+ {
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+ if (SAState_p->fLarge)
+ {
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET +
+ LargeTransformOffset] = flags;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET +
+ LargeTransformOffset] = SAParamsBasic_p->ContextRef;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET +
+ LargeTransformOffset] =
+ SAB_PACKBYTES(IVByteCount,ICVByteCount,HeaderProto,ESPProto);
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET +
+ LargeTransformOffset] = TokenHeaderWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET +
+ LargeTransformOffset] =
+ SAB_PACKBYTES(PadBlockByteCount/2, 0, 0, 0);
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET +
+ LargeTransformOffset] =IVInstructionWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET +
+ LargeTransformOffset] = VerifyInstructionWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET +
+ LargeTransformOffset] = CtxInstructionWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+ }
+ else
+#endif /* SAB_ENABLE_TWO_FIXED_RECORD_SIZES */
+ {
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET] = flags;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET] =
+ SAParamsBasic_p->ContextRef;
+;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET] =
+ SAB_PACKBYTES(IVByteCount,ICVByteCount,HeaderProto,ESPProto);
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET] = TokenHeaderWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET] =
+ SAB_PACKBYTES(PadBlockByteCount/2, 0, 0, 0);
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET] = IVInstructionWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET] =
+ VerifyInstructionWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET] =
+ CtxInstructionWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET] = 0;
+ }
+ }
+ }
+#endif
+ return SAB_STATUS_OK;
+}
+
+#endif /* SAB_ENABLE_BASIC_EXTENDED */
+
+
+/* end of file sa_builder_extended_basic.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_dtls.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_dtls.c
new file mode 100644
index 0000000..11abdd6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_dtls.c
@@ -0,0 +1,396 @@
+/* sa_builder_extended_dtls.c
+ *
+ * DTLS specific functions (for initialization of SABuilder_Params_t
+ * structures and for building the DTLS specifc part of an SA.) in the
+ * Extended use case.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#ifdef SAB_ENABLE_DTLS_EXTENDED
+#include "sa_builder_extended_internal.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "basic_defs.h"
+#include "log.h"
+#include "sa_builder_internal.h" /* SABuilder_SetDTLSParams */
+#include "sa_builder_ssltls.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetExtendedDTLSParams
+ *
+ * Fill in DTLS-specific extensions into the SA.for Extended.
+ *
+ * SAParams_p (input)
+ * The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ * Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ * The buffer in which the SA is built. If NULL, no SA will be built, but
+ * state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ * the buffer arguments is a null pointer while the corresponding buffer
+ * would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ * is not supported on the hardware for which this SA builder
+ * is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetExtendedDTLSParams(SABuilder_Params_t *const SAParams_p,
+ SABuilder_State_t * const SAState_p,
+ uint32_t * const SABuffer_p)
+{
+ SABuilder_Params_SSLTLS_t *SAParamsSSLTLS_p =
+ (SABuilder_Params_SSLTLS_t *)(SAParams_p->ProtocolExtension_p);
+ uint32_t TokenHeaderWord = SAB_HEADER_DEFAULT;
+ SABuilder_ESPProtocol_t ESPProto;
+ SABuilder_HeaderProtocol_t HeaderProto;
+ uint8_t PadBlockByteCount;
+ uint8_t IVByteCount;
+ uint8_t ICVByteCount;
+ uint8_t SeqOffset;
+ uint8_t AntiReplay;
+ uint32_t flags = 0;
+ uint32_t VerifyInstructionWord, CtxInstructionWord;
+
+ IDENTIFIER_NOT_USED(SAState_p);
+
+ if (SAParamsSSLTLS_p == NULL)
+ {
+ LOG_CRIT("SABuilder: SSLTLS extension pointer is null\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if ((SAParamsSSLTLS_p->version != SAB_DTLS_VERSION_1_0 &&
+ SAParamsSSLTLS_p->version != SAB_DTLS_VERSION_1_2) ||
+ (SAParams_p->CryptoAlgo != SAB_CRYPTO_AES &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_CHACHA20 &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_3DES &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_SM4 &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL))
+ {
+ if (SABuffer_p != 0)
+ LOG_CRIT("SABuilder: SSLTLS record only for look-aside\n");
+ // No extended transform record can be created, however it can
+ // still be valid for host look-aside.
+ return SAB_STATUS_OK;
+ }
+
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_NO_ANTI_REPLAY) != 0)
+ AntiReplay = 0;
+ else
+ AntiReplay = 1;
+
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ if (SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+ {
+ ESPProto = SAB_DTLS_PROTO_OUT_CHACHAPOLY;
+ PadBlockByteCount = 0;
+ IVByteCount = 0;
+ }
+ else if (SAParams_p->AuthAlgo == SAB_AUTH_AES_GCM)
+ {
+ ESPProto = SAB_DTLS_PROTO_OUT_GCM;
+ PadBlockByteCount = 0;
+ IVByteCount = 8;
+ }
+ else if (SAParams_p->CryptoAlgo == SAB_CRYPTO_NULL)
+ {
+ ESPProto = SAB_DTLS_PROTO_OUT_CHACHAPOLY;
+ PadBlockByteCount = 0;
+ IVByteCount = 0;
+ }
+ else
+ {
+ switch (SAParams_p->IVSrc)
+ {
+ case SAB_IV_SRC_DEFAULT:
+ case SAB_IV_SRC_PRNG:
+ TokenHeaderWord |=
+ SAB_HEADER_IV_PRNG;
+ break;
+ case SAB_IV_SRC_SA: /* No action required */
+ case SAB_IV_SRC_TOKEN:
+ break;
+ default:
+ LOG_CRIT("SABuilder_BuildSA:"
+ "Unsupported IV source\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ ESPProto = SAB_DTLS_PROTO_OUT_CBC;
+ if (SAParams_p->CryptoAlgo == SAB_CRYPTO_3DES)
+ {
+ PadBlockByteCount = 8;
+ IVByteCount = 8;
+ }
+ else
+ {
+ PadBlockByteCount = 16;
+ IVByteCount = 16;
+ }
+ }
+
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_IPV6) !=0)
+ {
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_CAPWAP) !=0)
+ {
+ HeaderProto = SAB_HDR_IPV6_OUT_DTLS_CAPWAP;
+ }
+ else
+ {
+ HeaderProto = SAB_HDR_IPV6_OUT_DTLS;
+ }
+ }
+ else
+ {
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_CAPWAP) !=0)
+ {
+ HeaderProto = SAB_HDR_IPV4_OUT_DTLS_CAPWAP;
+ }
+ else
+ {
+ HeaderProto = SAB_HDR_IPV4_OUT_DTLS;
+ }
+ }
+ }
+ else
+ {
+ if (SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+ {
+ ESPProto = SAB_DTLS_PROTO_IN_CHACHAPOLY;
+ PadBlockByteCount = 0;
+ IVByteCount = 0;
+ }
+ else if (SAParams_p->AuthAlgo == SAB_AUTH_AES_GCM)
+ {
+ ESPProto = SAB_DTLS_PROTO_IN_GCM;
+ PadBlockByteCount = 0;
+ IVByteCount = 8;
+ }
+ else if (SAParams_p->CryptoAlgo == SAB_CRYPTO_NULL)
+ {
+ ESPProto = SAB_DTLS_PROTO_IN_CHACHAPOLY;
+ PadBlockByteCount = 0;
+ IVByteCount = 0;
+ }
+ else
+ {
+ ESPProto = SAB_DTLS_PROTO_IN_CBC;
+ TokenHeaderWord |= SAB_HEADER_PAD_VERIFY;
+ if (SAParams_p->CryptoAlgo == SAB_CRYPTO_3DES)
+ {
+ PadBlockByteCount = 8;
+ IVByteCount = 8;
+ }
+ else
+ {
+ PadBlockByteCount = 16;
+ IVByteCount = 16;
+ }
+ }
+
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_IPV6) !=0)
+ {
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_CAPWAP) !=0)
+ {
+ HeaderProto = SAB_HDR_IPV6_IN_DTLS_CAPWAP;
+ }
+ else
+ {
+ HeaderProto = SAB_HDR_IPV6_IN_DTLS;
+ }
+ }
+ else
+ {
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_CAPWAP) !=0)
+ {
+ HeaderProto = SAB_HDR_IPV4_IN_DTLS_CAPWAP;
+ }
+ else
+ {
+ HeaderProto = SAB_HDR_IPV4_IN_DTLS;
+ }
+ }
+
+ AntiReplay *= SAParamsSSLTLS_p->SequenceMaskBitCount / 32;
+ }
+ SeqOffset = SAParams_p->OffsetSeqNum;
+
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND &&
+ SAParamsSSLTLS_p->PadAlignment >
+ PadBlockByteCount &&
+ SAParamsSSLTLS_p->PadAlignment <= 256)
+ PadBlockByteCount =
+ SAParamsSSLTLS_p->PadAlignment;
+
+ switch(SAParams_p->AuthAlgo)
+ {
+ case SAB_AUTH_HMAC_MD5:
+ ICVByteCount = 16;
+ break;
+ case SAB_AUTH_HMAC_SHA1:
+ ICVByteCount = 20;
+ break;
+ case SAB_AUTH_HMAC_SHA2_256:
+ case SAB_AUTH_HMAC_SM3:
+ ICVByteCount = 32;
+ break;
+ case SAB_AUTH_HMAC_SHA2_384:
+ ICVByteCount = 48;
+ break;
+ case SAB_AUTH_HMAC_SHA2_512:
+ ICVByteCount = 64;
+ break;
+ case SAB_AUTH_AES_GCM:
+ ICVByteCount = 16;
+ break;
+ case SAB_AUTH_POLY1305:
+ ICVByteCount = 16;
+ break;
+ break;
+ default:
+ LOG_CRIT("SABuilder_BuildSA: unsupported authentication algorithm\n");
+ return SAB_UNSUPPORTED_FEATURE;
+ }
+
+ /* Flags variable */
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_IPV6) !=0)
+ flags |= BIT_8;
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_PROCESS_IP_HEADERS) !=0)
+ flags |= BIT_19;
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_PLAINTEXT_HEADERS) !=0)
+ flags |= BIT_29;
+
+ /* Take care of the VERIFY and CTX token instructions */
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ VerifyInstructionWord = SAB_VERIFY_NONE;
+ CtxInstructionWord = SAB_CTX_OUT_SEQNUM +
+ ((unsigned int)(2<<24)) + SeqOffset;
+ }
+ else
+ {
+ if (PadBlockByteCount != 0)
+ {
+ VerifyInstructionWord = SAB_VERIFY_PAD;
+ }
+ else
+ {
+ VerifyInstructionWord = SAB_VERIFY_NONE;
+ }
+ if (ICVByteCount > 0)
+ {
+ VerifyInstructionWord += SAB_VERIFY_BIT_H + ICVByteCount;
+ }
+ if (AntiReplay > 0)
+ {
+ VerifyInstructionWord += SAB_VERIFY_BIT_SEQ;
+ }
+ CtxInstructionWord = SAB_CTX_SEQNUM +
+ ((unsigned int)(2+AntiReplay)<<24) + SeqOffset;
+ }
+ /* Write all parameters to their respective offsets */
+ if (SABuffer_p != NULL)
+ {
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+ if (SAState_p->fLarge)
+ {
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET +
+ LargeTransformOffset] = flags;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET +
+ LargeTransformOffset] = SAParamsSSLTLS_p->ContextRef;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET +
+ LargeTransformOffset] =
+ SAB_PACKBYTES(IVByteCount,ICVByteCount,HeaderProto,ESPProto);
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET +
+ LargeTransformOffset] = TokenHeaderWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET +
+ LargeTransformOffset] =
+ SAB_PACKBYTES(PadBlockByteCount/2, 0, 0, 0);
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET +
+ LargeTransformOffset] =0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET +
+ LargeTransformOffset] = VerifyInstructionWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET +
+ LargeTransformOffset] = CtxInstructionWord;
+ SABuffer_p[FIMRWARE_EIP207_CS_FLOW_TR_NATT_PORTS_WORD_OFFSET +
+ LargeTransformOffset] =
+ SAParamsSSLTLS_p->version;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+ }
+ else
+#endif /* SAB_ENABLE_TWO_FIXED_RECORD_SIZES */
+ {
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET] = flags;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET] =
+ SAParamsSSLTLS_p->ContextRef;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET] =
+ SAB_PACKBYTES(IVByteCount,ICVByteCount,HeaderProto,ESPProto);
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET] = TokenHeaderWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET] =
+ SAB_PACKBYTES(PadBlockByteCount/2, 0, 0, 0);
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET] =
+ VerifyInstructionWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET] =
+ CtxInstructionWord;
+ SABuffer_p[FIMRWARE_EIP207_CS_FLOW_TR_NATT_PORTS_WORD_OFFSET] =
+ SAParamsSSLTLS_p->version;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET] = 0;
+ }
+ }
+ return SAB_STATUS_OK;
+}
+
+
+#endif /* SAB_ENABLE_DTLS_EXTENDED */
+
+
+/* end of file sa_builder_extended_dtls.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_ipsec.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_ipsec.c
new file mode 100644
index 0000000..14a07ab
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_ipsec.c
@@ -0,0 +1,832 @@
+/* sa_builder_extended_ipsec.c
+ *
+ * IPsec specific functions (for initialization of SABuilder_Params_t
+ * structures and for building the IPSec specifc part of an SA.) in the
+ * Extended use case.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "c_sa_builder.h"
+
+#ifdef SAB_ENABLE_IPSEC_EXTENDED
+#include "sa_builder_extended_internal.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "basic_defs.h"
+#include "log.h"
+#include "sa_builder_internal.h" /* SABuilder_SetIpsecParams */
+#include "sa_builder_ipsec.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+#define ESP_HDR_LEN 8
+#define IPV4_HDR_LEN 20
+#define IPV6_HDR_LEN 40
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+#ifdef SAB_ENABLE_EXTENDED_TUNNEL_HEADER
+/*----------------------------------------------------------------------------
+ * get16
+ *
+ * Read 16-bit value from byte array not changing the byte order.
+ */
+static uint16_t
+get16no(
+ uint8_t *p,
+ unsigned int offs)
+{
+ return (p[offs+1]<<8) | p[offs];
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetExtendedIPsecParams
+ *
+ * Fill in IPsec-specific extensions into the SA.for Extended.
+ *
+ * SAParams_p (input)
+ * The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ * Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ * The buffer in which the SA is built. If NULL, no SA will be built, but
+ * state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ * the buffer arguments is a null pointer while the corresponding buffer
+ * would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ * is not supported on the hardware for which this SA builder
+ * is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetExtendedIPsecParams(SABuilder_Params_t *const SAParams_p,
+ SABuilder_State_t * const SAState_p,
+ uint32_t * const SABuffer_p)
+{
+ SABuilder_Params_IPsec_t *SAParamsIPsec_p =
+ (SABuilder_Params_IPsec_t *)(SAParams_p->ProtocolExtension_p);
+ uint32_t TokenHeaderWord = SAB_HEADER_DEFAULT;
+ SABuilder_ESPProtocol_t ESPProto;
+ SABuilder_HeaderProtocol_t HeaderProto;
+ uint8_t PadBlockByteCount;
+ uint8_t IVByteCount;
+ uint8_t ICVByteCount;
+ uint8_t SeqOffset;
+ uint8_t ExtSeq = 0;
+ uint8_t AntiReplay;
+ uint32_t CCMSalt = 0;
+ uint32_t flags = 0;
+ uint32_t VerifyInstructionWord, CtxInstructionWord;
+#ifdef SAB_ENABLE_EXTENDED_TUNNEL_HEADER
+ uint32_t MTUDiscount = 0;
+ uint32_t CheckSum = 0;
+#endif
+ IDENTIFIER_NOT_USED(SAState_p);
+
+ if (SAParamsIPsec_p == NULL)
+ {
+ LOG_CRIT("SABuilder: IPsec extension pointer is null\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_ESP) == 0)
+ {
+ LOG_CRIT("SABuilder: IPsec only supports ESP.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+ {
+ if(SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CBC &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GCM)
+ {
+ LOG_CRIT("SABuilder: IPsec for XFRM only supports CBC and GCM modes.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_NATT) != 0)
+ {
+ LOG_CRIT("SABuilder: IPsec for XFRM does not support NATT\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ }
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_NO_ANTI_REPLAY) != 0)
+ AntiReplay = 0;
+ else
+ AntiReplay = 1;
+
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+ ESPProto = SAB_ESP_PROTO_OUT_XFRM_CBC;
+ else
+ ESPProto = SAB_ESP_PROTO_OUT_CBC;
+ PadBlockByteCount = 4;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV6) !=0)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+ {
+ HeaderProto = SAB_HDR_IPV6_OUT_XFRM;
+ }
+ else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+ {
+ HeaderProto = SAB_HDR_IPV6_OUT_TUNNEL;
+ }
+ else
+ {
+ HeaderProto = SAB_HDR_IPV6_OUT_TRANSP;
+ }
+ }
+ else
+ {
+ HeaderProto = SAB_HDR_IPV6_OUT_TRANSP_HDRBYPASS;
+ }
+ }
+ else
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+ {
+ HeaderProto = SAB_HDR_IPV4_OUT_XFRM;
+ }
+ else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+ {
+ HeaderProto = SAB_HDR_IPV4_OUT_TUNNEL;
+ }
+ else
+ {
+ HeaderProto = SAB_HDR_IPV4_OUT_TRANSP;
+ }
+ }
+ else
+ {
+ HeaderProto = SAB_HDR_IPV4_OUT_TRANSP_HDRBYPASS;
+ }
+ }
+
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) != 0)
+ ExtSeq = 1;
+ }
+ else
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+ ESPProto = SAB_ESP_PROTO_IN_XFRM_CBC;
+ else
+ ESPProto = SAB_ESP_PROTO_IN_CBC;
+ PadBlockByteCount = 4;
+ TokenHeaderWord |= SAB_HEADER_PAD_VERIFY;
+
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV6) !=0)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+ {
+ HeaderProto = SAB_HDR_IPV6_IN_XFRM;
+ }
+ else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+ {
+ HeaderProto = SAB_HDR_IPV6_IN_TUNNEL;
+ }
+ else
+ {
+ HeaderProto = SAB_HDR_IPV6_IN_TRANSP;
+ TokenHeaderWord |= SAB_HEADER_UPD_HDR;
+ }
+ }
+ else
+ {
+ HeaderProto = SAB_HDR_IPV6_IN_TRANSP_HDRBYPASS;
+ }
+ }
+ else
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+ {
+ HeaderProto = SAB_HDR_IPV4_IN_XFRM;
+ }
+ else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+ {
+ HeaderProto = SAB_HDR_IPV4_IN_TUNNEL;
+ }
+ else
+ {
+ HeaderProto = SAB_HDR_IPV4_IN_TRANSP;
+ TokenHeaderWord |= SAB_HEADER_UPD_HDR;
+ }
+ }
+ else
+ {
+ HeaderProto = SAB_HDR_IPV4_IN_TRANSP_HDRBYPASS;
+ }
+ }
+
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) != 0)
+ ExtSeq = 1;
+ AntiReplay *= SAParamsIPsec_p->SequenceMaskBitCount / 32;
+ }
+ SeqOffset = SAParams_p->OffsetSeqNum;
+
+ switch (SAParams_p->CryptoAlgo)
+ {
+ case SAB_CRYPTO_NULL:
+ IVByteCount = 0;
+ break;
+ case SAB_CRYPTO_DES:
+ case SAB_CRYPTO_3DES:
+ IVByteCount = 8;
+ PadBlockByteCount = 8;
+ break;
+ case SAB_CRYPTO_AES:
+ case SAB_CRYPTO_SM4:
+ case SAB_CRYPTO_BC0:
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CBC)
+ {
+ IVByteCount = 16;
+ PadBlockByteCount = 16;
+ }
+ else
+ {
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ ESPProto = SAB_ESP_PROTO_OUT_CTR;
+ else
+ ESPProto = SAB_ESP_PROTO_IN_CTR;
+
+ if (SAParams_p->IVSrc == SAB_IV_SRC_IMPLICIT)
+ IVByteCount = 0;
+ else
+ IVByteCount = 8;
+ }
+ break;
+ case SAB_CRYPTO_CHACHA20:
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ ESPProto = SAB_ESP_PROTO_OUT_CHACHAPOLY;
+ else
+ ESPProto = SAB_ESP_PROTO_IN_CHACHAPOLY;
+
+ if (SAParams_p->IVSrc == SAB_IV_SRC_IMPLICIT)
+ IVByteCount = 0;
+ else
+ IVByteCount = 8;
+ break;
+ default:
+ LOG_CRIT("SABuilder_BuildSA:"
+ "Unsupported Crypto algorithm\n");
+ return SAB_INVALID_PARAMETER;
+ ;
+ }
+
+ /* For all inbound and CTR mode outbound packets there is
+ only one supported way to obtain the IV, which is already
+ taken care of. Now handle outbound CBC. */
+ if(SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CBC &&
+ SAParams_p->direction == SAB_DIRECTION_OUTBOUND &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+ {
+ switch (SAParams_p->IVSrc)
+ {
+ case SAB_IV_SRC_PRNG:
+ TokenHeaderWord |=
+ SAB_HEADER_IV_PRNG;
+ break;
+ case SAB_IV_SRC_DEFAULT:
+ case SAB_IV_SRC_SA: /* No action required */
+ case SAB_IV_SRC_TOKEN:
+ break;
+ default:
+ LOG_CRIT("SABuilder_BuildSA:"
+ "Unsupported IV source\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ }
+
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND &&
+ SAParamsIPsec_p->PadAlignment >
+ PadBlockByteCount &&
+ SAParamsIPsec_p->PadAlignment <= 256)
+ PadBlockByteCount =
+ SAParamsIPsec_p->PadAlignment;
+
+ switch(SAParams_p->AuthAlgo)
+ {
+ case SAB_AUTH_NULL:
+ ICVByteCount = 0;
+ ExtSeq = 0;
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ ESPProto = SAB_ESP_PROTO_OUT_NULLAUTH;
+ else
+ ESPProto = SAB_ESP_PROTO_IN_NULLAUTH;
+
+ break;
+ case SAB_AUTH_HMAC_MD5:
+ case SAB_AUTH_HMAC_SHA1:
+ case SAB_AUTH_AES_XCBC_MAC:
+ case SAB_AUTH_AES_CMAC_128:
+ ICVByteCount = 12;
+ break;
+ case SAB_AUTH_HMAC_SHA2_224:
+ case SAB_AUTH_HMAC_SHA2_256:
+ case SAB_AUTH_HMAC_SM3:
+ ICVByteCount = 16;
+ break;
+ case SAB_AUTH_HMAC_SHA2_384:
+ ICVByteCount = 24;
+ break;
+ case SAB_AUTH_HMAC_SHA2_512:
+ ICVByteCount = 32;
+ break;
+ case SAB_AUTH_AES_CCM:
+ case SAB_AUTH_AES_GCM:
+ case SAB_AUTH_AES_GMAC:
+ // All these protocols have a selectable ICV length.
+ if (SAParamsIPsec_p->ICVByteCount == 8 ||
+ SAParamsIPsec_p->ICVByteCount == 12 ||
+ SAParamsIPsec_p->ICVByteCount == 16)
+ {
+ ICVByteCount =
+ SAParamsIPsec_p->ICVByteCount;
+ }
+ else
+ {
+ ICVByteCount = 16;
+ }
+ switch (SAParams_p->AuthAlgo)
+ {
+ /* These protocols need specialized protocol codes
+ for the token generator.*/
+ case SAB_AUTH_AES_CCM:
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ ESPProto = SAB_ESP_PROTO_OUT_CCM;
+ else
+ ESPProto = SAB_ESP_PROTO_IN_CCM;
+
+ CCMSalt =
+ (SAParams_p->Nonce_p[0] << 8) |
+ (SAParams_p->Nonce_p[1] << 16) |
+ (SAParams_p->Nonce_p[2] << 24) |
+ SAB_CCM_FLAG_ADATA_L4 |
+ ((ICVByteCount-2)*4);
+ break;
+ case SAB_AUTH_AES_GCM:
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+ ESPProto = SAB_ESP_PROTO_OUT_XFRM_GCM;
+ else
+ ESPProto = SAB_ESP_PROTO_OUT_GCM;
+ }
+ else
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+ ESPProto = SAB_ESP_PROTO_IN_XFRM_GCM;
+ else
+ ESPProto = SAB_ESP_PROTO_IN_GCM;
+ }
+ break;
+ case SAB_AUTH_AES_GMAC:
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ ESPProto = SAB_ESP_PROTO_OUT_GMAC;
+ else
+ ESPProto = SAB_ESP_PROTO_IN_GMAC;
+ break;
+ default:
+ ;
+ }
+ break;
+ case SAB_AUTH_POLY1305:
+ ICVByteCount = 16;
+ break;
+ default:
+ LOG_CRIT("SABuilder_BuildSA: unsupported authentication algorithm\n");
+ return SAB_UNSUPPORTED_FEATURE;
+ }
+
+
+ /* Flags variable */
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV6) !=0)
+ flags |= BIT_8;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+ flags |= BIT_19;
+ if (ExtSeq !=0)
+ flags |= BIT_29;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_DEC_TTL) != 0)
+ flags |= BIT_27;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_CLEAR_DF) != 0)
+ flags |= BIT_20;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_SET_DF) != 0)
+ flags |= BIT_21;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_REPLACE_DSCP) != 0)
+ flags |= BIT_22;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_CLEAR_ECN) != 0)
+ flags |= BIT_23;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_APPEND_SEQNUM) != 0)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) != 0)
+ flags |= BIT_25;
+ else
+ flags |= BIT_24;
+ }
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TRANSPORT_NAT) != 0)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) != 0)
+ {
+ LOG_CRIT("NAT only for transport\n");
+ return SAB_INVALID_PARAMETER;
+ }
+ if (SAParams_p->direction==SAB_DIRECTION_INBOUND &&
+ SAParamsIPsec_p->SequenceMaskBitCount > 128)
+ {
+ if (SAState_p->fLarge && LargeTransformOffset == 16)
+ {
+ LOG_CRIT(
+ "SABuilder_BuildSA: Inbound NAT cannot be combined with \n"
+ " anti-replay mask > 128\n and HMAC-SHA384/512\n");
+ return SAB_UNSUPPORTED_FEATURE;
+ }
+ else if (SAParams_p->OffsetSeqNum == SAB_SEQNUM_HI_FIX_OFFSET &&
+ SAParamsIPsec_p->SequenceMaskBitCount > 384)
+ {
+ LOG_CRIT(
+ "SABuilder_BuildSA: Inbound NAT cannot be combined with \n"
+ " anti-replay mask > 384\n and HMAC-SHA384/512\n");
+ return SAB_UNSUPPORTED_FEATURE;
+ }
+ else
+ {
+ SAState_p->fLarge = true;
+ }
+ }
+ flags |= BIT_28;
+ }
+
+ /* Take care of the VERIFY and CTX token instructions */
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ VerifyInstructionWord = SAB_VERIFY_NONE;
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+ {
+ if (SAState_p->fLarge)
+ {
+ CtxInstructionWord = SAB_CTX_NONE + FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT + LargeTransformOffset - 1;
+ }
+ else
+#endif
+ {
+ CtxInstructionWord = SAB_CTX_NONE + FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT - 1;
+ }
+ }
+ else
+ {
+ CtxInstructionWord = SAB_CTX_OUT_SEQNUM +
+ ((unsigned int)(ExtSeq+1)<<24) + SeqOffset;
+ }
+ }
+ else
+ {
+ VerifyInstructionWord = SAB_VERIFY_PADSPI;
+ if (ICVByteCount > 0)
+ {
+ VerifyInstructionWord += SAB_VERIFY_BIT_H + ICVByteCount;
+ }
+ if (AntiReplay > 0 &&
+ (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_APPEND_SEQNUM) == 0 &&
+ (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) == 0)
+ {
+ /* Skip verification of sequence number in sequence number append
+ mode. */
+ VerifyInstructionWord += SAB_VERIFY_BIT_SEQ;
+ }
+ if (ICVByteCount == 0 || AntiReplay == 0 ||
+ (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_XFRM_API) != 0)
+ {
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+ if (SAState_p->fLarge)
+ {
+ CtxInstructionWord = SAB_CTX_NONE + FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT + LargeTransformOffset - 1;
+ }
+ else
+#endif
+ {
+ CtxInstructionWord = SAB_CTX_NONE + FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT - 1;
+ }
+ }
+ else if (ExtSeq != 0 ||
+ (AntiReplay != 0 &&
+ SAParams_p->OffsetSeqNum + 2 == SAParams_p->OffsetSeqMask))
+ {
+ if (AntiReplay > 12)
+ CtxInstructionWord = SAB_CTX_SEQNUM +
+ + SeqOffset;
+ else
+ CtxInstructionWord = SAB_CTX_SEQNUM +
+ ((unsigned int)(2+AntiReplay)<<24) + SeqOffset;
+ }
+ else
+ {
+ CtxInstructionWord = SAB_CTX_INSEQNUM +
+ ((unsigned int)(1+AntiReplay)<<24) + SeqOffset;
+ }
+ }
+
+#ifdef SAB_ENABLE_EXTENDED_TUNNEL_HEADER
+ /* Compute the maximum amount by which the packet can be enlarged,
+ so discount that from the output MTU to judge whether a packet can
+ be processed without fragmentation. */
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ MTUDiscount = ESP_HDR_LEN + 1 + PadBlockByteCount +
+ IVByteCount + ICVByteCount;
+
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV4) !=0)
+ MTUDiscount += IPV4_HDR_LEN;
+ else
+ MTUDiscount += IPV6_HDR_LEN;
+
+ // for IPv4 tunnel, pre-calculate checksum on IP addresses and store them in the transform record
+ // this checksum does not include the final inversion and is performed on data
+ // as they stored in the memory
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV4) !=0)
+ {
+ // protection against NULL pointers
+ if ((SAParamsIPsec_p->SrcIPAddr_p != NULL)&&
+ (SAParamsIPsec_p->DestIPAddr_p != NULL))
+ {
+ // add the addresses (in order they are stored in the memory)
+ CheckSum += get16no(SAParamsIPsec_p->SrcIPAddr_p, 0);
+ CheckSum += get16no(SAParamsIPsec_p->SrcIPAddr_p, 2);
+ CheckSum += get16no(SAParamsIPsec_p->DestIPAddr_p, 0);
+ CheckSum += get16no(SAParamsIPsec_p->DestIPAddr_p, 2);
+
+ // process the carries
+ while ((CheckSum>>16) != 0)
+ CheckSum = (CheckSum>>16) + (CheckSum & 0xffff);
+ }
+ }
+ }
+ }
+ /* Compute the checksum delta for internal NAT operations and for inbound
+ transport NAT-T checksum fixup */
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) == 0 &&
+ (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_CHECKSUM_FIX) != 0)
+ {
+ uint8_t IPLen = SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV4?4:16;
+ unsigned int i;
+ // Compute source address delta only if both original and new source
+ // addresses are provided, otherwise assume source address is unchanged.
+ if (SAParamsIPsec_p->SrcIPAddr_p != NULL &&
+ SAParamsIPsec_p->OrigSrcIPAddr_p != NULL)
+ {
+ for (i=0; i<IPLen; i+=2)
+ {
+ CheckSum += get16no(SAParamsIPsec_p->SrcIPAddr_p, i);
+ CheckSum += get16no(SAParamsIPsec_p->OrigSrcIPAddr_p, i) ^ 0xffff;
+ }
+ }
+ // Compute destination address delta only if both original and
+ // new destination addresses are provided, otherwise assume
+ // destination address is unchanged.
+ if (SAParamsIPsec_p->DestIPAddr_p != NULL &&
+ SAParamsIPsec_p->OrigDestIPAddr_p != NULL)
+ {
+ for (i=0; i<IPLen; i+=2)
+ {
+ CheckSum += get16no(SAParamsIPsec_p->DestIPAddr_p, i);
+ CheckSum += get16no(SAParamsIPsec_p->OrigDestIPAddr_p, i) ^ 0xffff;
+ }
+ }
+ // process the carries
+ while ((CheckSum>>16) != 0)
+ CheckSum = (CheckSum>>16) + (CheckSum & 0xffff);
+ }
+
+#endif
+
+ /* If NAT-T selected, select other header protocol range */
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_NATT) != 0)
+ HeaderProto += (SAB_HDR_IPV4_OUT_TRANSP_HDRBYPASS_NATT -
+ SAB_HDR_IPV4_OUT_TRANSP_HDRBYPASS);
+
+ /* Write all parameters to their respective offsets */
+ if (SABuffer_p != NULL)
+ {
+#ifdef SAB_ENABLE_TWO_FIXED_RECORD_SIZES
+ if (SAState_p->fLarge)
+ {
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET +
+ LargeTransformOffset] = flags;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET +
+ LargeTransformOffset] =
+ SAParamsIPsec_p->ContextRef;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET +
+ LargeTransformOffset] =
+ SAB_PACKBYTES(IVByteCount,ICVByteCount,HeaderProto,ESPProto);
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET +
+ LargeTransformOffset] = TokenHeaderWord;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_CHECKSUM_FIX) != 0 &&
+ (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) == 0)
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET +
+ LargeTransformOffset] =
+ SAB_PACKBYTES(PadBlockByteCount/2,
+ 0,
+ CheckSum & 0xff,
+ CheckSum >> 8);
+ else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) != 0)
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET +
+ LargeTransformOffset] =
+ SAB_PACKBYTES(PadBlockByteCount/2,
+ 0,
+ SAParamsIPsec_p->TTL,
+ SAParamsIPsec_p->DSCP);
+ else
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET
+ + LargeTransformOffset] =
+ SAB_PACKBYTES(PadBlockByteCount/2,
+ 0,
+ 0,
+ 0);
+
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET +
+ LargeTransformOffset] = CCMSalt;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET +
+ LargeTransformOffset] =
+ VerifyInstructionWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET +
+ LargeTransformOffset] =
+ CtxInstructionWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET +
+ LargeTransformOffset] = 0;
+#ifdef SAB_ENABLE_EXTENDED_TUNNEL_HEADER
+ SABuffer_p[FIMRWARE_EIP207_CS_FLOW_TR_NATT_PORTS_WORD_OFFSET +
+ LargeTransformOffset] =
+ SAB_PACKBYTES(SAParamsIPsec_p->NATTSrcPort >> 8,
+ SAParamsIPsec_p->NATTSrcPort & 0xff,
+ SAParamsIPsec_p->NATTDestPort >> 8,
+ SAParamsIPsec_p->NATTDestPort & 0xff);
+
+ if (HeaderProto == SAB_HDR_IPV4_OUT_TUNNEL ||
+ HeaderProto == SAB_HDR_IPV6_OUT_TUNNEL ||
+ HeaderProto == SAB_HDR_IPV4_OUT_TUNNEL_NATT ||
+ HeaderProto == SAB_HDR_IPV6_OUT_TUNNEL_NATT ||
+ (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TRANSPORT_NAT) != 0)
+ {
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParamsIPsec_p->SrcIPAddr_p == NULL ||
+ SAParamsIPsec_p->DestIPAddr_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer tunnel address.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_SRC_WORD_OFFSET + LargeTransformOffset,
+ SAParamsIPsec_p->SrcIPAddr_p,
+ (SAParamsIPsec_p->IPsecFlags&SAB_IPSEC_IPV4)!=0?4:16);
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_DST_WORD_OFFSET + LargeTransformOffset,
+ SAParamsIPsec_p->DestIPAddr_p,
+ (SAParamsIPsec_p->IPsecFlags&SAB_IPSEC_IPV4)!=0?4:16);
+
+#ifdef FIRMWARE_EIP207_CS_FLOW_TR_CHECKSUM_WORD_OFFSET
+ // checksum (only for IPv4)
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV4) !=0)
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CHECKSUM_WORD_OFFSET +
+ LargeTransformOffset] = CheckSum;
+#endif
+ }
+
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PATH_MTU_WORD_OFFSET +
+ LargeTransformOffset] = MTUDiscount;
+#endif /* SAB_ENABLE_EXTENDED_TUNNEL_HEADER */
+ }
+ else
+#endif /* SAB_ENABLE_TWO_FIXED_RECORD_SIZES */
+ {
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET] = flags;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET] =
+ SAParamsIPsec_p->ContextRef;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET] =
+ SAB_PACKBYTES(IVByteCount,ICVByteCount,HeaderProto,ESPProto);
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET] = TokenHeaderWord;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_CHECKSUM_FIX) != 0 &&
+ (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) == 0)
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET] =
+ SAB_PACKBYTES(PadBlockByteCount/2,
+ 0,
+ CheckSum & 0xff,
+ CheckSum >> 8);
+ else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) != 0)
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET] =
+ SAB_PACKBYTES(PadBlockByteCount/2,
+ 0,
+ SAParamsIPsec_p->TTL,
+ SAParamsIPsec_p->DSCP);
+ else
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET] =
+ SAB_PACKBYTES(PadBlockByteCount/2,
+ 0,
+ 0,
+ 0);
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET] = CCMSalt;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET] =
+ VerifyInstructionWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET] =
+ CtxInstructionWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET] = 0;
+#ifdef SAB_ENABLE_EXTENDED_TUNNEL_HEADER
+ SABuffer_p[FIMRWARE_EIP207_CS_FLOW_TR_NATT_PORTS_WORD_OFFSET] =
+ SAB_PACKBYTES(SAParamsIPsec_p->NATTSrcPort >> 8,
+ SAParamsIPsec_p->NATTSrcPort & 0xff,
+ SAParamsIPsec_p->NATTDestPort >> 8,
+ SAParamsIPsec_p->NATTDestPort & 0xff);
+
+ if (HeaderProto == SAB_HDR_IPV4_OUT_TUNNEL ||
+ HeaderProto == SAB_HDR_IPV6_OUT_TUNNEL ||
+ HeaderProto == SAB_HDR_IPV4_OUT_TUNNEL_NATT ||
+ HeaderProto == SAB_HDR_IPV6_OUT_TUNNEL_NATT ||
+ (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TRANSPORT_NAT) != 0)
+ {
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParamsIPsec_p->SrcIPAddr_p == NULL ||
+ SAParamsIPsec_p->DestIPAddr_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer tunnel address.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_SRC_WORD_OFFSET,
+ SAParamsIPsec_p->SrcIPAddr_p,
+ (SAParamsIPsec_p->IPsecFlags&SAB_IPSEC_IPV4)!=0?4:16);
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_DST_WORD_OFFSET,
+ SAParamsIPsec_p->DestIPAddr_p,
+ (SAParamsIPsec_p->IPsecFlags&SAB_IPSEC_IPV4)!=0?4:16);
+
+#ifdef FIRMWARE_EIP207_CS_FLOW_TR_CHECKSUM_WORD_OFFSET
+ // checksum (only for IPv4)
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV4) !=0)
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CHECKSUM_WORD_OFFSET] = CheckSum;
+#endif
+
+ }
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PATH_MTU_WORD_OFFSET] = MTUDiscount;
+#endif /* SAB_ENABLE_EXTENDED_TUNNEL_HEADER */
+ }
+ }
+ return SAB_STATUS_OK;
+}
+
+
+#endif /* SAB_ENABLE_IPSEC_EXTENDED */
+
+
+/* end of file sa_builder_extended_ipsec.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_macsec.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_macsec.c
new file mode 100644
index 0000000..38b3312
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_extended_macsec.c
@@ -0,0 +1,187 @@
+/* sa_builder_extended_macsec.c
+ *
+ * MACsec specific functions (for initialization of SABuilder_Params_t
+ * structures and for building the MACsec specific part of an SA) in the
+ * Extended use case.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2013-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#ifdef SAB_ENABLE_MACSEC_EXTENDED
+#include "sa_builder_extended_internal.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "basic_defs.h"
+#include "log.h"
+#include "sa_builder_internal.h" /* SABuilder_SetMACsecParams */
+#include "sa_builder_macsec.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+#define SAB_MACSEC_ETHER_TYPE 0x88e5
+/* Various bits in the TCI byte */
+#define SAB_MACSEC_TCI_ES BIT_6
+#define SAB_MACSEC_TCI_SC BIT_5
+#define SAB_MACSEC_TCI_SCB BIT_4
+#define SAB_MACSEC_TCI_E BIT_3
+#define SAB_MACSEC_TCI_C BIT_2
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetExtendedMACsecParams
+ *
+ * Fill in MACsec-specific extensions into the SA.for Extended.
+ *
+ * SAParams_p (input)
+ * The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ * Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ * The buffer in which the SA is built. If NULL, no SA will be built, but
+ * state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ * the buffer arguments is a null pointer while the corresponding buffer
+ * would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ * is not supported on the hardware for which this SA builder
+ * is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetExtendedMACsecParams(SABuilder_Params_t *const SAParams_p,
+ SABuilder_State_t * const SAState_p,
+ uint32_t * const SABuffer_p)
+{
+ SABuilder_Params_MACsec_t *SAParamsMACsec_p =
+ (SABuilder_Params_MACsec_t *)(SAParams_p->ProtocolExtension_p);
+ uint32_t TokenHeaderWord = SAB_HEADER_DEFAULT;
+ SABuilder_ESPProtocol_t ESPProto;
+ SABuilder_HeaderProtocol_t HeaderProto;
+ uint8_t IVByteCount;
+ uint8_t ICVByteCount;
+ uint8_t SeqOffset;
+ uint8_t TCI; /* TCI byte in SECtag */
+ uint32_t flags = 0;
+ uint32_t VerifyInstructionWord, CtxInstructionWord;
+
+ IDENTIFIER_NOT_USED(SAState_p);
+
+ if (SAParamsMACsec_p == NULL)
+ {
+ LOG_CRIT("SABuilder: MACsec extension pointer is null\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ SeqOffset = SAParams_p->OffsetSeqNum;
+ ICVByteCount = 16;
+ TCI = SAParamsMACsec_p->AN;
+ if ((SAParamsMACsec_p->MACsecFlags & SAB_MACSEC_ES) != 0)
+ {
+ TCI |= SAB_MACSEC_TCI_ES;
+ }
+ if ((SAParamsMACsec_p->MACsecFlags & SAB_MACSEC_SC) != 0)
+ {
+ IVByteCount = 8;
+ TCI |= SAB_MACSEC_TCI_SC;
+ }
+ else
+ {
+ IVByteCount = 0;
+ }
+ if ((SAParamsMACsec_p->MACsecFlags & SAB_MACSEC_SCB) != 0)
+ {
+ TCI |= SAB_MACSEC_TCI_SCB;
+ }
+
+ if (SAParams_p->AuthAlgo == SAB_AUTH_AES_GCM)
+ TCI |= SAB_MACSEC_TCI_E | SAB_MACSEC_TCI_C;
+
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ HeaderProto = SAB_HDR_MACSEC_OUT;
+ if (SAParams_p->AuthAlgo == SAB_AUTH_AES_GCM)
+ ESPProto = SAB_MACSEC_PROTO_OUT_GCM;
+ else
+ ESPProto = SAB_MACSEC_PROTO_OUT_GMAC;
+ VerifyInstructionWord = SAB_VERIFY_NONE;
+ CtxInstructionWord = SAB_CTX_OUT_SEQNUM +
+ ((unsigned int)(1<<24)) + SeqOffset;
+ }
+ else
+ {
+ HeaderProto = SAB_HDR_MACSEC_IN;
+ if (SAParams_p->AuthAlgo == SAB_AUTH_AES_GCM)
+ ESPProto = SAB_MACSEC_PROTO_IN_GCM;
+ else
+ ESPProto = SAB_MACSEC_PROTO_IN_GMAC;
+ VerifyInstructionWord = SAB_VERIFY_NONE + SAB_VERIFY_BIT_H +
+ SAB_VERIFY_BIT_SEQ + ICVByteCount;
+ CtxInstructionWord = SAB_CTX_SEQNUM +
+ ((unsigned int)(1<<24)) + SeqOffset;
+ }
+
+ /* Write all parameters to their respective offsets */
+ if (SABuffer_p != NULL)
+ {
+ /* Do not support large transform records as Macsec will never
+ use HMAC-SHA512 */
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_FLAGS_WORD_OFFSET] = flags;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_HDRPROC_CTX_WORD_OFFSET] =
+ SAParamsMACsec_p->ContextRef;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_BYTE_PARAM_WORD_OFFSET] =
+ SAB_PACKBYTES(IVByteCount,ICVByteCount,HeaderProto,ESPProto);
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_HDR_WORD_OFFSET] = TokenHeaderWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_PAD_ALIGN_WORD_OFFSET] =
+ SAB_PACKBYTES(SAB_MACSEC_ETHER_TYPE>>8,
+ SAB_MACSEC_ETHER_TYPE &0xff, TCI, 0);
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_CCM_SALT_WORD_OFFSET] =
+ SAParamsMACsec_p->ConfOffset;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_VFY_INST_WORD_OFFSET] =
+ VerifyInstructionWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET] =
+ CtxInstructionWord;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET] = 0;
+ SABuffer_p[FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET] = 0;
+
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ FIRMWARE_EIP207_CS_FLOW_TR_TUNNEL_SRC_WORD_OFFSET,
+ SAParamsMACsec_p->SCI_p, 8);
+ }
+ return SAB_STATUS_OK;
+}
+
+#endif /* SAB_ENABLE_MACSEC_EXTENDED */
+
+
+/* end of file sa_builder_extended_dtls.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_ipsec.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_ipsec.c
new file mode 100644
index 0000000..eb5144d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_ipsec.c
@@ -0,0 +1,722 @@
+/* sa_builder_ipsec.c
+ *
+ * IPsec specific functions (for initialization of SABuilder_Params_t
+ * structures and for building the IPSec specifc part of an SA.).
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "sa_builder_ipsec.h"
+#include "sa_builder_internal.h" /* SABuilder_SetIpsecParams */
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#include "basic_defs.h"
+#include "log.h"
+
+#ifdef SAB_ENABLE_PROTO_IPSEC
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+#ifdef SAB_ENABLE_1024BIT_SEQMASK
+#define SAB_SEQUENCE_MAXBITS 1024
+#elif defined(SAB_ENABLE_384BIT_SEQMASK)
+#define SAB_SEQUENCE_MAXBITS 384
+#else
+#define SAB_SEQUENCE_MAXBITS 128
+#endif
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_ESP
+ *
+ * This function initializes the SABuilder_Params_t data structure and its
+ * SABuilder_Params_IPsec_t extension with sensible defaults for ESP
+ * processing.
+ *
+ * SAParams_p (output)
+ * Pointer to SA parameter structure to be filled in.
+ * SAParamsIPsec_p (output)
+ * Pointer to IPsec parameter extension to be filled in
+ * spi (input)
+ * SPI of the newly created parameter structure (must not be zero).
+ * TunnelTransport (input)
+ * Must be one of SAB_IPSEC_TUNNEL or SAB_IPSEC_TRANSPORT.
+ * IPMode (input)
+ * Must be one of SAB_IPSEC_IPV4 or SAB_IPSEC_IPV6.
+ * direction (input)
+ * Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Both the crypto and the authentication algorithm are initialized to
+ * NULL, which is illegal according to the IPsec standards, but it is
+ * possible to use this setting for debug purposes.
+ *
+ * Both the SAParams_p and SAParamsIPsec_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsIPsec_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ * or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_ESP(
+ SABuilder_Params_t * const SAParams_p,
+ SABuilder_Params_IPsec_t * const SAParamsIPsec_p,
+ const uint32_t spi,
+ const uint32_t TunnelTransport,
+ const uint32_t IPMode,
+ const SABuilder_Direction_t direction)
+{
+ int i;
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p == NULL || SAParamsIPsec_p == NULL)
+ {
+ LOG_CRIT("SABuilder_Init_ESP: NULL pointer parameter supplied.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if (spi == 0)
+ {
+ LOG_CRIT("SABuilder_Init_ESP: SPI may not be 0.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if (TunnelTransport != SAB_IPSEC_TUNNEL &&
+ TunnelTransport != SAB_IPSEC_TRANSPORT)
+ {
+ LOG_CRIT("SABuilder_Init_ESP: Invalid TunnelTransport.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if (IPMode != SAB_IPSEC_IPV4 && IPMode != SAB_IPSEC_IPV6)
+ {
+ LOG_CRIT("SABuilder_Init_ESP: Invalid IPMode.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if (direction != SAB_DIRECTION_OUTBOUND &&
+ direction != SAB_DIRECTION_INBOUND)
+ {
+ LOG_CRIT("SABuilder_Init_ESP: Invalid direction.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+
+ SAParams_p->protocol = SAB_PROTO_IPSEC;
+ SAParams_p->direction = direction;
+ SAParams_p->ProtocolExtension_p = (void*)SAParamsIPsec_p;
+ SAParams_p->flags = 0;
+ SAParams_p->RedirectInterface = 0;
+
+ SAParams_p->CryptoAlgo = SAB_CRYPTO_NULL;
+ SAParams_p->CryptoMode = SAB_CRYPTO_MODE_CBC;
+ SAParams_p->IVSrc = SAB_IV_SRC_DEFAULT;
+ SAParams_p->CryptoParameter = 0;
+ SAParams_p->KeyByteCount = 0;
+ SAParams_p->Key_p = NULL;
+ SAParams_p->IV_p = NULL;
+ SAParams_p->Nonce_p = NULL;
+
+ SAParams_p->AuthAlgo = SAB_AUTH_NULL;
+ SAParams_p->AuthKey1_p = NULL;
+ SAParams_p->AuthKey2_p = NULL;
+ SAParams_p->AuthKey3_p = NULL;
+ SAParams_p->AuthKeyByteCount = 0;
+
+ SAParams_p->OffsetARC4StateRecord = 0;
+ SAParams_p->CW0 = 0;
+ SAParams_p->CW1 = 0;
+ SAParams_p->OffsetDigest0 = 0;
+ SAParams_p->OffsetDigest1 = 0;
+ SAParams_p->OffsetSeqNum = 0;
+ SAParams_p->OffsetSeqMask = 0;
+ SAParams_p->OffsetIV = 0;
+ SAParams_p->OffsetIJPtr = 0;
+ SAParams_p->OffsetARC4State = 0;
+ SAParams_p->SeqNumWord32Count = 0;
+ SAParams_p->SeqMaskWord32Count = 0;
+ SAParams_p->IVWord32Count = 0;
+
+ SAParamsIPsec_p->spi = spi;
+ SAParamsIPsec_p->IPsecFlags = SAB_IPSEC_ESP | TunnelTransport | IPMode;
+ SAParamsIPsec_p->SeqNum = 0;
+ SAParamsIPsec_p->SeqNumHi = 0;
+ SAParamsIPsec_p->SeqMask[0] = 1;
+ for (i=1; i<SA_SEQ_MASK_WORD_COUNT; i++)
+ SAParamsIPsec_p->SeqMask[i] = 0;
+ SAParamsIPsec_p->PadAlignment = 0;
+ SAParamsIPsec_p->ICVByteCount = 0;
+ SAParamsIPsec_p->SrcIPAddr_p = NULL;
+ SAParamsIPsec_p->DestIPAddr_p = NULL;
+ SAParamsIPsec_p->OrigSrcIPAddr_p = NULL;
+ SAParamsIPsec_p->OrigDestIPAddr_p = NULL;
+ SAParamsIPsec_p->NATTSrcPort = 4500;
+ SAParamsIPsec_p->NATTDestPort = 4500;
+ SAParamsIPsec_p->ContextRef = 0;
+ SAParamsIPsec_p->TTL = 240;
+ SAParamsIPsec_p->DSCP = 0;
+ SAParamsIPsec_p->SequenceMaskBitCount = 0;
+ return SAB_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetIPsecParams
+ *
+ * Fill in IPsec-specific extensions into the SA.
+ *
+ * SAParams_p (input, updated)
+ * The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ * Variables containing information about the SA being generated/
+ * SABuffer_p (output).
+ * The buffer in which the SA is built. If NULL, no SA will be built, but
+ * state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ * the buffer arguments is a null pointer while the corresponding buffer
+ * would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ * is not supported on the hardware for which this SA builder
+ * is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetIPsecParams(SABuilder_Params_t *const SAParams_p,
+ SABuilder_State_t * const SAState_p,
+ uint32_t * const SABuffer_p)
+{
+ unsigned int IVOffset = 0;
+ SABuilder_Params_IPsec_t *SAParamsIPsec_p;
+ bool fFixedSeqOffset = false;
+ SAParamsIPsec_p = (SABuilder_Params_IPsec_t *)
+ (SAParams_p->ProtocolExtension_p);
+ if (SAParamsIPsec_p == NULL)
+ {
+ LOG_CRIT("SABuilder: IPsec extension pointer is null\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* First check whether AH or ESP flags are correct */
+
+ if ( (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_AH) != 0)
+ {
+#ifdef SAB_ENABLE_IPSEC_AH
+ if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL ||
+ (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_ESP) != 0)
+ {
+ LOG_CRIT("SABuilder: AH does not support crypto.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#else
+ LOG_CRIT("SABuilder: AH unsupported..\n");
+ return SAB_INVALID_PARAMETER;
+#endif
+ }
+
+#ifndef SAB_ENABLE_IPSEC_ESP
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_ESP) != 0)
+ {
+ LOG_CRIT("SABuilder: ESP unsupported.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+
+ /* Check for supported algorithms and crypto modes in IPsec */
+ if ((SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_DES &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_3DES &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_AES &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_CHACHA20 &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_SM4 &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_BC0) ||
+ (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL && (
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CBC &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CTR &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GCM &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GMAC &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CCM &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CHACHA_CTR32)))
+ {
+ LOG_CRIT("SABuilder: IPsec: crypto algorithm/mode not supported\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* Check for supported authentication algorithms in IPsec */
+ if (SAParams_p->AuthAlgo != SAB_AUTH_NULL &&
+ SAParams_p->AuthAlgo != SAB_AUTH_HMAC_MD5 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA1 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA2_256 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA2_384 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA2_512 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_AES_XCBC_MAC &&
+ SAParams_p->AuthAlgo != SAB_AUTH_AES_CMAC_128 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_AES_GCM &&
+ SAParams_p->AuthAlgo != SAB_AUTH_AES_GMAC &&
+ SAParams_p->AuthAlgo != SAB_AUTH_AES_CCM &&
+ SAParams_p->AuthAlgo != SAB_AUTH_POLY1305 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SM3)
+ {
+ LOG_CRIT("SABuilder: IPsec: auth algorithm not supported\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* Add SPI to SA record */
+ if (SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] = SAParamsIPsec_p->spi;
+ SAState_p->CurrentOffset += 1;
+
+ /* Determine whether we will have a fixed sequence number offset */
+ if (SAParams_p->direction == SAB_DIRECTION_INBOUND)
+ {
+ /* Determine size of sequence number mask in bits */
+ if (SAParamsIPsec_p->SequenceMaskBitCount == 0)
+ {
+ /* Some flags indicate specific mask sizes */
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_MASK_384) != 0)
+ {
+ SAParamsIPsec_p->SequenceMaskBitCount = 384;
+ }
+ else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_MASK_256) != 0)
+ {
+ SAParamsIPsec_p->SequenceMaskBitCount = 256;
+ }
+ else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_MASK_128) != 0)
+ {
+ SAParamsIPsec_p->SequenceMaskBitCount = 128;
+ }
+ else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_MASK_32) != 0)
+ {
+ SAParamsIPsec_p->SequenceMaskBitCount = 32;
+ }
+ else
+ {
+ SAParamsIPsec_p->SequenceMaskBitCount = 64;
+ }
+ }
+ if (SAParamsIPsec_p->SequenceMaskBitCount > SAB_SEQUENCE_MAXBITS ||
+ (SAParamsIPsec_p->SequenceMaskBitCount & 0x1f) != 0)
+ {
+ LOG_CRIT("SABuilder: Illegal sequence mask size.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#ifdef SAB_ENABLE_DEFAULT_FIXED_OFFSETS
+ fFixedSeqOffset = true;
+#else
+ if (SAParamsIPsec_p->SequenceMaskBitCount > 128 ||
+ (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_FIXED_SEQ_OFFSET) != 0)
+ {
+ fFixedSeqOffset = true;
+ }
+#endif
+ if (SAParamsIPsec_p->SequenceMaskBitCount ==32)
+ {
+ fFixedSeqOffset = false; /* not supported for 32-bit mask */
+ }
+ }
+
+ if (fFixedSeqOffset)
+ {
+ /* Use a fixed sequence number offset for inbound if the hardware
+ supports it. */
+ /* Take care to insert the IV (nonce) just after the SPI. */
+ IVOffset = SAState_p->CurrentOffset;
+
+ /* Select one of two fixed offsets for the sequence number */
+ if (SAState_p->CurrentOffset < SAB_SEQNUM_LO_FIX_OFFSET)
+ {
+ SAState_p->CurrentOffset = SAB_SEQNUM_LO_FIX_OFFSET;
+ }
+ else
+ {
+ SAState_p->CurrentOffset = SAB_SEQNUM_HI_FIX_OFFSET;
+ }
+
+ /* Add sequence number */
+ SAParams_p->OffsetSeqNum = SAState_p->CurrentOffset;
+
+ if (SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] = SAParamsIPsec_p->SeqNum;
+
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) != 0)
+ {
+ if (SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset+1] = SAParamsIPsec_p->SeqNumHi;
+ SAState_p->CW0 |= SAB_CW0_SPI | SAB_CW0_SEQNUM_64_FIX;
+ SAParams_p->SeqNumWord32Count = 2;
+ }
+ else
+ {
+ SAState_p->CW0 |= SAB_CW0_SPI | SAB_CW0_SEQNUM_32_FIX;
+ SAParams_p->SeqNumWord32Count = 1;
+ }
+ // Always reserve 2 words for the sequence number.
+ SAState_p->CurrentOffset += 2;
+ }
+ else
+ {
+ /* Add sequence number */
+ SAParams_p->OffsetSeqNum = SAState_p->CurrentOffset;
+
+ if (SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] = SAParamsIPsec_p->SeqNum;
+ SAState_p->CurrentOffset += 1;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) != 0)
+ {
+ if (SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] = SAParamsIPsec_p->SeqNumHi;
+ SAState_p->CW0 |= SAB_CW0_SPI | SAB_CW0_SEQNUM_64;
+ SAState_p->CurrentOffset += 1;
+
+ SAParams_p->SeqNumWord32Count = 2;
+ }
+ else
+ {
+ SAState_p->CW0 |= SAB_CW0_SPI | SAB_CW0_SEQNUM_32;
+ SAParams_p->SeqNumWord32Count = 1;
+ }
+ }
+
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+
+ if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL &&
+ SAParams_p->AuthAlgo==SAB_AUTH_NULL)
+ SAState_p->CW0 |= SAB_CW0_TOP_NULL_OUT;
+ else if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL)
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_OUT;
+ else if (SAParams_p->AuthAlgo==SAB_AUTH_NULL)
+ SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT;
+ else if (SAParams_p->AuthAlgo==SAB_AUTH_AES_CCM ||
+ SAParams_p->AuthAlgo==SAB_AUTH_AES_GMAC)
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_ENCRYPT;
+ else
+ SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT_HASH;
+
+ /* Some versions of the hardware can update the sequence number
+ early, so multiple engines can operate in parallel. */
+ SAState_p->CW1 |= SAB_CW1_EARLY_SEQNUM_UPDATE;
+ SAState_p->CW1 |= SAParams_p->OffsetSeqNum << 24;
+
+ SAState_p->CW1 |= SAB_CW1_SEQNUM_STORE;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_NO_ANTI_REPLAY)!=0 &&
+ (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) == 0)
+ {
+ /* Disable outbound sequence number rollover checking by putting
+ an 64-sequence number in the SA. This will not be
+ used in authentication (no ESN) */
+ if (SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] = 0;
+ SAState_p->CW0 |= SAB_CW0_SEQNUM_64;
+ SAState_p->CurrentOffset += 1;
+ }
+
+ /* Take care of IV and nonce */
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CTR ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GMAC ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CHACHA_CTR32)
+ {
+ if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT)
+ SAParams_p->IVSrc = SAB_IV_SRC_SEQ;
+
+ /* Add nonce, always present */
+ SAState_p->CW1 |= SAB_CW1_IV0;
+ if (SABuffer_p != NULL)
+ {
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+ SABuffer_p[SAState_p->CurrentOffset] =
+ (SAParams_p->Nonce_p[0] << 8) |
+ (SAParams_p->Nonce_p[1] << 16) |
+ (SAParams_p->Nonce_p[2] << 24) | SAB_CCM_FLAG_L4;
+ else
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->Nonce_p,
+ sizeof(uint32_t));
+ }
+ SAState_p->CurrentOffset +=1;
+
+ if (SAParams_p->IVSrc == SAB_IV_SRC_SEQ)
+ {
+ SAState_p->CW1 |= SAB_CW1_IV_ORIG_SEQ;
+ }
+ else if (SAParams_p->IVSrc == SAB_IV_SRC_IMPLICIT)
+ {
+ SAState_p->CW1 |= SAB_CW1_IV_INCR_SEQ;
+ }
+ else if (SAParams_p->IVSrc == SAB_IV_SRC_XORSEQ)
+ {
+ SAState_p->CW1 |= SAB_CW1_IV_CTR|SAB_CW1_CRYPTO_NONCE_XOR;
+ SAState_p->CW1 |= SAB_CW1_IV0|SAB_CW1_IV1|SAB_CW1_IV2;
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->IV_p,
+ 2*sizeof(uint32_t));
+ SAState_p->CurrentOffset +=2;
+ }
+ else if (SAParams_p->IVSrc == SAB_IV_SRC_SA)
+ {
+ SAState_p->CW1 |= SAB_CW1_IV_CTR | SAB_CW1_IV1 | SAB_CW1_IV2;
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p->IV_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer IV.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SAParams_p->OffsetIV = SAState_p->CurrentOffset;
+ SAParams_p->IVWord32Count = 2;
+
+ SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+ SAParams_p->IV_p, 8);
+ SAState_p->CurrentOffset += 2;
+ }
+ else
+ {
+ SAState_p->CW1 |= SAB_CW1_IV_CTR;
+ }
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+ {
+ /* Add 0 counter field (IV3) */
+ SAState_p->CW1 |= SAB_CW1_IV3;
+ if(SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] = 0;
+ SAState_p->CurrentOffset+=1;
+ }
+ }
+ else if (SAState_p->IVWords > 0)
+ { /* CBC mode, non-null */
+ if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT)
+ SAParams_p->IVSrc = SAB_IV_SRC_PRNG;
+ SAState_p->CW1 |= SAB_CW1_IV_FULL;
+ if (SAParams_p->IVSrc == SAB_IV_SRC_SA)
+ {
+ SAState_p->CW1 |= SAB_CW1_IV0 | SAB_CW1_IV1;
+ if(SAState_p->IVWords == 4)
+ SAState_p->CW1 |= SAB_CW1_IV2 | SAB_CW1_IV3;
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p->IV_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer IV.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SAParams_p->OffsetIV = SAState_p->CurrentOffset;
+ SAParams_p->IVWord32Count = SAState_p->IVWords;
+
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->IV_p,
+ SAState_p->IVWords * sizeof(uint32_t));
+ SAState_p->CurrentOffset += SAState_p->IVWords;
+ }
+ }
+ }
+ else
+ { /* Inbound */
+ unsigned int InputMaskWordCount =
+ SAParamsIPsec_p->SequenceMaskBitCount / 32;
+ unsigned int AllocMaskWordCount;
+
+ if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL &&
+ SAParams_p->AuthAlgo==SAB_AUTH_NULL)
+ SAState_p->CW0 |= SAB_CW0_TOP_NULL_IN;
+ else if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL)
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_IN;
+ else if (SAParams_p->AuthAlgo==SAB_AUTH_NULL)
+ SAState_p->CW0 |= SAB_CW0_TOP_DECRYPT;
+ else if (SAParams_p->AuthAlgo==SAB_AUTH_AES_CCM)
+ SAState_p->CW0 |= SAB_CW0_TOP_DECRYPT_HASH;
+ else
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_DECRYPT;
+
+ SAState_p->CW1 |= SAB_CW1_PAD_IPSEC;
+
+ /* Add sequence mask Always add one even with no anti-replay*/
+ SAParams_p->OffsetSeqMask = SAState_p->CurrentOffset;
+
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_APPEND_SEQNUM) != 0)
+ SAState_p->CW0 |= SAB_CW0_SEQNUM_APPEND;
+
+ /* Determine the required hardware mask size in words and set
+ control words accordingly. */
+ if (InputMaskWordCount == 1)
+ {
+ AllocMaskWordCount = 1;
+ SAState_p->CW0 |= SAB_CW0_MASK_32;
+ }
+ else if (InputMaskWordCount == 2)
+ {
+ AllocMaskWordCount = 2;
+ if (fFixedSeqOffset)
+ {
+ SAState_p->CW0 |= SAB_CW0_MASK_64_FIX;
+ }
+ else
+ {
+ SAState_p->CW0 |= SAB_CW0_MASK_64;
+ }
+ }
+ else if (InputMaskWordCount <= 4)
+ {
+ AllocMaskWordCount = 4;
+ if (fFixedSeqOffset)
+ {
+ SAState_p->CW0 |= SAB_CW0_MASK_128_FIX;
+ }
+ else
+ {
+ SAState_p->CW0 |= SAB_CW0_MASK_128;
+ }
+ }
+#ifdef SAB_ENABLE_256BIT_SEQMASK
+ else if (InputMaskWordCount <= 8)
+ {
+ AllocMaskWordCount = 8;
+ SAState_p->CW0 |= SAB_CW0_MASK_256_FIX;
+ }
+#endif
+ else if (InputMaskWordCount <= 12)
+ {
+ AllocMaskWordCount = 12;
+ SAState_p->CW0 |= SAB_CW0_MASK_384_FIX;
+ }
+ else
+ {
+ AllocMaskWordCount = 32;
+ SAState_p->CW0 |= SAB_CW0_MASK_1024_FIX;
+ SAState_p->fLargeMask = true;
+ SAState_p->fLarge = true;
+ }
+ if(SABuffer_p != NULL)
+ {
+ unsigned int i;
+ if (AllocMaskWordCount <= SA_SEQ_MASK_WORD_COUNT)
+ {
+ for (i = 0; i < InputMaskWordCount; i++)
+ SABuffer_p[SAState_p->CurrentOffset+i] =
+ SAParamsIPsec_p->SeqMask[i];
+ /* If the input mask is smaller than the one picked by the
+ hardware, fill the remaining words with all-one, the
+ hardware will treat these words as invalid.
+ */
+ for (i= InputMaskWordCount; i < AllocMaskWordCount; i++)
+ SABuffer_p[SAState_p->CurrentOffset+i] = 0xffffffff;
+ }
+ else
+ {
+ /* Mask too big to store in parameter structure.
+ Also need to shift the '1' bit to correct position */
+ uint32_t WordIdx, BitMask;
+ for (i= 0; i < AllocMaskWordCount; i++)
+ SABuffer_p[SAState_p->CurrentOffset+i] = 0;
+ WordIdx = (SAParamsIPsec_p->SeqNum & MASK_10_BITS) >> 5;
+ BitMask = 1 << (SAParamsIPsec_p->SeqNum & MASK_5_BITS);
+ SABuffer_p[SAState_p->CurrentOffset+WordIdx] = BitMask;
+ }
+ }
+ SAState_p->CurrentOffset += AllocMaskWordCount;
+ SAParams_p->SeqMaskWord32Count = InputMaskWordCount;
+
+ /* Add nonce for CTR and related modes */
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CTR ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GMAC ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CHACHA_CTR32)
+ {
+ if (IVOffset == 0)
+ IVOffset = SAState_p->CurrentOffset;
+
+ SAState_p->CW1 |= SAB_CW1_IV0;
+
+ /* For Poly/Chacha, we need to run in XOR IV mode with
+ delayed OTK in order to make the OTK derivation from the
+ extracted IV work */
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CHACHA_CTR32)
+ {
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_NONCE_XOR|
+ SAB_CW1_CRYPTO_MODE_CHACHA_POLY_OTK;
+ /* need all 3 IV double words - for IV=seqno these need to be
+ zeroized */
+ SAState_p->CW1 |= SAB_CW1_IV1|SAB_CW1_IV2;
+ if (SAParams_p->IVSrc == SAB_IV_SRC_IMPLICIT)
+ SAState_p->CW1 |= SAB_CW1_IV_CTR;
+ }
+ else if (SAParams_p->IVSrc == SAB_IV_SRC_IMPLICIT)
+ SAState_p->CW1 |= SAB_CW1_IV_ORIG_SEQ;
+
+ if (SABuffer_p != NULL)
+ {
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+ {
+ SABuffer_p[IVOffset] =
+ (SAParams_p->Nonce_p[0] << 8) |
+ (SAParams_p->Nonce_p[1] << 16) |
+ (SAParams_p->Nonce_p[2] << 24) | SAB_CCM_FLAG_L4;
+ }
+ else
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ IVOffset,
+ SAParams_p->Nonce_p,
+ sizeof(uint32_t));
+ }
+ IVOffset += 1;
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+ {
+ /* Add 0 counter field (IV3) */
+ SAState_p->CW1 |= SAB_CW1_IV3;
+ if(SABuffer_p != NULL)
+ SABuffer_p[IVOffset] = 0;
+ IVOffset += 1;
+ }
+ else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CHACHA_CTR32)
+ {
+ /* For ChaCha20 the IV1 and IV2 words are required to be 0 */
+ SABuilderLib_ZeroFill(SABuffer_p, IVOffset, 2*sizeof(uint32_t));
+ IVOffset +=2;
+ }
+ if (IVOffset > SAState_p->CurrentOffset)
+ {
+ SAState_p->CurrentOffset = IVOffset;
+ }
+ }
+ }
+ return SAB_STATUS_OK;
+}
+
+
+#endif /* SAB_ENABLE_PROTO_IPSEC */
+
+/* end of file sa_builder_ipsec.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_macsec.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_macsec.c
new file mode 100644
index 0000000..e6a7f99
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_macsec.c
@@ -0,0 +1,275 @@
+/* sa_builder_macsec.c
+ *
+ * MACsec specific functions (for initialization of SABuilder_Params_t
+ * structures and for building the MACsec specifc part of an SA.).
+ */
+
+/*****************************************************************************
+* Copyright (c) 2013-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "sa_builder_macsec.h"
+#include "sa_builder_internal.h" /* SABuilder_SetMACsecParams */
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#include "basic_defs.h"
+#include "log.h"
+
+#ifdef SAB_ENABLE_PROTO_MACSEC
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_MACsec
+ *
+ * This function initializes the SABuilder_Params_t data structure and its
+ * SABuilder_Params_MACsec_t extension with sensible defaults for MACsec
+ * processing.
+ *
+ * SAParams_p (output)
+ * Pointer to SA parameter structure to be filled in.
+ * SAParamsMACsec_p (output)
+ * Pointer to MACsec parameter extension to be filled in
+ * SCI_p (input)
+ * Pointer to Secure Channel Identifier, 8 bytes.
+ * AN (input)
+ * Association number, a number for 0 to 3.
+ * direction (input)
+ * Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Both the crypto and the authentication algorithm are initialized to
+ * NULL. The crypto algorithm (which may remain NULL) must be set to
+ * one of the algorithms supported by the protocol. The authentication
+ * algorithm must also be set to one of the algorithms supported by
+ * the protocol..Any required keys have to be specified as well.
+ *
+ * Both the SAParams_p and SAParamsMACsec_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsMACsec_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ * or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_MACsec(
+ SABuilder_Params_t * const SAParams_p,
+ SABuilder_Params_MACsec_t * const SAParamsMACsec_p,
+ const uint8_t *SCI_p,
+ const uint8_t AN,
+ const SABuilder_Direction_t direction)
+{
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p == NULL || SAParamsMACsec_p == NULL || SCI_p == NULL)
+ {
+ LOG_CRIT("SABuilder_Init_MACsec: NULL pointer parameter supplied.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if (AN > 3)
+ {
+ LOG_CRIT("SABuilder_Init_MACsec: Invalid Association Number.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if (direction != SAB_DIRECTION_OUTBOUND &&
+ direction != SAB_DIRECTION_INBOUND)
+ {
+ LOG_CRIT("SABuilder_Init_ESP: Invalid direction.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+
+ SAParams_p->protocol = SAB_PROTO_MACSEC;
+ SAParams_p->direction = direction;
+ SAParams_p->ProtocolExtension_p = (void*)SAParamsMACsec_p;
+ SAParams_p->flags = 0;
+ SAParams_p->RedirectInterface = 0;
+
+ SAParams_p->CryptoAlgo = SAB_CRYPTO_NULL;
+ SAParams_p->CryptoMode = SAB_CRYPTO_MODE_CBC;
+ SAParams_p->IVSrc = SAB_IV_SRC_DEFAULT;
+ SAParams_p->CryptoParameter = 0;
+ SAParams_p->KeyByteCount = 0;
+ SAParams_p->Key_p = NULL;
+ SAParams_p->IV_p = NULL;
+ SAParams_p->Nonce_p = NULL;
+
+ SAParams_p->AuthAlgo = SAB_AUTH_NULL;
+ SAParams_p->AuthKey1_p = NULL;
+ SAParams_p->AuthKey2_p = NULL;
+ SAParams_p->AuthKey3_p = NULL;
+ SAParams_p->AuthKeyByteCount = 0;
+
+ SAParams_p->OffsetARC4StateRecord = 0;
+ SAParams_p->CW0 = 0;
+ SAParams_p->CW1 = 0;
+ SAParams_p->OffsetDigest0 = 0;
+ SAParams_p->OffsetDigest1 = 0;
+ SAParams_p->OffsetSeqNum = 0;
+ SAParams_p->OffsetSeqMask = 0;
+ SAParams_p->OffsetIV = 0;
+ SAParams_p->OffsetIJPtr = 0;
+ SAParams_p->OffsetARC4State = 0;
+ SAParams_p->SeqNumWord32Count = 0;
+ SAParams_p->SeqMaskWord32Count = 0;
+ SAParams_p->IVWord32Count = 0;
+
+ SAParamsMACsec_p->MACsecFlags = 0;
+ SAParamsMACsec_p->SCI_p = SCI_p;
+ SAParamsMACsec_p->AN = AN;
+ SAParamsMACsec_p->SeqNum = 0;
+ SAParamsMACsec_p->ReplayWindow = 0;
+ SAParamsMACsec_p->ConfOffset = 0;
+ SAParamsMACsec_p->ContextRef = 0;
+
+ return SAB_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetMACsecParams
+ *
+ * Fill in MACsec-specific extensions into the SA.
+ *
+ * SAParams_p (input)
+ * The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ * Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ * The buffer in which the SA is built. If NULL, no SA will be built, but
+ * state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ * the buffer arguments is a null pointer while the corresponding buffer
+ * would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ * is not supported on the hardware for which this SA builder
+ * is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetMACsecParams(SABuilder_Params_t *const SAParams_p,
+ SABuilder_State_t * const SAState_p,
+ uint32_t * const SABuffer_p)
+{
+ SABuilder_Params_MACsec_t *SAParamsMACsec_p;
+ SAParamsMACsec_p = (SABuilder_Params_MACsec_t *)
+ (SAParams_p->ProtocolExtension_p);
+ if (SAParamsMACsec_p == NULL)
+ {
+ LOG_CRIT("SABuilder: MACsec extension pointer is null\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* Allow only AES-GMAC and AES-GCM */
+ if (SAParams_p->AuthAlgo != SAB_AUTH_AES_GCM &&
+ SAParams_p->AuthAlgo != SAB_AUTH_AES_GMAC)
+ {
+ LOG_CRIT("SABuilder: Only AES-GCM and GMAC allowed wtih MACsec\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if ( (SAParamsMACsec_p->MACsecFlags & SAB_MACSEC_ES) != 0 &&
+ (SAParamsMACsec_p->MACsecFlags & SAB_MACSEC_SC) != 0)
+ {
+ LOG_CRIT("SABuilder: MACSEC if ES is set, then SC must be zero,\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* Add sequence number */
+ SAState_p->CW0 |= SAB_CW0_SEQNUM_32;
+ SAParams_p->OffsetSeqNum = SAState_p->CurrentOffset;
+ SAParams_p->SeqNumWord32Count = 1;
+ SAState_p->CW1 |= SAB_CW1_SEQNUM_STORE;
+
+ if (SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] = SAParamsMACsec_p->SeqNum;
+ SAState_p->CurrentOffset += 1;
+
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM)
+ SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT_HASH;
+ else
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_ENCRYPT;
+ /* Some versions of the hardware can update the sequence number
+ early, so multiple engines can operate in parallel. */
+ SAState_p->CW1 |= SAB_CW1_EARLY_SEQNUM_UPDATE;
+ SAState_p->CW1 |= SAParams_p->OffsetSeqNum << 24;
+ }
+ else
+ {
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_DECRYPT;
+
+ /* Add 'sequence number mask' parameter, which is the replay
+ window size */
+ SAParams_p->OffsetSeqMask = SAState_p->CurrentOffset;
+ if(SABuffer_p != NULL)
+ {
+ SABuffer_p[SAState_p->CurrentOffset] =
+ SAParamsMACsec_p->ReplayWindow;
+ SABuffer_p[SAState_p->CurrentOffset+1] = 0; // Add dummy mask word.
+ }
+ SAParams_p->SeqMaskWord32Count = 1;
+ SAState_p->CurrentOffset += 2;
+ SAState_p->CW0 |= SAB_CW0_MASK_32;
+ SAState_p->CW1 |= SAB_CW1_MACSEC_SEQCHECK|SAB_CW1_NO_MASK_UPDATE;
+ }
+
+ /* Add SCI (IV0 and IV1) */
+ SAState_p->CW1 |= SAB_CW1_IV_CTR | SAB_CW1_IV0 | SAB_CW1_IV1 | SAB_CW1_IV2;
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParamsMACsec_p->SCI_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer SCI.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SAParams_p->OffsetIV = SAState_p->CurrentOffset;
+ SAParams_p->IVWord32Count = 2;
+
+ SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+ SAParamsMACsec_p->SCI_p, 8);
+ SAState_p->CurrentOffset += 2;
+
+ /* Add sequence number once more (IV2) */
+ if (SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] = SAParamsMACsec_p->SeqNum;
+ SAState_p->CurrentOffset += 1;
+
+ return SAB_STATUS_OK;
+}
+
+
+#endif /* SAB_ENABLE_PROTO_MACSEC */
+
+/* end of file sa_builder_macsec.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_srtp.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_srtp.c
new file mode 100644
index 0000000..a43e711
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_srtp.c
@@ -0,0 +1,228 @@
+/* sa_builder_srtp.c
+ *
+ * SRTP specific functions (for initialization of
+ * SABuilder_Params_t structures and for building the SRTP
+ * specifc part of an SA.).
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "sa_builder_srtp.h"
+#include "sa_builder_internal.h" /* SABuilder_SetSSLTLSParams */
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#include "basic_defs.h"
+#include "log.h"
+
+#ifdef SAB_ENABLE_PROTO_SRTP
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_SRTP
+ *
+ * This function initializes the SABuilder_Params_t data structure and
+ * its SABuilder_Params_SRTP_t extension with sensible defaults for
+ * SRTP processing..
+ *
+ * SAParams_p (output)
+ * Pointer to SA parameter structure to be filled in.
+ * SAParamsSRTP_p (output)
+ * Pointer to SRTP parameter extension to be filled in
+ * IsSRTCP (input)
+ * true if the SA is for SRTCP.
+ * direction (input)
+ * Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Tis function initializes the authentication algorithm to HMAC_SHA1.
+ * The application has to fill in the appropriate keys. The crypto algorithm
+ * is initialized to NULL. It can be changed to AES ICM and then a crypto
+ * key has to be added as well.
+ *
+ * Both the SAParams_p and SAParamsSRTP_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsSRTP_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ * or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_SRTP(
+ SABuilder_Params_t * const SAParams_p,
+ SABuilder_Params_SRTP_t * const SAParamsSRTP_p,
+ const bool IsSRTCP,
+ const SABuilder_Direction_t direction)
+{
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p == NULL || SAParamsSRTP_p == NULL)
+ {
+ LOG_CRIT("SABuilder_Init_SSLTLS: NULL pointer parameter supplied.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if (direction != SAB_DIRECTION_OUTBOUND &&
+ direction != SAB_DIRECTION_INBOUND)
+ {
+ LOG_CRIT("SABuilder_Init_ESP: Invalid direction.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+
+ SAParams_p->protocol = SAB_PROTO_SRTP;
+ SAParams_p->direction = direction;
+ SAParams_p->ProtocolExtension_p = (void*)SAParamsSRTP_p;
+ SAParams_p->flags = 0;
+ SAParams_p->RedirectInterface = 0;
+
+ SAParams_p->CryptoAlgo = SAB_CRYPTO_NULL;
+ SAParams_p->CryptoMode = SAB_CRYPTO_MODE_CBC;
+ SAParams_p->IVSrc = SAB_IV_SRC_DEFAULT;
+ SAParams_p->CryptoParameter = 0;
+ SAParams_p->KeyByteCount = 0;
+ SAParams_p->Key_p = NULL;
+ SAParams_p->IV_p = NULL;
+ SAParams_p->Nonce_p = NULL;
+
+ SAParams_p->AuthAlgo = SAB_AUTH_HMAC_SHA1;
+ SAParams_p->AuthKey1_p = NULL;
+ SAParams_p->AuthKey2_p = NULL;
+ SAParams_p->AuthKey3_p = NULL;
+ SAParams_p->AuthKeyByteCount = 0;
+
+ SAParams_p->OffsetARC4StateRecord = 0;
+ SAParams_p->CW0 = 0;
+ SAParams_p->CW1 = 0;
+ SAParams_p->OffsetDigest0 = 0;
+ SAParams_p->OffsetDigest1 = 0;
+ SAParams_p->OffsetSeqNum = 0;
+ SAParams_p->OffsetSeqMask = 0;
+ SAParams_p->OffsetIV = 0;
+ SAParams_p->OffsetIJPtr = 0;
+ SAParams_p->OffsetARC4State = 0;
+ SAParams_p->SeqNumWord32Count = 0;
+ SAParams_p->SeqMaskWord32Count = 0;
+ SAParams_p->IVWord32Count = 0;
+
+ SAParamsSRTP_p->SRTPFlags = 0;
+ if (IsSRTCP)
+ SAParamsSRTP_p->SRTPFlags |= SAB_SRTP_FLAG_SRTCP;
+ SAParamsSRTP_p->MKI = 0;
+ SAParamsSRTP_p->ICVByteCount = 10;
+
+ return SAB_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetSRTPParams
+ *
+ * Fill in SRTP-specific extensions into the SA.
+ *
+ * SAParams_p (input)
+ * The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ * Variables containing information about the SA being generated.
+ * SABuffer_p (input, output).
+ * The buffer in which the SA is built. If NULL, no SA will be built, but
+ * state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ * the buffer arguments is a null pointer while the corresponding buffer
+ * would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ * is not supported on the hardware for which this SA builder
+ * is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetSRTPParams(SABuilder_Params_t *const SAParams_p,
+ SABuilder_State_t * const SAState_p,
+ uint32_t * const SABuffer_p)
+{
+ SABuilder_Params_SRTP_t *SAParamsSRTP_p;
+ SAParamsSRTP_p = (SABuilder_Params_SRTP_t *)
+ (SAParams_p->ProtocolExtension_p);
+ if (SAParamsSRTP_p == NULL)
+ {
+ LOG_CRIT("SABuilder: SRTP extension pointer is null\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if (SAParams_p->CryptoAlgo == SAB_CRYPTO_AES)
+ {
+ SAState_p->CW1 &= ~0x7; // Clear crypto mode (CTR or ICM);
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_MODE_CTR_LOAD | SAB_CW1_IV_CTR;
+ }
+ else if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+ {
+ LOG_CRIT("SABuilder: I: crypto algorithm not supported\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if (SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA1)
+ {
+ LOG_CRIT("SABuilder: I: authentication algorithm not supported\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* Add MKI (as the SPI field) */
+ if ((SAParamsSRTP_p->SRTPFlags & SAB_SRTP_FLAG_INCLUDE_MKI) != 0)
+ {
+ SAState_p->CW0 |= SAB_CW0_SPI;
+ if (SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] = SAParamsSRTP_p->MKI;
+ SAState_p->CurrentOffset += 1;
+ }
+
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL)
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_OUT;
+ else
+ SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT_HASH;
+ }
+ else
+ {
+ if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL)
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_IN;
+ else
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_DECRYPT;
+ }
+
+ return SAB_STATUS_OK;
+}
+
+#endif /* SAB_ENABLE_PROTO_SRTP */
+
+
+/* end of file sa_builder_srtp.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_ssltls.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_ssltls.c
new file mode 100644
index 0000000..6a47ad0
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/sa/sa_builder_ssltls.c
@@ -0,0 +1,760 @@
+/* sa_builder_ssltls.c
+ *
+ * SSL/TLS/DTLS specific functions (for initialization of SABuilder_Params_t
+ * structures and for building the SSL/TLS/DTLS specifc part of an SA.).
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2021 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "sa_builder_ssltls.h"
+#include "sa_builder_internal.h" /* SABuilder_SetSSLTLSParams */
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_sa_builder.h"
+#include "basic_defs.h"
+#include "log.h"
+
+#ifdef SAB_ENABLE_PROTO_SSLTLS
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+#ifdef SAB_ENABLE_384BIT_SEQMASK
+#define SAB_SEQUENCE_MAXBITS 384
+#else
+#define SAB_SEQUENCE_MAXBITS 128
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+/*----------------------------------------------------------------------------
+ * SABuilder_Init_SSLTLS
+ *
+ * This function initializes the SABuilder_Params_t data structure and its
+ * SABuilder_Params_SSLTLS_t extension with sensible defaults for SSL, TLS
+ * and DTLS processing.
+ *
+ * SAParams_p (output)
+ * Pointer to SA parameter structure to be filled in.
+ * SAParamsSSLTLS_p (output)
+ * Pointer to SSLTLS parameter extension to be filled in
+ * version (input)
+ * Version code for the desired protcol (choose one of the SAB_*_VERSION_*
+ * constants from sa_builder_params_ssltls.h).
+ * direction (input)
+ * Must be one of SAB_DIRECTION_INBOUND or SAB_DIRECTION_OUTBOUND.
+ *
+ * Both the crypto and the authentication algorithm are initialized to
+ * NULL. The crypto algorithm (which may remain NULL) must be set to
+ * one of the algorithms supported by the protocol. The authentication
+ * algorithm must also be set to one of the algorithms supported by
+ * the protocol..Any required keys have to be specified as well.
+ *
+ * Both the SAParams_p and SAParamsSSLTLS_p input parameters must point
+ * to valid storage where variables of the appropriate type can be
+ * stored. This function initializes the link from SAParams_p to
+ * SAParamsSSSLTLS_p.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when one of the pointer parameters is NULL
+ * or the remaining parameters have illegal values.
+ */
+SABuilder_Status_t
+SABuilder_Init_SSLTLS(
+ SABuilder_Params_t * const SAParams_p,
+ SABuilder_Params_SSLTLS_t * const SAParamsSSLTLS_p,
+ const uint16_t version,
+ const SABuilder_Direction_t direction)
+{
+ int i;
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p == NULL || SAParamsSSLTLS_p == NULL)
+ {
+ LOG_CRIT("SABuilder_Init_SSLTLS: NULL pointer parameter supplied.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if (version != SAB_SSL_VERSION_3_0 &&
+ version != SAB_TLS_VERSION_1_0 &&
+ version != SAB_TLS_VERSION_1_1 &&
+ version != SAB_TLS_VERSION_1_2 &&
+ version != SAB_TLS_VERSION_1_3 &&
+ version != SAB_DTLS_VERSION_1_0 &&
+ version != SAB_DTLS_VERSION_1_2)
+ {
+ LOG_CRIT("SABuilder_Init_SSLTLS: Invalid protocol version.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ if (direction != SAB_DIRECTION_OUTBOUND &&
+ direction != SAB_DIRECTION_INBOUND)
+ {
+ LOG_CRIT("SABuilder_Init_ESP: Invalid direction.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+
+ SAParams_p->protocol = SAB_PROTO_SSLTLS;
+ SAParams_p->direction = direction;
+ SAParams_p->ProtocolExtension_p = (void*)SAParamsSSLTLS_p;
+ SAParams_p->flags = 0;
+ SAParams_p->RedirectInterface = 0;
+
+ SAParams_p->CryptoAlgo = SAB_CRYPTO_NULL;
+ SAParams_p->CryptoMode = SAB_CRYPTO_MODE_CBC;
+ SAParams_p->IVSrc = SAB_IV_SRC_DEFAULT;
+ SAParams_p->CryptoParameter = 0;
+ SAParams_p->KeyByteCount = 0;
+ SAParams_p->Key_p = NULL;
+ SAParams_p->IV_p = NULL;
+ SAParams_p->Nonce_p = NULL;
+
+ SAParams_p->AuthAlgo = SAB_AUTH_NULL;
+ SAParams_p->AuthKey1_p = NULL;
+ SAParams_p->AuthKey2_p = NULL;
+ SAParams_p->AuthKey3_p = NULL;
+ SAParams_p->AuthKeyByteCount = 0;
+
+ SAParams_p->OffsetARC4StateRecord = 0;
+ SAParams_p->CW0 = 0;
+ SAParams_p->CW1 = 0;
+ SAParams_p->OffsetDigest0 = 0;
+ SAParams_p->OffsetDigest1 = 0;
+ SAParams_p->OffsetSeqNum = 0;
+ SAParams_p->OffsetSeqMask = 0;
+ SAParams_p->OffsetIV = 0;
+ SAParams_p->OffsetIJPtr = 0;
+ SAParams_p->OffsetARC4State = 0;
+ SAParams_p->SeqNumWord32Count = 0;
+ SAParams_p->SeqMaskWord32Count = 0;
+ SAParams_p->IVWord32Count = 0;
+
+ SAParamsSSLTLS_p->SSLTLSFlags = 0;
+ SAParamsSSLTLS_p->version = version;
+ SAParamsSSLTLS_p->epoch = 0;
+ SAParamsSSLTLS_p->SeqNum = 0;
+ SAParamsSSLTLS_p->SeqNumHi = 0;
+ for (i=0; i<12; i++)
+ SAParamsSSLTLS_p->SeqMask[i] = 0;
+ SAParamsSSLTLS_p->PadAlignment = 0;
+ SAParamsSSLTLS_p->ContextRef = 0;
+ SAParamsSSLTLS_p->SequenceMaskBitCount = 0;
+ SAParamsSSLTLS_p->ICVByteCount = 0;
+ return SAB_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * SABuilder_SetSSLTLSParams
+ *
+ * Fill in SSL/TLS/DTLS-specific extensions into the SA.
+ *
+ * SAParams_p (input)
+ * The SA parameters structure from which the SA is derived.
+ * SAState_p (input, output)
+ * Variables containing information about the SA being generated/
+ * SABuffer_p (input, output).
+ * The buffer in which the SA is built. If NULL, no SA will be built, but
+ * state variables in SAState_p will still be updated.
+ *
+ * Return:
+ * SAB_STATUS_OK on success
+ * SAB_INVALID_PARAMETER when SAParams_p is invalid, or if any of
+ * the buffer arguments is a null pointer while the corresponding buffer
+ * would be required for the operation.
+ * SAB_UNSUPPORTED_FEATURE when SAParams_p describes an operations that
+ * is not supported on the hardware for which this SA builder
+ * is configured.
+ */
+SABuilder_Status_t
+SABuilder_SetSSLTLSParams(SABuilder_Params_t *const SAParams_p,
+ SABuilder_State_t * const SAState_p,
+ uint32_t * const SABuffer_p)
+{
+ unsigned int IVOffset = 0;
+ SABuilder_Params_SSLTLS_t *SAParamsSSLTLS_p;
+ bool fFixedSeqOffset = false;
+ SAParamsSSLTLS_p = (SABuilder_Params_SSLTLS_t *)
+ (SAParams_p->ProtocolExtension_p);
+ if (SAParamsSSLTLS_p == NULL)
+ {
+ LOG_CRIT("SABuilder: SSLTLS extension pointer is null\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* Prohibit ARC4 in DTLS and TLS1.3 */
+ if (SAParams_p->CryptoAlgo == SAB_CRYPTO_ARCFOUR &&
+ (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3||
+ SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_0||
+ SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_2))
+ {
+ LOG_CRIT("SABuilder: ARC4 not allowed with DTLS/TLS1.3\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* Prohibit CBC mode or NULL crypto in TLS1.3 */
+ if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3 &&
+ (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CBC ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_NULL))
+ {
+ LOG_CRIT("SABuilder: CBC or nullcrypto not allowed with TLS1.3\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* AES GCM/CCM/Chacha20 is only allowed with TLS1.2/TLS1.3/DTLS1.2 */
+ if ((SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20 ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM) &&
+ SAParamsSSLTLS_p->version != SAB_TLS_VERSION_1_2 &&
+ SAParamsSSLTLS_p->version != SAB_TLS_VERSION_1_3 &&
+ SAParamsSSLTLS_p->version != SAB_DTLS_VERSION_1_2)
+ {
+ LOG_CRIT("SABuilder: AES-GCM/CCM/ChaCha20 only allowed with TLS/DTLS 1.2 and 1.3\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* Prohibit stateless ARC4*/
+ if (SAParams_p->CryptoAlgo == SAB_CRYPTO_ARCFOUR &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_STATEFUL)
+ {
+ LOG_CRIT("SABuilder: ARC4 must be stateful\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* Check for supported algorithms and crypto modes in SSL/TLS */
+ if ((SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_ARCFOUR &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_DES &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_3DES &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_AES &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_CHACHA20 &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_SM4 &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_BC0) ||
+ (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_STATEFUL &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CBC &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GCM &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CCM &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CHACHA_CTR32))
+ {
+ LOG_CRIT("SABuilder: SSLTLS crypto algorithm/mode not supported\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* Check for supported authentication algorithms in SSL/TLS */
+ if (SAParams_p->AuthAlgo != SAB_AUTH_HMAC_MD5 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_SSLMAC_MD5 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA1 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_SSLMAC_SHA1 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA2_256 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA2_384 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SHA2_512 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_AES_GCM &&
+ SAParams_p->AuthAlgo != SAB_AUTH_AES_CCM &&
+ SAParams_p->AuthAlgo != SAB_AUTH_POLY1305 &&
+ SAParams_p->AuthAlgo != SAB_AUTH_HMAC_SM3)
+ {
+ LOG_CRIT("SABuilder: SSLTLS: auth algorithm not supported\n");
+ return SAB_INVALID_PARAMETER;
+ }
+
+ /* Add version to SA record */
+ if (SABuffer_p != NULL)
+ {
+ if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+ {
+ SABuffer_p[SAState_p->CurrentOffset] = SAB_TLS_VERSION_1_2<<16;
+ /* fixed type & version to be put in record for TLS1.3 */
+ }
+ else
+ {
+ SABuffer_p[SAState_p->CurrentOffset] = SAParamsSSLTLS_p->version<<16;
+ }
+ }
+ SAState_p->CurrentOffset += 1;
+
+ /* Determine whether we will have a fixed sequence number offset */
+ if (SAParams_p->direction == SAB_DIRECTION_INBOUND &&
+ (SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_0||
+ SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_2))
+ {
+ /* Determine size of sequence number mask in bits */
+ if (SAParamsSSLTLS_p->SequenceMaskBitCount == 0)
+ {
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_MASK_128) != 0)
+ {
+ SAParamsSSLTLS_p->SequenceMaskBitCount = 128;
+ }
+ else if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_MASK_32) != 0)
+ {
+ SAParamsSSLTLS_p->SequenceMaskBitCount = 32;
+ }
+ else
+ {
+ SAParamsSSLTLS_p->SequenceMaskBitCount = 64;
+ }
+ }
+ if (SAParamsSSLTLS_p->SequenceMaskBitCount > SAB_SEQUENCE_MAXBITS ||
+ (SAParamsSSLTLS_p->SequenceMaskBitCount & 0x1f) != 0)
+ {
+ LOG_CRIT("SABuilder: Illegal sequence mask size.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#ifdef SAB_ENABLE_DEFAULT_FIXED_OFFSETS
+ fFixedSeqOffset = true;
+#else
+ if (SAParamsSSLTLS_p->SequenceMaskBitCount > 128 ||
+ (SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_FIXED_SEQ_OFFSET) != 0)
+ {
+ fFixedSeqOffset = true;
+ }
+#endif
+ if (SAParamsSSLTLS_p->SequenceMaskBitCount == 32)
+ {
+ fFixedSeqOffset = false; /* not supported for 32-bit mask */
+ }
+ }
+
+
+ if (fFixedSeqOffset)
+ {
+ /* Use a fixed sequence number offset for inbound if the hardware
+ supports it. */
+ /* Take care to insert the IV (nonce) just after the SPI. */
+ IVOffset = SAState_p->CurrentOffset;
+
+ /* Select one of two fixed offsets for the sequence number */
+ if (SAState_p->CurrentOffset < SAB_SEQNUM_LO_FIX_OFFSET)
+ {
+ SAState_p->CurrentOffset = SAB_SEQNUM_LO_FIX_OFFSET;
+ }
+ else
+ {
+ SAState_p->CurrentOffset = SAB_SEQNUM_HI_FIX_OFFSET;
+ }
+
+ /* Add sequence number */
+ SAParams_p->OffsetSeqNum = SAState_p->CurrentOffset;
+ SAParams_p->SeqNumWord32Count = 2;
+ SAState_p->CW1 |= SAB_CW1_SEQNUM_STORE;
+ SAState_p->CW0 |= SAB_CW0_SPI | SAB_CW0_SEQNUM_48_FIX;
+ if (SABuffer_p != NULL)
+ {
+ SABuffer_p[SAState_p->CurrentOffset] = SAParamsSSLTLS_p->SeqNum;
+ SABuffer_p[SAState_p->CurrentOffset + 1] =
+ (SAParamsSSLTLS_p->SeqNumHi & 0xffff) |
+ (SAParamsSSLTLS_p->epoch << 16);
+ }
+ SAState_p->CurrentOffset += 2;
+ }
+ else
+ {
+ /* Add sequence number */
+ SAParams_p->OffsetSeqNum = SAState_p->CurrentOffset;
+ SAParams_p->SeqNumWord32Count = 2;
+ SAState_p->CW1 |= SAB_CW1_SEQNUM_STORE;
+
+ if (SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] = SAParamsSSLTLS_p->SeqNum;
+ SAState_p->CurrentOffset += 1;
+ if (SAParamsSSLTLS_p->version != SAB_DTLS_VERSION_1_0 &&
+ SAParamsSSLTLS_p->version != SAB_DTLS_VERSION_1_2)
+ {
+ SAState_p->CW0 |= SAB_CW0_SPI | SAB_CW0_SEQNUM_64;
+ if (SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] =
+ SAParamsSSLTLS_p->SeqNumHi;
+ }
+ else
+ {
+ SAState_p->CW0 |= SAB_CW0_SPI | SAB_CW0_SEQNUM_48;
+ if (SABuffer_p != NULL)
+ SABuffer_p[SAState_p->CurrentOffset] =
+ (SAParamsSSLTLS_p->SeqNumHi & 0xffff) |
+ (SAParamsSSLTLS_p->epoch << 16);
+ }
+ SAState_p->CurrentOffset += 1;
+ }
+
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+
+ if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL)
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_OUT;
+ else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+ SAState_p->CW0 |= SAB_CW0_TOP_ENCRYPT_HASH;
+ else
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_ENCRYPT;
+
+ /* Some versions of the hardware can update the sequence number
+ early, so multiple engines can operate in parallel. */
+ SAState_p->CW1 |= SAB_CW1_EARLY_SEQNUM_UPDATE;
+ SAState_p->CW1 |= SAParams_p->OffsetSeqNum << 24;
+
+ /* Take care of IV */
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+ {
+ if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+ {
+ SAState_p->CW1 = (SAState_p->CW1 & ~SAB_CW1_IV_MODE_MASK) |
+ SAB_CW1_IV_ORIG_SEQ|SAB_CW1_CRYPTO_NONCE_XOR;
+ SAState_p->CW1 |= SAB_CW1_IV0|SAB_CW1_IV1|SAB_CW1_IV2|
+ SAB_CW1_IV3 | SAB_CW1_CCM_IV_SHIFT;
+ if (SABuffer_p != NULL)
+ {
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->Nonce_p,
+ 3 * sizeof(uint32_t));
+ SABuffer_p[SAState_p->CurrentOffset + 3] =
+ SAB_CCM_FLAG_L3 << 24;
+ }
+ SAState_p->CurrentOffset += 4;
+ }
+ else
+ {
+ SAState_p->CW1 = (SAState_p->CW1 & ~SAB_CW1_IV_MODE_MASK) |
+ SAB_CW1_IV_ORIG_SEQ;
+ SAState_p->CW1 |= SAB_CW1_IV0|SAB_CW1_IV3 | SAB_CW1_CCM_IV_SHIFT;
+ if (SABuffer_p != NULL)
+ {
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->Nonce_p,
+ sizeof(uint32_t));
+ SABuffer_p[SAState_p->CurrentOffset + 1] =
+ SAB_CCM_FLAG_L3 << 24;
+ }
+ SAState_p->CurrentOffset += 2;
+ }
+ }
+ else if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3 ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+ {
+ SAState_p->CW1 = (SAState_p->CW1 & ~SAB_CW1_IV_MODE_MASK) |
+ SAB_CW1_IV_ORIG_SEQ|SAB_CW1_CRYPTO_NONCE_XOR;
+ SAState_p->CW1 |= SAB_CW1_IV0|SAB_CW1_IV1|SAB_CW1_IV2;
+ /* Always store the nonce (implicit salt) with TLS1.3 */
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->Nonce_p, 3*sizeof(uint32_t));
+ SAState_p->CurrentOffset +=3;
+ }
+ else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM)
+ {
+ if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT)
+ SAParams_p->IVSrc = SAB_IV_SRC_SEQ;
+
+ if (SAParams_p->IVSrc == SAB_IV_SRC_SEQ)
+ {
+ SAState_p->CW1 |= SAB_CW1_IV_ORIG_SEQ;
+ }
+ else if (SAParams_p->IVSrc == SAB_IV_SRC_XORSEQ)
+ {
+ SAState_p->CW1 |= SAB_CW1_IV_CTR|SAB_CW1_CRYPTO_NONCE_XOR;
+ SAState_p->CW1 |= SAB_CW1_IV0|SAB_CW1_IV1|SAB_CW1_IV2;
+ }
+ else if (SAParams_p->IVSrc == SAB_IV_SRC_SA)
+ {
+ SAState_p->CW1 |= SAB_CW1_IV_CTR | SAB_CW1_IV1 | SAB_CW1_IV2;
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p->IV_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer IV.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SAParams_p->OffsetIV = SAState_p->CurrentOffset;
+ SAParams_p->IVWord32Count = 2;
+
+ SABuilderLib_CopyKeyMat(SABuffer_p, SAState_p->CurrentOffset,
+ SAParams_p->IV_p, 8);
+ SAState_p->CurrentOffset += 2;
+ }
+ else
+ {
+ SAState_p->CW1 |= SAB_CW1_IV_CTR;
+ }
+ SAState_p->CW1 |= SAB_CW1_IV0;
+ /* Always store the nonce (implicit salt) with AES-GCM */
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->Nonce_p,
+ sizeof(uint32_t));
+ SAState_p->CurrentOffset +=1;
+ if (SAParams_p->IVSrc == SAB_IV_SRC_XORSEQ)
+ {
+ /* Store a fixed 8-byte value to XOR with sequence number */
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->IV_p,
+ 2*sizeof(uint32_t));
+ SAState_p->CurrentOffset +=2;
+ }
+ }
+ else if (SAState_p->IVWords > 0)
+ { /* CBC mode, non-null */
+ if (SAParamsSSLTLS_p->version == SAB_SSL_VERSION_3_0 ||
+ SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_0)
+ {
+ SAParams_p->IVSrc = SAB_IV_SRC_SA;
+ SAState_p->CW1 |= SAB_CW1_CRYPTO_STORE;
+ }
+ else if (SAParams_p->IVSrc == SAB_IV_SRC_DEFAULT)
+ {
+ SAParams_p->IVSrc = SAB_IV_SRC_PRNG;
+ }
+ SAState_p->CW1 |= SAB_CW1_IV_FULL;
+ if (SAParams_p->IVSrc == SAB_IV_SRC_SA)
+ {
+ SAState_p->CW1 |= SAB_CW1_IV0 | SAB_CW1_IV1;
+ if(SAState_p->IVWords == 4)
+ SAState_p->CW1 |= SAB_CW1_IV2 | SAB_CW1_IV3;
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p->IV_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer IV.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SAParams_p->OffsetIV = SAState_p->CurrentOffset;
+ SAParams_p->IVWord32Count = SAState_p->IVWords;
+
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->IV_p,
+ SAState_p->IVWords * sizeof(uint32_t));
+ SAState_p->CurrentOffset += SAState_p->IVWords;
+ }
+ }
+ }
+ else
+ { /* Inbound */
+ if (SAParams_p->CryptoAlgo==SAB_CRYPTO_NULL)
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_IN;
+ else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+ SAState_p->CW0 |= SAB_CW0_TOP_HASH_DECRYPT;
+ else
+ SAState_p->CW0 |= SAB_CW0_TOP_DECRYPT_HASH;
+
+ if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_GCM &&
+ SAParams_p->CryptoMode != SAB_CRYPTO_MODE_CCM &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_CHACHA20 &&
+ SAState_p->IVWords > 0)
+ {
+ SAState_p->CW1 |= SAB_CW1_PREPKT_OP;
+ if (SAParamsSSLTLS_p->version == SAB_SSL_VERSION_3_0)
+ {
+ SAState_p->CW1 |= SAB_CW1_PAD_SSL;
+ }
+ else
+ {
+ SAState_p->CW1 |= SAB_CW1_PAD_TLS;
+ }
+ }
+ if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+ {
+ SAState_p->CW1 |= SAB_CW1_PAD_TLS | SAB_CW1_CRYPTO_AEAD;
+ }
+
+ /* Add sequence mask for DTLS only. */
+ if ((SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_0 ||
+ SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_2))
+ {
+ unsigned int InputMaskWordCount =
+ SAParamsSSLTLS_p->SequenceMaskBitCount / 32;
+ unsigned int AllocMaskWordCount;
+ SAParams_p->OffsetSeqMask = SAState_p->CurrentOffset;
+ /* Determine the required hardware mask size in words and set
+ control words accordingly. */
+ if (InputMaskWordCount == 1)
+ {
+ AllocMaskWordCount = 1;
+ SAState_p->CW0 |= SAB_CW0_MASK_32;
+ }
+ else if (InputMaskWordCount == 2)
+ {
+ AllocMaskWordCount = 2;
+ if (fFixedSeqOffset)
+ {
+ SAState_p->CW0 |= SAB_CW0_MASK_64_FIX;
+ }
+ else
+ {
+ SAState_p->CW0 |= SAB_CW0_MASK_64;
+ }
+ }
+ else if (InputMaskWordCount <= 4)
+ {
+ AllocMaskWordCount = 4;
+ if (fFixedSeqOffset)
+ {
+ SAState_p->CW0 |= SAB_CW0_MASK_128_FIX;
+ }
+ else
+ {
+ SAState_p->CW0 |= SAB_CW0_MASK_128;
+ }
+ }
+#ifdef SAB_ENABLE_256BIT_SEQMASK
+ else if (InputMaskWordCount <= 8)
+ {
+ AllocMaskWordCount = 8;
+ SAState_p->CW0 |= SAB_CW0_MASK_256_FIX;
+ }
+#endif
+ else
+ {
+ AllocMaskWordCount = 12;
+ SAState_p->CW0 |= SAB_CW0_MASK_384_FIX;
+ }
+ if(SABuffer_p != NULL)
+ {
+ unsigned int i;
+ for (i = 0; i < InputMaskWordCount; i++)
+ SABuffer_p[SAState_p->CurrentOffset+i] =
+ SAParamsSSLTLS_p->SeqMask[i];
+ /* If the input mask is smaller than the one picked by the
+ hardware, fill the remaining words with all-one, the
+ hardware will treat these words as invalid.
+ */
+ for (i= InputMaskWordCount; i < AllocMaskWordCount; i++)
+ SABuffer_p[SAState_p->CurrentOffset+i] = 0xffffffff;
+ }
+ SAState_p->CurrentOffset += AllocMaskWordCount;
+ SAParams_p->SeqMaskWord32Count = InputMaskWordCount;
+ }
+
+ if (IVOffset == 0)
+ IVOffset = SAState_p->CurrentOffset;
+ if (SAState_p->IVWords > 0 &&
+ (SAParamsSSLTLS_p->version == SAB_SSL_VERSION_3_0 ||
+ SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_0))
+ {
+ SAParams_p->IVSrc = SAB_IV_SRC_SA;
+ SAState_p->CW1 |= SAB_CW1_IV_FULL;
+
+ SAState_p->CW1 |= SAB_CW1_IV0 | SAB_CW1_IV1 |
+ SAB_CW1_CRYPTO_STORE;
+ if(SAState_p->IVWords == 4)
+ SAState_p->CW1 |= SAB_CW1_IV2 | SAB_CW1_IV3;
+#ifdef SAB_STRICT_ARGS_CHECK
+ if (SAParams_p->IV_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer IV.\n");
+ return SAB_INVALID_PARAMETER;
+ }
+#endif
+ SAParams_p->OffsetIV = IVOffset;
+ SAParams_p->IVWord32Count = SAState_p->IVWords;
+
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ IVOffset,
+ SAParams_p->IV_p,
+ SAState_p->IVWords * sizeof(uint32_t));
+ IVOffset += SAState_p->IVWords;
+ }
+
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+ {
+ if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+ {
+ SAState_p->CW1 = (SAState_p->CW1 & ~SAB_CW1_IV_MODE_MASK) |
+ SAB_CW1_IV_ORIG_SEQ|SAB_CW1_CRYPTO_NONCE_XOR;
+ SAState_p->CW1 |= SAB_CW1_IV0|SAB_CW1_IV1|SAB_CW1_IV2|
+ SAB_CW1_IV3 | SAB_CW1_CCM_IV_SHIFT;
+ if (SABuffer_p != NULL)
+ {
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->Nonce_p,
+ 3 * sizeof(uint32_t));
+ SABuffer_p[SAState_p->CurrentOffset + 3] =
+ SAB_CCM_FLAG_L3 << 24;
+ }
+ SAState_p->CurrentOffset += 4;
+ }
+ else
+ {
+ SAState_p->CW1 = (SAState_p->CW1 & ~SAB_CW1_IV_MODE_MASK);
+ SAState_p->CW1 |= SAB_CW1_IV0| SAB_CW1_IV3 | SAB_CW1_CCM_IV_SHIFT;
+ if (SABuffer_p != NULL)
+ {
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ SAState_p->CurrentOffset,
+ SAParams_p->Nonce_p,
+ sizeof(uint32_t));
+ SABuffer_p[SAState_p->CurrentOffset + 1] =
+ SAB_CCM_FLAG_L3 << 24;
+ }
+ SAState_p->CurrentOffset += 2;
+ }
+ }
+ else if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3 ||
+ SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+ {
+
+ if (SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_2)
+ {
+ /* DTLS inbound extracts the sequence number from the packet, use delayed OTK mode */
+ SAState_p->CW1 |= SAB_CW1_IV_CTR|SAB_CW1_CRYPTO_NONCE_XOR;
+ } else {
+ /* regular TLS inbound internally increments the sequence number, so can save some cycles by starting OTK calc early */
+ SAState_p->CW1 = (SAState_p->CW1 & ~SAB_CW1_IV_MODE_MASK) |
+ SAB_CW1_IV_ORIG_SEQ|SAB_CW1_CRYPTO_NONCE_XOR;
+ }
+ SAState_p->CW1 |= SAB_CW1_IV0|SAB_CW1_IV1|SAB_CW1_IV2;
+ /* Always store the nonce (implicit salt) with TLS1.3 */
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ IVOffset,
+ SAParams_p->Nonce_p, 3*sizeof(uint32_t));
+ IVOffset +=3;
+ }
+ else if(SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM)
+ {
+ SAState_p->CW1 |= SAB_CW1_IV_CTR|SAB_CW1_IV0;
+ /* Always store the nonce (implicit salt) with AES-GCM */
+ SABuilderLib_CopyKeyMat(SABuffer_p,
+ IVOffset,
+ SAParams_p->Nonce_p, sizeof(uint32_t));
+ IVOffset +=1;
+ }
+ if (IVOffset > SAState_p->CurrentOffset)
+ {
+ SAState_p->CurrentOffset = IVOffset;
+ }
+
+ }
+
+ return SAB_STATUS_OK;
+}
+
+
+#endif /* SAB_ENABLE_PROTO_SSLTLS */
+
+/* end of file sa_builder_ssltls.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/token/token_builder_context.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/token/token_builder_context.c
new file mode 100644
index 0000000..16b039e
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/token/token_builder_context.c
@@ -0,0 +1,1696 @@
+/* token_builder_context.c
+ *
+ * This is the main implementation module for the EIP-96 Token Builder.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+#include "token_builder.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+#include "c_token_builder.h"
+#include "basic_defs.h"
+#include "clib.h"
+#include "log.h"
+#include "sa_builder_params.h"
+#include "sa_builder_params_ipsec.h"
+
+#include "token_builder_internal.h"
+#include "sa_builder_params.h"
+#ifdef TKB_ENABLE_PROTO_IPSEC
+#include "sa_builder_params_ipsec.h"
+#endif
+#ifdef TKB_ENABLE_PROTO_SSLTLS
+#include "sa_builder_params_ssltls.h"
+#endif
+#ifdef TKB_ENABLE_PROTO_BASIC
+#include "sa_builder_params_basic.h"
+#endif
+#ifdef TKB_ENABLE_PROTO_SRTP
+#include "sa_builder_params_srtp.h"
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+
+/*----------------------------------------------------------------------------
+ * TokenBuilder_GetContextSize
+ *
+ * Determine the size of the token context record in 32-bit words, which may
+ * depend on the SA parameters.
+ *
+ * SAParams_p (input)
+ * Points to the SA parameters data structure
+ * TokenContextWord32Count_p (output)
+ * Required size of the Token Context Record in 32-bit words.
+ *
+ * Note: This implementation has one Token Context Record format with a fixed
+ * size. Therefore this function does not look at the SA parameters.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ * the contents of the input data structures are invalid.
+ */
+TokenBuilder_Status_t
+TokenBuilder_GetContextSize(
+ const SABuilder_Params_t * const SAParams_p,
+ unsigned int * const TokenContextWord32Count_p
+ )
+{
+#ifdef TKB_STRICT_ARGS_CHECK
+ if (SAParams_p == NULL || TokenContextWord32Count_p == NULL)
+ {
+ LOG_CRIT("TokenBuilder_GetContextSize: NULL pointer supplied\n");
+ return TKB_INVALID_PARAMETER;
+ }
+#endif
+ *TokenContextWord32Count_p =
+ ((unsigned int)sizeof(TokenBuilder_Context_t) + sizeof(uint32_t) - 1) /
+ sizeof(uint32_t);
+ return TKB_STATUS_OK;
+}
+
+
+#ifdef TKB_ENABLE_PROTO_IPSEC
+#ifdef TKB_ENABLE_EXTENDED_IPSEC
+/*----------------------------------------------------------------------------
+ * TokenBuilder_BuildContext_IPsec
+ *
+ * Fill in the context fields for extended IPsec operations.
+ *
+ * SAParams_p (input)
+ * Points to the SA parameters data structure. It is important that
+ * SABuilder_GetSIze() and SABuilder_BuildSA() have already been called
+ * for this SA.
+ * TokenContext_Internal_p (output)
+ * Buffer to hold the Token Context Record.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ * the contents of the SA parameters are invalid.
+ */
+static TokenBuilder_Status_t
+TokenBuilder_BuildContext_Extended(
+ const SABuilder_Params_t * const SAParams_p,
+ TokenBuilder_Context_t * const TokenContext_Internal_p)
+{
+ uint8_t HeaderProto;
+ SABuilder_Params_IPsec_t *SAParamsIPsec_p;
+ SAParamsIPsec_p = (SABuilder_Params_IPsec_t *)
+ (SAParams_p->ProtocolExtension_p);
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV6) !=0)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+ {
+ HeaderProto = TKB_HDR_IPV6_OUT_TUNNEL;
+ }
+ else
+ {
+ HeaderProto = TKB_HDR_IPV6_OUT_TRANSP;
+ }
+ }
+ else
+ {
+ HeaderProto = TKB_HDR_IPV6_OUT_TRANSP_HDRBYPASS;
+ }
+ }
+ else
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+ {
+ HeaderProto = TKB_HDR_IPV4_OUT_TUNNEL;
+ }
+ else
+ {
+ HeaderProto = TKB_HDR_IPV4_OUT_TRANSP;
+ }
+ }
+ else
+ {
+ HeaderProto = TKB_HDR_IPV4_OUT_TRANSP_HDRBYPASS;
+ }
+ }
+
+ }
+ else
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV6) !=0)
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+ {
+ TokenContext_Internal_p->TokenHeaderWord |= TKB_HEADER_UPD_HDR;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+ {
+ HeaderProto = TKB_HDR_IPV6_IN_TUNNEL;
+ }
+ else
+ {
+ HeaderProto = TKB_HDR_IPV6_IN_TRANSP;
+ }
+ }
+ else
+ {
+ HeaderProto = TKB_HDR_IPV6_IN_TRANSP_HDRBYPASS;
+ }
+ }
+ else
+ {
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_PROCESS_IP_HEADERS) !=0)
+ {
+ TokenContext_Internal_p->TokenHeaderWord |= TKB_HEADER_UPD_HDR;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TUNNEL) !=0)
+ {
+ HeaderProto = TKB_HDR_IPV4_IN_TUNNEL;
+ }
+ else
+ {
+ HeaderProto = TKB_HDR_IPV4_IN_TRANSP;
+ }
+ }
+ else
+ {
+ HeaderProto = TKB_HDR_IPV4_IN_TRANSP_HDRBYPASS;
+ }
+ }
+
+ }
+ /* If NAT-T selected, select other header protocol range */
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_NATT) != 0)
+ HeaderProto += (TKB_HDR_IPV4_OUT_TRANSP_HDRBYPASS_NATT -
+ TKB_HDR_IPV4_OUT_TRANSP_HDRBYPASS);
+
+ TokenContext_Internal_p->hproto = HeaderProto;
+
+ TokenContext_Internal_p->u.generic.TTL = SAParamsIPsec_p->TTL;
+ TokenContext_Internal_p->u.generic.DSCP = SAParamsIPsec_p->DSCP;
+ TokenContext_Internal_p->NATT_Ports =
+ (SAParamsIPsec_p->NATTSrcPort >> 8) |
+ ((SAParamsIPsec_p->NATTSrcPort & 0xff) << 8) |
+ ((SAParamsIPsec_p->NATTDestPort & 0xff00) << 8) |
+ ((SAParamsIPsec_p->NATTDestPort & 0xff) << 24 );
+
+ TokenContext_Internal_p->u.generic.ESPFlags = 0;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_CLEAR_DF) != 0)
+ TokenContext_Internal_p->u.generic.ESPFlags |= TKB_ESP_FLAG_CLEAR_DF;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_SET_DF) != 0)
+ TokenContext_Internal_p->u.generic.ESPFlags |= TKB_ESP_FLAG_SET_DF;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_REPLACE_DSCP) != 0)
+ TokenContext_Internal_p->u.generic.ESPFlags |= TKB_ESP_FLAG_REPLACE_DSCP;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_CLEAR_ECN) != 0)
+ TokenContext_Internal_p->u.generic.ESPFlags |= TKB_ESP_FLAG_CLEAR_ECN;
+
+ if (HeaderProto == TKB_HDR_IPV4_OUT_TUNNEL ||
+ HeaderProto == TKB_HDR_IPV6_OUT_TUNNEL ||
+ HeaderProto == TKB_HDR_IPV4_OUT_TUNNEL_NATT ||
+ HeaderProto == TKB_HDR_IPV6_OUT_TUNNEL_NATT)
+ {
+ if (SAParamsIPsec_p->SrcIPAddr_p == NULL ||
+ SAParamsIPsec_p->DestIPAddr_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer tunnel address.\n");
+ return TKB_INVALID_PARAMETER;
+ }
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_IPV4) != 0)
+ {
+ memcpy(TokenContext_Internal_p->TunnelIP,
+ SAParamsIPsec_p->SrcIPAddr_p,
+ 4);
+ memcpy(TokenContext_Internal_p->TunnelIP + 4,
+ SAParamsIPsec_p->DestIPAddr_p,
+ 4);
+ }
+ else
+ {
+ memcpy(TokenContext_Internal_p->TunnelIP,
+ SAParamsIPsec_p->SrcIPAddr_p,
+ 16);
+ memcpy(TokenContext_Internal_p->TunnelIP + 16,
+ SAParamsIPsec_p->DestIPAddr_p,
+ 16);
+ }
+ }
+ else if ((HeaderProto == TKB_HDR_IPV4_OUT_TRANSP_NATT ||
+ HeaderProto == TKB_HDR_IPV4_IN_TRANSP_NATT) &&
+ (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TRANSPORT_NAT) !=0)
+ {
+ TokenContext_Internal_p->u.generic.ESPFlags |= TKB_ESP_FLAG_NAT;
+ if (SAParamsIPsec_p->SrcIPAddr_p == NULL ||
+ SAParamsIPsec_p->DestIPAddr_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer NAT address.\n");
+ return TKB_INVALID_PARAMETER;
+ }
+ memcpy(TokenContext_Internal_p->TunnelIP,
+ SAParamsIPsec_p->SrcIPAddr_p,
+ 4);
+ memcpy(TokenContext_Internal_p->TunnelIP + 4,
+ SAParamsIPsec_p->DestIPAddr_p,
+ 4);
+ }
+ else if ((HeaderProto == TKB_HDR_IPV6_OUT_TRANSP_NATT ||
+ HeaderProto == TKB_HDR_IPV6_IN_TRANSP_NATT) &&
+ (SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_TRANSPORT_NAT) !=0)
+ {
+ TokenContext_Internal_p->u.generic.ESPFlags |= TKB_ESP_FLAG_NAT;
+ if (SAParamsIPsec_p->SrcIPAddr_p == NULL ||
+ SAParamsIPsec_p->DestIPAddr_p == NULL)
+ {
+ LOG_CRIT("SABuilder: NULL pointer NAT address.\n");
+ return TKB_INVALID_PARAMETER;
+ }
+ memcpy(TokenContext_Internal_p->TunnelIP,
+ SAParamsIPsec_p->SrcIPAddr_p,
+ 16);
+ memcpy(TokenContext_Internal_p->TunnelIP + 16,
+ SAParamsIPsec_p->DestIPAddr_p,
+ 16);
+ }
+ return TKB_STATUS_OK;
+}
+
+/*----------------------------------------------------------------------------
+ * TokenBuilder_Next_PktId
+ *
+ * Increment the PktID if the Token Context describes an IPv4 ESP Tunnel
+ * operation
+ *
+ */
+unsigned int
+TokenBuilder_Next_PktId(
+ const void * const TokenContext_p,
+ unsigned int PktId)
+{
+ const TokenBuilder_Context_t * const TokenContext_Internal_p =
+ (const TokenBuilder_Context_t * const )TokenContext_p;
+ if (TokenContext_Internal_p->hproto == TKB_HDR_IPV4_OUT_TUNNEL ||
+ TokenContext_Internal_p->hproto == TKB_HDR_IPV4_OUT_TUNNEL_NATT)
+ {
+ return (PktId + 1) & MASK_16_BITS;
+ }
+ else
+ {
+ return PktId;
+ }
+}
+
+
+#endif
+
+/*----------------------------------------------------------------------------
+ * TokenBuilder_BuildContext_IPsec
+ *
+ * Create a Token Context Record for IPsec.
+ *
+ * SAParams_p (input)
+ * Points to the SA parameters data structure. It is important that
+ * SABuilder_GetSIze() and SABuilder_BuildSA() have already been called
+ * for this SA.
+ * TokenContext_Internal_p (output)
+ * Buffer to hold the Token Context Record.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ * the contents of the SA parameters are invalid.
+ */
+static TokenBuilder_Status_t
+TokenBuilder_BuildContext_IPsec(
+ const SABuilder_Params_t * const SAParams_p,
+ TokenBuilder_Context_t * const TokenContext_Internal_p)
+{
+ SABuilder_Params_IPsec_t *SAParamsIPsec_p;
+ SAParamsIPsec_p = (SABuilder_Params_IPsec_t *)
+ (SAParams_p->ProtocolExtension_p);
+ if (SAParamsIPsec_p == NULL)
+ {
+ LOG_CRIT("TokenBuilder_BuildContext:"
+ " IPsec extension pointer is NULL\n");
+ return TKB_INVALID_PARAMETER;
+ }
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_ESP) != 0)
+ {
+#ifdef TKB_ENABLE_IPSEC_ESP
+ TokenContext_Internal_p->ExtSeq = 0;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_NO_ANTI_REPLAY) != 0)
+ TokenContext_Internal_p->AntiReplay = 0;
+ else
+ TokenContext_Internal_p->AntiReplay = 1;
+
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_ESP_OUT;
+ TokenContext_Internal_p->PadBlockByteCount = 4;
+ TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CBC;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) != 0)
+ TokenContext_Internal_p->ExtSeq = 1;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_ESP_IN;
+ TokenContext_Internal_p->PadBlockByteCount = 4;
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_PAD_VERIFY;
+ TokenContext_Internal_p->IVHandling = TKB_IV_INBOUND_CBC;
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_LONG_SEQ) != 0)
+ TokenContext_Internal_p->ExtSeq = 1;
+ if (TokenContext_Internal_p->ExtSeq == 0 &&
+ SAParams_p->OffsetSeqNum + 2 == SAParams_p->OffsetSeqMask &&
+ TokenContext_Internal_p->AntiReplay != 0)
+ {
+ TokenContext_Internal_p->ExtSeq = 2;
+ /* Special case, ExtSeq==2 do not use extended sequence
+ number, but update context as if we have extended
+ sequence number. Special SA format fixed seqnum/mask
+ offsets.
+ */
+ }
+ TokenContext_Internal_p->AntiReplay *=
+ SAParamsIPsec_p->SequenceMaskBitCount / 32;
+ }
+ TokenContext_Internal_p->SeqOffset = SAParams_p->OffsetSeqNum;
+
+ switch (SAParams_p->CryptoAlgo)
+ {
+ case SAB_CRYPTO_NULL:
+ TokenContext_Internal_p->IVByteCount = 0;
+ break;
+ case SAB_CRYPTO_DES:
+ case SAB_CRYPTO_3DES:
+ TokenContext_Internal_p->IVByteCount = 8;
+ TokenContext_Internal_p->PadBlockByteCount = 8;
+ break;
+ case SAB_CRYPTO_AES:
+ case SAB_CRYPTO_SM4:
+ case SAB_CRYPTO_BC0:
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CBC)
+ {
+ TokenContext_Internal_p->IVByteCount = 16;
+ TokenContext_Internal_p->PadBlockByteCount = 16;
+ }
+ else
+ {
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_OUTBOUND_CTR;
+ else
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_INBOUND_CTR;
+ if (SAParams_p->IVSrc == SAB_IV_SRC_IMPLICIT)
+ TokenContext_Internal_p->IVByteCount = 0;
+ else
+ TokenContext_Internal_p->IVByteCount = 8;
+ }
+ break;
+ case SAB_CRYPTO_CHACHA20:
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_OUTBOUND_CTR;
+ else
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_INBOUND_CTR;
+ if (SAParams_p->IVSrc == SAB_IV_SRC_IMPLICIT)
+ TokenContext_Internal_p->IVByteCount = 0;
+ else
+ TokenContext_Internal_p->IVByteCount = 8;
+ break;
+ default:
+ LOG_CRIT("TokenBuilder_BuildContext:"
+ " unsupported crypto algorithm.\n");
+ return TKB_INVALID_PARAMETER;
+ }
+
+ /* For all inbound and CTR mode outbound packets there is
+ only one supported way to obtain the IV, which is already
+ taken care of. Now handle outbound CBC. */
+ if(SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CBC &&
+ SAParams_p->direction == SAB_DIRECTION_OUTBOUND &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+ {
+ switch (SAParams_p->IVSrc)
+ {
+ case SAB_IV_SRC_DEFAULT:
+ case SAB_IV_SRC_PRNG:
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_IV_PRNG;
+ break;
+ case SAB_IV_SRC_SA: /* No action required */
+ break;
+ case SAB_IV_SRC_TOKEN:
+ if (TokenContext_Internal_p->IVByteCount == 8)
+ {
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_OUTBOUND_TOKEN_2WORDS;
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_IV_TOKEN_2WORDS;
+ }
+ else
+ {
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_OUTBOUND_TOKEN_4WORDS;
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_IV_TOKEN_4WORDS;
+ }
+ break;
+ default:
+ LOG_CRIT("TokenBuilder_BuildContext:"
+ "Unsupported IV source\n");
+ return TKB_INVALID_PARAMETER;
+ }
+ }
+
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND &&
+ SAParamsIPsec_p->PadAlignment >
+ TokenContext_Internal_p->PadBlockByteCount &&
+ SAParamsIPsec_p->PadAlignment <= 256)
+ TokenContext_Internal_p->PadBlockByteCount =
+ SAParamsIPsec_p->PadAlignment;
+
+ switch(SAParams_p->AuthAlgo)
+ {
+ case SAB_AUTH_NULL:
+ TokenContext_Internal_p->ICVByteCount = 0;
+ TokenContext_Internal_p->ExtSeq = 0;
+ break;
+ case SAB_AUTH_HMAC_MD5:
+ case SAB_AUTH_HMAC_SHA1:
+ case SAB_AUTH_AES_XCBC_MAC:
+ case SAB_AUTH_AES_CMAC_128:
+ TokenContext_Internal_p->ICVByteCount = 12;
+ break;
+ case SAB_AUTH_HMAC_SHA2_224:
+ case SAB_AUTH_HMAC_SHA2_256:
+ case SAB_AUTH_HMAC_SM3:
+ TokenContext_Internal_p->ICVByteCount = 16;
+ break;
+ case SAB_AUTH_HMAC_SHA2_384:
+ TokenContext_Internal_p->ICVByteCount = 24;
+ break;
+ case SAB_AUTH_HMAC_SHA2_512:
+ TokenContext_Internal_p->ICVByteCount = 32;
+ break;
+ case SAB_AUTH_AES_CCM:
+ case SAB_AUTH_AES_GCM:
+ case SAB_AUTH_AES_GMAC:
+ // All these protocols have a selectable ICV length.
+ if (SAParamsIPsec_p->ICVByteCount == 8 ||
+ SAParamsIPsec_p->ICVByteCount == 12 ||
+ SAParamsIPsec_p->ICVByteCount == 16)
+ {
+ TokenContext_Internal_p->ICVByteCount =
+ SAParamsIPsec_p->ICVByteCount;
+ }
+ else
+ {
+ TokenContext_Internal_p->ICVByteCount = 16;
+ }
+ switch (SAParams_p->AuthAlgo)
+ {
+ /* These protocols need specialized protocol codes
+ for the token generator.*/
+ case SAB_AUTH_AES_CCM:
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_ESP_CCM_OUT;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_ESP_CCM_IN;
+ }
+ TokenContext_Internal_p->u.generic.CCMSalt =
+ (SAParams_p->Nonce_p[0] << 8) |
+ (SAParams_p->Nonce_p[1] << 16) |
+ (SAParams_p->Nonce_p[2] << 24) |
+ TKB_CCM_FLAG_ADATA_L4 |
+ ((TokenContext_Internal_p->ICVByteCount-2)*4);
+ break;
+ case SAB_AUTH_AES_GCM:
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_ESP_GCM_OUT;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_ESP_GCM_IN;
+ }
+ break;
+ case SAB_AUTH_AES_GMAC:
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_ESP_GMAC_OUT;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_ESP_GMAC_IN;
+ }
+ break;
+ default:
+ ;
+ }
+ break;
+ case SAB_AUTH_POLY1305:
+ TokenContext_Internal_p->ICVByteCount = 16;
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ TokenContext_Internal_p->protocol =
+ TKB_PROTO_ESP_CHACHAPOLY_OUT;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol =
+ TKB_PROTO_ESP_CHACHAPOLY_IN;
+ }
+ break;
+ default:
+ LOG_CRIT("TokenBuilder_BuildContext:"
+ " unsupported authentication algorithm.\n");
+ return TKB_INVALID_PARAMETER;
+ }
+#else /* TKB_ENABLE_IPSEC_ESP */
+ LOG_CRIT("TokenBuilder_BuildContext: ESP not supported\n");
+ return TKB_INVALID_PARAMETER;
+#endif /* TKB_ENABLE_IPSEC_ESP */
+ }
+ else if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_AH) != 0)
+ {
+#ifdef TKB_ENABLE_IPSEC_AH
+
+#else /* TKB_ENABLE_IPSEC_AH */
+ LOG_CRIT("TokenBuilder_BuildContext: AH not supported\n");
+ return TKB_INVALID_PARAMETER;
+#endif /* TKB_ENABLE_IPSEC_AH */
+ }
+ else
+ {
+ LOG_CRIT("TokenBuilder_BuildContext: Neither ESP nor AH set\n");
+ return TKB_INVALID_PARAMETER;
+ }
+#ifdef TKB_ENABLE_EXTENDED_IPSEC
+ if ((SAParamsIPsec_p->IPsecFlags & SAB_IPSEC_EXT_PROCESSING) != 0)
+ {
+ TokenBuilder_Status_t Rc;
+
+ Rc = TokenBuilder_BuildContext_Extended(SAParams_p,
+ TokenContext_Internal_p);
+ return Rc;
+ }
+#endif
+ return TKB_STATUS_OK;
+}
+#endif
+
+
+#ifdef TKB_ENABLE_PROTO_SSLTLS
+/*----------------------------------------------------------------------------
+ * TokenBuilder_BuildContext_SSLTLS
+ *
+ * Create a Token Context Record for SSL/TLS/DTLS
+ *
+ * SAParams_p (input)
+ * Points to the SA parameters data structure. It is important that
+ * SABuilder_GetSIze() and SABuilder_BuildSA() have already been called
+ * for this SA.
+ * TokenContext_Internal_p (output)
+ * Buffer to hold the Token Context Record.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ * the contents of the SA parameters are invalid.
+ */
+static TokenBuilder_Status_t
+TokenBuilder_BuildContext_SSLTLS(
+ const SABuilder_Params_t * const SAParams_p,
+ TokenBuilder_Context_t * const TokenContext_Internal_p)
+{
+ SABuilder_Params_SSLTLS_t *SAParamsSSLTLS_p;
+ SAParamsSSLTLS_p = (SABuilder_Params_SSLTLS_t *)
+ (SAParams_p->ProtocolExtension_p);
+ if (SAParamsSSLTLS_p == NULL)
+ {
+ LOG_CRIT("TokenBuilder_BuildContext:"
+ " SSL/TLS extension pointer is NULL\n");
+ return TKB_INVALID_PARAMETER;
+ }
+
+ TokenContext_Internal_p->ExtSeq = 0;
+ TokenContext_Internal_p->AntiReplay = 1;
+ TokenContext_Internal_p->IVOffset = 0;
+ TokenContext_Internal_p->DigestWordCount = 0;
+ TokenContext_Internal_p->u.generic.ESPFlags = 0;
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_SSLTLS_OUT;
+ TokenContext_Internal_p->PadBlockByteCount = 1;
+ TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CBC;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_SSLTLS_IN;
+ TokenContext_Internal_p->PadBlockByteCount = 1;
+ if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_ARCFOUR)
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_PAD_VERIFY;
+ TokenContext_Internal_p->IVHandling = TKB_IV_INBOUND_CBC;
+ }
+ TokenContext_Internal_p->SeqOffset = SAParams_p->OffsetSeqNum;
+
+ switch (SAParams_p->CryptoAlgo)
+ {
+ case SAB_CRYPTO_NULL:
+ TokenContext_Internal_p->IVByteCount = 0;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+ break;
+ case SAB_CRYPTO_ARCFOUR:
+ TokenContext_Internal_p->IVByteCount = 0;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_ARC4;
+ TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIJPtr;
+ break;
+ case SAB_CRYPTO_DES:
+ case SAB_CRYPTO_3DES:
+ TokenContext_Internal_p->IVByteCount = 8;
+ TokenContext_Internal_p->PadBlockByteCount = 8;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_IV2;
+ TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+ break;
+ case SAB_CRYPTO_AES:
+ case SAB_CRYPTO_SM4:
+ case SAB_CRYPTO_BC0:
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_GCM)
+ {
+ TokenContext_Internal_p->IVByteCount = 8;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+ TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CTR;
+ if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+ {
+ TokenContext_Internal_p->protocol =
+ TKB_PROTO_TLS13_GCM_OUT;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol =
+ TKB_PROTO_SSLTLS_GCM_OUT;
+ }
+ }
+ else
+ {
+ TokenContext_Internal_p->IVHandling = TKB_IV_INBOUND_CTR;
+ if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+ {
+ TokenContext_Internal_p->protocol =
+ TKB_PROTO_TLS13_GCM_IN;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol =
+ TKB_PROTO_SSLTLS_GCM_IN;
+ }
+ }
+ }
+ else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CCM)
+ {
+ TokenContext_Internal_p->IVByteCount = 8;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+ TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CTR;
+ if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+ {
+ TokenContext_Internal_p->protocol =
+ TKB_PROTO_TLS13_CCM_OUT;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol =
+ TKB_PROTO_SSLTLS_CCM_OUT;
+ }
+ }
+ else
+ {
+ TokenContext_Internal_p->IVHandling = TKB_IV_INBOUND_CTR;
+ if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+ {
+ TokenContext_Internal_p->protocol =
+ TKB_PROTO_TLS13_CCM_IN;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol =
+ TKB_PROTO_SSLTLS_CCM_IN;
+ }
+ }
+ if (SAParamsSSLTLS_p->ICVByteCount == 0)
+ TokenContext_Internal_p->ICVByteCount = 16;
+ else if (SAParamsSSLTLS_p->ICVByteCount == 8 ||
+ SAParamsSSLTLS_p->ICVByteCount == 16)
+ {
+ TokenContext_Internal_p->ICVByteCount = SAParamsSSLTLS_p->ICVByteCount;
+ }
+ else
+ {
+ LOG_CRIT("TokenBuilder_BuildContext:"
+ " TLS AES-CCM rquires tag length of 8 or 16\n");
+ return TKB_INVALID_PARAMETER;
+ }
+ TokenContext_Internal_p->u.generic.CCMSalt = TKB_CCM_FLAG_ADATA_L3 |
+ ((TokenContext_Internal_p->ICVByteCount-2)*4);
+ }
+ else
+ {
+ TokenContext_Internal_p->IVByteCount = 16;
+ TokenContext_Internal_p->PadBlockByteCount = 16;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_IV4;
+ TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+ }
+ break;
+ case SAB_CRYPTO_CHACHA20:
+ TokenContext_Internal_p->IVByteCount = 0;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_TLS13_CHACHAPOLY_OUT;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_SSLTLS_CHACHAPOLY_OUT;
+ }
+ }
+ else
+ {
+ if (SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_3)
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_TLS13_CHACHAPOLY_IN;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_SSLTLS_CHACHAPOLY_IN;
+ }
+ }
+ break;
+ default:
+ LOG_CRIT("TokenBuilder_BuildContext:"
+ " unsupported crypto algorithm.\n");
+ return TKB_INVALID_PARAMETER;
+ }
+
+ /* For all inbound and ARCFOUR outbound packets there is
+ only one supported way to obtain the IV, which is already
+ taken care of. Now handle outbound CBC. */
+ if(SAParams_p->CryptoMode == SAB_CRYPTO_MODE_CBC &&
+ SAParams_p->direction == SAB_DIRECTION_OUTBOUND &&
+ SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+ {
+ switch (SAParams_p->IVSrc)
+ {
+ case SAB_IV_SRC_DEFAULT:
+ case SAB_IV_SRC_PRNG:
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_IV_PRNG;
+ break;
+ case SAB_IV_SRC_SA: /* No action required */
+ break;
+ case SAB_IV_SRC_TOKEN:
+ if (TokenContext_Internal_p->IVByteCount == 8)
+ {
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_OUTBOUND_TOKEN_2WORDS;
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_IV_TOKEN_2WORDS;
+ }
+ else
+ {
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_OUTBOUND_TOKEN_4WORDS;
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_IV_TOKEN_4WORDS;
+ }
+ break;
+ default:
+ LOG_CRIT("TokenBuilder_BuildContext:"
+ "Unsupported IV source\n");
+ return TKB_INVALID_PARAMETER;
+ }
+ }
+
+ /* In SSL and TLS1.0 the IV does not appear explicitly in the packet */
+ if (SAParamsSSLTLS_p->version == SAB_SSL_VERSION_3_0 ||
+ SAParamsSSLTLS_p->version == SAB_TLS_VERSION_1_0)
+ TokenContext_Internal_p->IVByteCount = 0;
+ else if (TokenContext_Internal_p->u.generic.UpdateHandling == TKB_UPD_IV2 ||
+ TokenContext_Internal_p->u.generic.UpdateHandling == TKB_UPD_IV4)
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_BLK;
+
+ /* Sequence numbers appear explicitly in the packet in DTLS */
+ if (SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_0 ||
+ SAParamsSSLTLS_p->version == SAB_DTLS_VERSION_1_2)
+ {
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_CAPWAP) != 0)
+ TokenContext_Internal_p->u.generic.ESPFlags |= TKB_DTLS_FLAG_CAPWAP;
+
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_NO_ANTI_REPLAY) != 0)
+ TokenContext_Internal_p->ExtSeq = 1;
+ else
+ TokenContext_Internal_p->ExtSeq = 1 +
+ SAParamsSSLTLS_p->SequenceMaskBitCount / 32;
+#ifdef TKB_ENABLE_EXTENDED_DTLS
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_EXT_PROCESSING) != 0)
+ {
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_IPV6) != 0)
+ TokenContext_Internal_p->hproto = TKB_HDR_IPV6_OUT_DTLS;
+ else
+ TokenContext_Internal_p->hproto = TKB_HDR_IPV4_OUT_DTLS;
+ }
+ else
+ {
+ TokenContext_Internal_p->hproto = TKB_HDR_DTLS_UDP_IN;
+ if ((SAParamsSSLTLS_p->SSLTLSFlags & SAB_DTLS_PLAINTEXT_HEADERS) != 0)
+ TokenContext_Internal_p->u.generic.ESPFlags |= TKB_DTLS_FLAG_PLAINTEXT_HDR;
+ }
+ }
+#endif
+ }
+
+ /* Version field is not hashed in SSL 3.0. */
+ if (SAParamsSSLTLS_p->version == SAB_SSL_VERSION_3_0)
+ TokenContext_Internal_p->AntiReplay = 0;
+
+
+ switch(SAParams_p->AuthAlgo)
+ {
+ case SAB_AUTH_HMAC_MD5:
+ case SAB_AUTH_SSLMAC_MD5:
+ TokenContext_Internal_p->ICVByteCount = 16;
+ break;
+ case SAB_AUTH_HMAC_SHA1:
+ case SAB_AUTH_SSLMAC_SHA1:
+ TokenContext_Internal_p->ICVByteCount = 20;
+ break;
+ case SAB_AUTH_HMAC_SHA2_224:
+ TokenContext_Internal_p->ICVByteCount = 28;
+ break;
+ case SAB_AUTH_HMAC_SHA2_256:
+ case SAB_AUTH_HMAC_SM3:
+ TokenContext_Internal_p->ICVByteCount = 32;
+ break;
+ case SAB_AUTH_HMAC_SHA2_384:
+ TokenContext_Internal_p->ICVByteCount = 48;
+ break;
+ case SAB_AUTH_HMAC_SHA2_512:
+ TokenContext_Internal_p->ICVByteCount = 64;
+ break;
+ case SAB_AUTH_AES_GCM:
+ TokenContext_Internal_p->ICVByteCount = 16;
+ break;
+ case SAB_AUTH_AES_CCM:
+ /* Was already set earlier */
+ break;
+ case SAB_AUTH_POLY1305:
+ TokenContext_Internal_p->ICVByteCount = 16;
+ break;
+ default:
+ LOG_CRIT("TokenBuilder_BuildContext:"
+ " unsupported authentication algorithm.\n");
+ return TKB_INVALID_PARAMETER;
+ }
+ if (SAParamsSSLTLS_p->ICVByteCount != 0 &&
+ SAParamsSSLTLS_p->ICVByteCount < TokenContext_Internal_p->ICVByteCount)
+ {
+ TokenContext_Internal_p->ICVByteCount = SAParamsSSLTLS_p->ICVByteCount;
+ }
+ return TKB_STATUS_OK;
+}
+#endif
+
+
+#ifdef TKB_ENABLE_PROTO_BASIC
+/*----------------------------------------------------------------------------
+ * TokenBuilder_BuildContext_Basic
+ *
+ * Create a Token Context Record for Basic crypto
+ *
+ * SAParams_p (input)
+ * Points to the SA parameters data structure. It is important that
+ * SABuilder_GetSIze() and SABuilder_BuildSA() have already been called
+ * for this SA.
+ * TokenContext_Internal_p (output)
+ * Buffer to hold the Token Context Record.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ * the contents of the SA parameters are invalid.
+ */
+static TokenBuilder_Status_t
+TokenBuilder_BuildContext_Basic(
+ const SABuilder_Params_t * const SAParams_p,
+ TokenBuilder_Context_t * const TokenContext_Internal_p)
+{
+ SABuilder_Params_Basic_t *SAParamsBasic_p;
+ SAParamsBasic_p = (SABuilder_Params_Basic_t *)
+ (SAParams_p->ProtocolExtension_p);
+ if (SAParamsBasic_p == NULL)
+ {
+ LOG_CRIT("TokenBuilder_BuildContext:"
+ " Basic extension pointer is NULL\n");
+ return TKB_INVALID_PARAMETER;
+ }
+
+ TokenContext_Internal_p->ExtSeq = 0;
+ TokenContext_Internal_p->AntiReplay = 0;
+ TokenContext_Internal_p->IVOffset = 0;
+ TokenContext_Internal_p->SeqOffset = 0;
+ TokenContext_Internal_p->PadBlockByteCount = 1;
+ TokenContext_Internal_p->IVByteCount = 0;
+ TokenContext_Internal_p->ICVByteCount = 0;
+ TokenContext_Internal_p->DigestWordCount = 0;
+ TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CBC;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+ TokenContext_Internal_p->u.generic.CCMSalt = 0;
+
+ if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+ { /* Basic crypto */
+ if (SAParams_p->AuthAlgo == SAB_AUTH_NULL)
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_CRYPTO;
+ }
+ else if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+ {
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_HASHENC;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_DECHASH;
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_PAD_VERIFY;
+ }
+ }
+#ifdef TKB_ENABLE_CRYPTO_CHACHAPOLY
+ else if (SAParams_p->CryptoAlgo == SAB_CRYPTO_CHACHA20)
+ {
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_CHACHAPOLY_OUT;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_CHACHAPOLY_IN;
+ }
+ }
+#endif
+ else
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_CRYPTHASH;
+ }
+ switch (SAParams_p->CryptoAlgo)
+ {
+ case SAB_CRYPTO_ARCFOUR:
+ TokenContext_Internal_p->IVByteCount = 0;
+ if (SAParams_p->CryptoMode != SAB_CRYPTO_MODE_STATELESS)
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_ARC4;
+ TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIJPtr;
+ break;
+ case SAB_CRYPTO_DES:
+ case SAB_CRYPTO_3DES:
+ TokenContext_Internal_p->IVByteCount = 8;
+ TokenContext_Internal_p->PadBlockByteCount = 8;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_IV2;
+ TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+ break;
+ case SAB_CRYPTO_AES:
+ case SAB_CRYPTO_SM4:
+ case SAB_CRYPTO_BC0:
+ TokenContext_Internal_p->IVByteCount = 16;
+ TokenContext_Internal_p->PadBlockByteCount = 16;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_IV4;
+ TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+ break;
+#ifdef TKB_ENABLE_CRYPTO_WIRELESS
+ case SAB_CRYPTO_KASUMI:
+ TokenContext_Internal_p->IVByteCount = 8;
+ TokenContext_Internal_p->PadBlockByteCount = 8;
+ TokenContext_Internal_p->IVHandling = TKB_IV_KASUMI_F8;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+ TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+ break;
+ case SAB_CRYPTO_SNOW:
+ TokenContext_Internal_p->IVByteCount = 16;
+ TokenContext_Internal_p->PadBlockByteCount = 1;
+ TokenContext_Internal_p->IVHandling = TKB_IV_SNOW_UEA2;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+ TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+ break;
+ case SAB_CRYPTO_ZUC:
+ TokenContext_Internal_p->IVByteCount = 16;
+ TokenContext_Internal_p->PadBlockByteCount = 1;
+ TokenContext_Internal_p->IVHandling = TKB_IV_ZUC_EEA3;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+ TokenContext_Internal_p->IVOffset = SAParams_p->OffsetIV;
+ break;
+#endif
+#ifdef TKB_ENABLE_CRYPTO_CHACHAPOLY
+ case SAB_CRYPTO_CHACHA20:
+ TokenContext_Internal_p->IVByteCount = 16;
+ TokenContext_Internal_p->PadBlockByteCount = 1;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+ break;
+#endif
+ default:
+ LOG_CRIT("TokenBuilder_BuildContext:"
+ " unsupported crypto algorithm.\n");
+ return TKB_INVALID_PARAMETER;
+ }
+
+ switch (SAParams_p->CryptoMode)
+ {
+ case SAB_CRYPTO_MODE_ECB:
+ TokenContext_Internal_p->IVByteCount = 0;
+ TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CBC;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+ break;
+ case SAB_CRYPTO_MODE_BASIC:
+ case SAB_CRYPTO_MODE_CBC:
+ case SAB_CRYPTO_MODE_ICM:
+ case SAB_CRYPTO_MODE_CFB:
+ case SAB_CRYPTO_MODE_OFB:
+ case SAB_CRYPTO_MODE_XTS:
+ case SAB_CRYPTO_MODE_XTS_STATEFUL:
+ case SAB_CRYPTO_MODE_CHACHA_CTR32:
+ case SAB_CRYPTO_MODE_CHACHA_CTR64:
+ if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_BASIC)
+ {
+ TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CBC;
+ if (SAParams_p->CryptoAlgo == SAB_CRYPTO_KASUMI)
+ {
+ TokenContext_Internal_p->IVByteCount = 0;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+ break;
+ }
+ else
+ {
+ TokenContext_Internal_p->PadBlockByteCount = 1;
+ }
+ }
+ else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_ICM)
+ {
+ TokenContext_Internal_p->PadBlockByteCount = 1;
+ }
+ else if (SAParams_p->CryptoMode == SAB_CRYPTO_MODE_XTS ||
+ SAParams_p->CryptoMode == SAB_CRYPTO_MODE_XTS_STATEFUL)
+ {
+ TokenContext_Internal_p->PadBlockByteCount = 1;
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_XTS_CRYPTO;
+ }
+
+ if (SAParams_p->IVSrc == SAB_IV_SRC_TOKEN)
+ {
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+ if (TokenContext_Internal_p->IVByteCount == 8)
+ {
+ TokenContext_Internal_p->IVByteCount = 0;
+ if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_COPY_TOKEN_2WORDS;
+ else
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_OUTBOUND_TOKEN_2WORDS;
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_IV_TOKEN_2WORDS;
+ }
+ else
+ {
+ TokenContext_Internal_p->IVByteCount = 0;
+ if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_COPY_TOKEN_4WORDS;
+ else
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_OUTBOUND_TOKEN_4WORDS;
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_IV_TOKEN_4WORDS;
+ }
+ }
+ else if (SAParams_p->IVSrc == SAB_IV_SRC_INPUT)
+ {
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+ if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+ TokenContext_Internal_p->IVHandling = TKB_IV_COPY_CBC;
+ else
+ TokenContext_Internal_p->IVHandling = TKB_IV_INBOUND_CBC;
+ }
+ else
+ {
+ if(SAParams_p->IVSrc == SAB_IV_SRC_PRNG)
+ {
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_IV_PRNG;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+ }
+ if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+ {
+ if (TokenContext_Internal_p->IVByteCount==8)
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_OUTBOUND_2WORDS;
+ else
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_OUTBOUND_4WORDS;
+ }
+ TokenContext_Internal_p->IVByteCount = 0;
+ }
+
+ break;
+ case SAB_CRYPTO_MODE_CTR:
+ case SAB_CRYPTO_MODE_CCM:
+ case SAB_CRYPTO_MODE_GCM:
+ case SAB_CRYPTO_MODE_GMAC:
+ TokenContext_Internal_p->PadBlockByteCount = 1;
+ TokenContext_Internal_p->u.generic.UpdateHandling = TKB_UPD_NULL;
+
+ if (SAParams_p->IVSrc == SAB_IV_SRC_TOKEN)
+ {
+ TokenContext_Internal_p->IVByteCount = 0;
+ if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_COPY_TOKEN_4WORDS;
+ else
+ TokenContext_Internal_p->IVHandling =
+ TKB_IV_OUTBOUND_TOKEN_4WORDS;
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_IV_TOKEN_4WORDS;
+ }
+ else if (SAParams_p->IVSrc == SAB_IV_SRC_INPUT)
+ {
+ TokenContext_Internal_p->IVByteCount = 8;
+ if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+ TokenContext_Internal_p->IVHandling = TKB_IV_COPY_CTR;
+ else
+ TokenContext_Internal_p->IVHandling = TKB_IV_INBOUND_CTR;
+ }
+ else
+ {
+ TokenContext_Internal_p->IVByteCount = 0;
+ if ((SAParams_p->flags & SAB_FLAG_COPY_IV) != 0)
+ TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CTR;
+ }
+ break;
+#ifdef TKB_ENABLE_CRYPTO_WIRELESS
+ case SAB_CRYPTO_MODE_F8:
+ case SAB_CRYPTO_MODE_UEA2:
+ case SAB_CRYPTO_MODE_EEA3:
+ TokenContext_Internal_p->PadBlockByteCount = 1;
+ TokenContext_Internal_p->u.generic.CCMSalt =
+ (SAParamsBasic_p->bearer << 3) |
+ (SAParamsBasic_p->direction<<2);
+ if (TokenContext_Internal_p->IVByteCount == 8)
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_IV_TOKEN_2WORDS;
+ else
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_IV_TOKEN_4WORDS;
+ TokenContext_Internal_p->IVByteCount = 0;
+ break;
+#endif
+ default:
+ ;
+ }
+ }
+ else if (SAParams_p->AuthAlgo == SAB_AUTH_NULL)
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_BYPASS;
+ }
+ else if (SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_HMAC_PRECOMPUTE &&
+ SAParams_p->OffsetDigest1 != 0)
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_HMAC_PRECOMPUTE;
+ }
+ else
+ {
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_HASH;
+ }
+ if (SAParams_p->AuthAlgo != SAB_AUTH_NULL)
+ { /* Basic hash */
+ if ((SAParams_p->flags & (SAB_FLAG_HASH_SAVE|
+ SAB_FLAG_HASH_INTERMEDIATE)) != 0)
+ {
+ /* We intend to store the hash state.*/
+ TokenContext_Internal_p->SeqOffset = SAParams_p->OffsetDigest0;
+ }
+ if(SAParams_p->CryptoAlgo == SAB_CRYPTO_NULL)
+ {
+ /* Use ExtSeq variable to specify that payload will be copied */
+ if ((SAParams_p->flags & SAB_FLAG_SUPPRESS_PAYLOAD) == 0)
+ TokenContext_Internal_p->ExtSeq = 1;
+ }
+ else
+ {
+ /* Use ExtSeq variable to specify that header
+ * (authenticated data( will be copied */
+ if ((SAParams_p->flags & SAB_FLAG_SUPPRESS_HEADER) == 0)
+ TokenContext_Internal_p->ExtSeq = 1;
+ }
+ switch(SAParams_p->AuthAlgo)
+ {
+ case SAB_AUTH_HASH_MD5:
+ TokenContext_Internal_p->ICVByteCount = 16;
+ TokenContext_Internal_p->DigestWordCount = 16 + 4;
+ break;
+ case SAB_AUTH_HMAC_MD5:
+ TokenContext_Internal_p->ICVByteCount = 16;
+ TokenContext_Internal_p->DigestWordCount = 4;
+ break;
+ case SAB_AUTH_HASH_SHA1:
+ TokenContext_Internal_p->ICVByteCount = 20;
+ TokenContext_Internal_p->DigestWordCount = 16 + 5;
+ break;
+ case SAB_AUTH_HMAC_SHA1:
+ TokenContext_Internal_p->ICVByteCount = 20;
+ TokenContext_Internal_p->DigestWordCount = 5;
+ break;
+ case SAB_AUTH_HASH_SHA2_224:
+ TokenContext_Internal_p->ICVByteCount = 32;
+ TokenContext_Internal_p->DigestWordCount = 16 + 8;
+ break;
+ case SAB_AUTH_HMAC_SHA2_224:
+ TokenContext_Internal_p->ICVByteCount = 32;
+ TokenContext_Internal_p->DigestWordCount = 8;
+ break;
+ case SAB_AUTH_HASH_SHA2_256:
+ case SAB_AUTH_HASH_SM3:
+ TokenContext_Internal_p->ICVByteCount = 32;
+ TokenContext_Internal_p->DigestWordCount = 16 + 8;
+ break;
+ case SAB_AUTH_HMAC_SHA2_256:
+ case SAB_AUTH_HMAC_SM3:
+ TokenContext_Internal_p->ICVByteCount = 32;
+ TokenContext_Internal_p->DigestWordCount = 8;
+ break;
+ case SAB_AUTH_HASH_SHA2_384:
+ TokenContext_Internal_p->ICVByteCount = 64;
+ TokenContext_Internal_p->DigestWordCount = 16 + 16;
+ break;
+ case SAB_AUTH_HMAC_SHA2_384:
+ if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_ENCRYPT_AFTER_HASH) != 0)
+ TokenContext_Internal_p->ICVByteCount = 48;
+ else
+ TokenContext_Internal_p->ICVByteCount = 64;
+ TokenContext_Internal_p->DigestWordCount = 16;
+ break;
+ case SAB_AUTH_HASH_SHA2_512:
+ TokenContext_Internal_p->ICVByteCount = 64;
+ TokenContext_Internal_p->DigestWordCount = 16 + 16;
+ break;
+ case SAB_AUTH_HMAC_SHA2_512:
+ TokenContext_Internal_p->ICVByteCount = 64;
+ TokenContext_Internal_p->DigestWordCount = 16;
+ break;
+ case SAB_AUTH_HASH_SHA3_224:
+ case SAB_AUTH_HMAC_SHA3_224:
+ case SAB_AUTH_KEYED_HASH_SHA3_224:
+ TokenContext_Internal_p->ICVByteCount = 28;
+ TokenContext_Internal_p->DigestWordCount = 7;
+ break;
+ case SAB_AUTH_HASH_SHA3_256:
+ case SAB_AUTH_HMAC_SHA3_256:
+ case SAB_AUTH_KEYED_HASH_SHA3_256:
+ TokenContext_Internal_p->ICVByteCount = 32;
+ TokenContext_Internal_p->DigestWordCount = 8;
+ break;
+ case SAB_AUTH_HASH_SHA3_384:
+ case SAB_AUTH_HMAC_SHA3_384:
+ case SAB_AUTH_KEYED_HASH_SHA3_384:
+ TokenContext_Internal_p->ICVByteCount = 48;
+ TokenContext_Internal_p->DigestWordCount = 12;
+ break;
+ case SAB_AUTH_HASH_SHA3_512:
+ case SAB_AUTH_HMAC_SHA3_512:
+ case SAB_AUTH_KEYED_HASH_SHA3_512:
+ TokenContext_Internal_p->ICVByteCount = 64;
+ TokenContext_Internal_p->DigestWordCount = 16;
+ break;
+
+ case SAB_AUTH_AES_XCBC_MAC:
+ case SAB_AUTH_AES_CMAC_128:
+ case SAB_AUTH_AES_CMAC_192:
+ case SAB_AUTH_AES_CMAC_256:
+ TokenContext_Internal_p->ICVByteCount = 16;
+ TokenContext_Internal_p->DigestWordCount = 4;
+ break;
+ case SAB_AUTH_AES_CCM:
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_CCM_OUT;
+ else
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_CCM_IN;
+ TokenContext_Internal_p->ICVByteCount = 16;
+ TokenContext_Internal_p->DigestWordCount = 4;
+ // Adjust byte count now as it influences the SALT value.
+ if (SAParamsBasic_p->ICVByteCount != 0 &&
+ SAParamsBasic_p->ICVByteCount <
+ TokenContext_Internal_p->ICVByteCount)
+ TokenContext_Internal_p->ICVByteCount =
+ SAParamsBasic_p->ICVByteCount;
+ TokenContext_Internal_p->u.generic.CCMSalt =
+ (SAParams_p->Nonce_p[0] << 8) |
+ (SAParams_p->Nonce_p[1] << 16) |
+ (SAParams_p->Nonce_p[2] << 24) |
+ TKB_CCM_FLAG_ADATA_L4 |
+ ((TokenContext_Internal_p->ICVByteCount-2)*4);
+ break;
+ case SAB_AUTH_AES_GCM:
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_GCM_OUT;
+ else
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_GCM_IN;
+ TokenContext_Internal_p->ICVByteCount = 16;
+ TokenContext_Internal_p->DigestWordCount = 4;
+ break;
+ case SAB_AUTH_AES_GMAC:
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_GMAC_OUT;
+ else
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_GMAC_IN;
+ TokenContext_Internal_p->ICVByteCount = 16;
+ TokenContext_Internal_p->DigestWordCount = 4;
+ break;
+#ifdef TKB_ENABLE_CRYPTO_WIRELESS
+ case SAB_AUTH_KASUMI_F9:
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_KASUMI_HASH;
+ TokenContext_Internal_p->ICVByteCount = 4;
+ TokenContext_Internal_p->DigestWordCount = 4;
+ TokenContext_Internal_p->u.generic.CCMSalt =
+ SAParamsBasic_p->fresh;
+ break;
+ case SAB_AUTH_SNOW_UIA2:
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_SNOW_HASH;
+ TokenContext_Internal_p->ICVByteCount = 4;
+ TokenContext_Internal_p->DigestWordCount = 4;
+ TokenContext_Internal_p->u.generic.CCMSalt =
+ SAParamsBasic_p->fresh;
+ break;
+ case SAB_AUTH_ZUC_EIA3:
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_ZUC_HASH;
+ TokenContext_Internal_p->ICVByteCount = 4;
+ TokenContext_Internal_p->DigestWordCount = 4;
+ TokenContext_Internal_p->u.generic.CCMSalt =
+ (SAParamsBasic_p->bearer << 3);
+ break;
+#endif
+#ifdef TKB_ENABLE_CRYPTO_CHACHAPOLY
+ case SAB_AUTH_KEYED_HASH_POLY1305:
+ case SAB_AUTH_POLY1305:
+ TokenContext_Internal_p->ICVByteCount = 16;
+ TokenContext_Internal_p->DigestWordCount = 4;
+ break;
+#endif
+ default:
+ LOG_CRIT("TokenBuilder_BuildContext:"
+ " unsupported authentication algorithm.\n");
+ return TKB_INVALID_PARAMETER;
+ }
+ if (SAParamsBasic_p->ICVByteCount != 0 &&
+ SAParamsBasic_p->ICVByteCount <
+ TokenContext_Internal_p->ICVByteCount)
+ TokenContext_Internal_p->ICVByteCount =
+ SAParamsBasic_p->ICVByteCount;
+ if ((SAParamsBasic_p->BasicFlags & SAB_BASIC_FLAG_EXTRACT_ICV) != 0 ||
+ ((SAParams_p->AuthAlgo == SAB_AUTH_AES_CCM ||
+ SAParams_p->AuthAlgo == SAB_AUTH_AES_GCM ||
+ SAParams_p->AuthAlgo == SAB_AUTH_AES_GMAC) &&
+ TokenContext_Internal_p->SeqOffset == 0))
+ TokenContext_Internal_p->AntiReplay =
+ TokenContext_Internal_p->ICVByteCount;
+ }
+ return TKB_STATUS_OK;
+}
+#endif
+
+
+#ifdef TKB_ENABLE_PROTO_SRTP
+/*----------------------------------------------------------------------------
+ * TokenBuilder_BuildContext_SRTP
+ *
+ * Create a Token Context Record for SRTP
+ *
+ * SAParams_p (input)
+ * Points to the SA parameters data structure. It is important that
+ * SABuilder_GetSIze() and SABuilder_BuildSA() have already been called
+ * for this SA.
+ * TokenContext_Internal_p (output)
+ * Buffer to hold the Token Context Record.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ * the contents of the SA parameters are invalid.
+ */
+static TokenBuilder_Status_t
+TokenBuilder_BuildContext_SRTP(
+ const SABuilder_Params_t * const SAParams_p,
+ TokenBuilder_Context_t * const TokenContext_Internal_p)
+{
+ // Note: SRTP may not make use of the Token Context fields
+ // CW0, CW1 CCMAalt and UpdateHandling as they occupy the same
+ // space as the SaltKey fields.
+ SABuilder_Params_SRTP_t *SAParamsSRTP_p;
+ SAParamsSRTP_p = (SABuilder_Params_SRTP_t *)
+ (SAParams_p->ProtocolExtension_p);
+ if (SAParamsSRTP_p == NULL)
+ {
+ LOG_CRIT("TokenBuilder_BuildContext:"
+ " SRTP extension pointer is NULL\n");
+ return TKB_INVALID_PARAMETER;
+ }
+
+ if (SAParams_p->direction == SAB_DIRECTION_OUTBOUND)
+ TokenContext_Internal_p->protocol = TKB_PROTO_SRTP_OUT;
+ else
+ TokenContext_Internal_p->protocol = TKB_PROTO_SRTP_IN;
+
+ TokenContext_Internal_p->ICVByteCount = SAParamsSRTP_p->ICVByteCount;
+
+ if (SAParams_p->CryptoAlgo != SAB_CRYPTO_NULL)
+ {
+ TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_TOKEN_SRTP;
+
+ TokenContext_Internal_p->IVByteCount = 16;
+ TokenContext_Internal_p->TokenHeaderWord |=
+ TKB_HEADER_IV_TOKEN_4WORDS;
+ if (SAParams_p->Nonce_p == NULL)
+ {
+ LOG_CRIT("TokenBuilder_BuildContext: NULL nonce pointer.\n");
+ return TKB_INVALID_PARAMETER;
+ }
+
+ TokenContext_Internal_p->u.srtp.SaltKey0 =
+ (SAParams_p->Nonce_p[0]) |
+ (SAParams_p->Nonce_p[1] << 8) |
+ (SAParams_p->Nonce_p[2] << 16) |
+ (SAParams_p->Nonce_p[3] << 24);
+ TokenContext_Internal_p->u.srtp.SaltKey1 =
+ (SAParams_p->Nonce_p[4]) |
+ (SAParams_p->Nonce_p[5] << 8) |
+ (SAParams_p->Nonce_p[6] << 16) |
+ (SAParams_p->Nonce_p[7] << 24);
+ TokenContext_Internal_p->u.srtp.SaltKey2 =
+ (SAParams_p->Nonce_p[8]) |
+ (SAParams_p->Nonce_p[9] << 8) |
+ (SAParams_p->Nonce_p[10] << 16) |
+ (SAParams_p->Nonce_p[11] << 24);
+ TokenContext_Internal_p->u.srtp.SaltKey3 =
+ (SAParams_p->Nonce_p[12]) |
+ (SAParams_p->Nonce_p[13] << 8);
+ }
+ else
+ {
+ TokenContext_Internal_p->IVHandling = TKB_IV_OUTBOUND_CBC;
+ TokenContext_Internal_p->IVByteCount = 0;
+ }
+
+ if ((SAParamsSRTP_p->SRTPFlags & SAB_SRTP_FLAG_SRTCP) != 0)
+ {
+ TokenContext_Internal_p->ExtSeq = 4;
+ }
+ else
+ {
+ TokenContext_Internal_p->ExtSeq = 0;
+ }
+
+ if ((SAParamsSRTP_p->SRTPFlags & SAB_SRTP_FLAG_INCLUDE_MKI) != 0)
+ {
+ TokenContext_Internal_p->AntiReplay = 4;
+ }
+ else
+ {
+ TokenContext_Internal_p->AntiReplay = 0;
+ }
+ return TKB_STATUS_OK;
+}
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * TokenBuilder_BuildContext
+ *
+ * Create a Token Context Record.
+ *
+ * SAParams_p (input)
+ * Points to the SA parameters data structure. It is important that
+ * SABuilder_GetSIze() and SABuilder_BuildSA() have already been called
+ * for this SA.
+ * TokenContext_p (output)
+ * Buffer to hold the Token Context Record. It must point to a valid
+ * storage buffer that is large enough to hold the Token
+ * Context. Before calling this function, the application must call
+ * TokeBuilder_GetContextSize() with the same SA parameters and
+ * allocate a buffer of that size.
+ *
+ * Return:
+ * TKB_STATUS_OK if successful.
+ * TKB_INVALID_PARAMETER if any of the pointer parameters is NULL or if
+ * the contents of the SA parameters are invalid.
+ */
+TokenBuilder_Status_t
+TokenBuilder_BuildContext(
+ const SABuilder_Params_t * const SAParams_p,
+ void * const TokenContext_p
+ )
+{
+ TokenBuilder_Context_t *TokenContext_Internal_p =
+ (TokenBuilder_Context_t *)TokenContext_p;
+ TokenBuilder_Status_t Rc;
+#ifdef TKB_STRICT_ARGS_CHECK
+ if (SAParams_p == NULL || TokenContext_p == NULL)
+ {
+ LOG_CRIT("TokenBuilder_BuildContext: NULL pointer supplied\n");
+ return TKB_INVALID_PARAMETER;
+ }
+#endif
+
+ TokenContext_Internal_p->TokenHeaderWord = TKB_HEADER_DEFAULT;
+
+ TokenContext_Internal_p->u.generic.CW0 = SAParams_p->CW0;
+ TokenContext_Internal_p->u.generic.CW1 = SAParams_p->CW1;
+ TokenContext_Internal_p->hproto = TKB_HDR_BYPASS;
+ switch (SAParams_p->protocol)
+ {
+#ifdef TKB_ENABLE_PROTO_IPSEC
+ case SAB_PROTO_IPSEC:
+ Rc = TokenBuilder_BuildContext_IPsec(SAParams_p,
+ TokenContext_Internal_p);
+ break;
+#endif /* TKB_ENABLE_PROTO_IPSEC */
+#ifdef TKB_ENABLE_PROTO_SSLTLS
+ case SAB_PROTO_SSLTLS:
+ Rc = TokenBuilder_BuildContext_SSLTLS(SAParams_p,
+ TokenContext_Internal_p);
+ break;
+#endif
+#ifdef TKB_ENABLE_PROTO_BASIC
+ case SAB_PROTO_BASIC:
+ Rc = TokenBuilder_BuildContext_Basic(SAParams_p,
+ TokenContext_Internal_p);
+ break;
+#endif
+#ifdef TKB_ENABLE_PROTO_SRTP
+ case SAB_PROTO_SRTP:
+ Rc = TokenBuilder_BuildContext_SRTP(SAParams_p,
+ TokenContext_Internal_p);
+ break;
+#endif
+ default:
+ LOG_CRIT("TokenBuilder_BuildContext: unsupported protocol.\n");
+ return TKB_INVALID_PARAMETER;
+ }
+
+ if (Rc != TKB_STATUS_OK)
+ {
+ return Rc;
+ }
+
+ if (TokenContext_Internal_p->protocol != TKB_PROTO_BASIC_HMAC_PRECOMPUTE &&
+ SAParams_p->OffsetDigest1 != 0 &&
+ SAParams_p->AuthKey2_p == NULL)
+ {
+ /* HMAC key desired, but not supplied, convert context temporarily
+ to context prepare context. After the first token, the Token
+ Builder will switch it back */
+ TokenContext_Internal_p->protocol_next =
+ TokenContext_Internal_p->protocol;
+ TokenContext_Internal_p->hproto_next =
+ TokenContext_Internal_p->hproto;
+ TokenContext_Internal_p->IVHandling_next =
+ TokenContext_Internal_p->IVHandling;
+ TokenContext_Internal_p->HeaderWordFields_next =
+ (TokenContext_Internal_p->TokenHeaderWord >> 22) & MASK_8_BITS;
+ TokenContext_Internal_p->protocol = TKB_PROTO_BASIC_HMAC_CTXPREPARE;
+ TokenContext_Internal_p->hproto = TKB_HDR_BYPASS;
+ TokenContext_Internal_p->IVHandling = TKB_IV_INBOUND_CTR;
+ /* Clear fields in Token Header word, to prevent IV from token etc.*/
+ TokenContext_Internal_p->TokenHeaderWord &= 0xc03fffff;
+ TokenContext_Internal_p->DigestWordCount =
+ SAParams_p->OffsetDigest1 - SAParams_p->OffsetDigest0;
+ TokenContext_Internal_p->DigestOffset = SAParams_p->OffsetDigest0;
+ }
+
+ LOG_INFO("TokenBuilderBuildContext: created context, header word=%08x\n"
+ " proto=%d hproto=%d padalign=%d ivsize=%d icvsize=%d\n"
+ " seqoffset=%d extseq=%d antireplay=%d ivhandling=%d\n",
+ TokenContext_Internal_p->TokenHeaderWord,
+ TokenContext_Internal_p->protocol,
+ TokenContext_Internal_p->hproto,
+ TokenContext_Internal_p->PadBlockByteCount,
+ TokenContext_Internal_p->IVByteCount,
+ TokenContext_Internal_p->ICVByteCount,
+ TokenContext_Internal_p->SeqOffset,
+ TokenContext_Internal_p->ExtSeq,
+ TokenContext_Internal_p->AntiReplay,
+ TokenContext_Internal_p->IVHandling);
+
+ return TKB_STATUS_OK;
+}
+
+
+
+
+/* end of file token_builder_context.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/token/token_builder_core.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/token/token_builder_core.c
new file mode 100644
index 0000000..1cdba87
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/builder/token/token_builder_core.c
@@ -0,0 +1,5650 @@
+/* File token_builder_core.c
+ code generated by tbgen.py */
+
+/*****************************************************************************
+* Copyright (c) 2011-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+****************************************************************************/
+
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "token_builder.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "c_token_builder.h"
+#include "basic_defs.h"
+#include "clib.h"
+#include "token_builder_internal.h"
+#include "token_builder_macros.h"
+
+#include "log.h"
+
+TokenBuilder_Status_t
+TokenBuilder_GetSize(
+ const void * const TokenContext_p,
+ unsigned int * const TokenWord32Count_p
+ )
+{
+ TokenBuilder_Context_t ContextCopy;
+ TokenBuilder_Context_t *TokenContext_Internal_p = &ContextCopy;
+ unsigned int WordCountOld = 0;
+
+
+ uint32_t proto;
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ uint32_t hproto;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t seq_offset;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t ivlen;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SRTP == 1u
+ uint32_t icvlen;
+#endif
+ uint32_t ivhandling;
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_WIRELESS == 1u || TKB_HAVE_PROTO_SRTP == 1u
+ uint32_t extseq;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_SRTP == 1u || TKB_HAVE_PROTO_IPSEC == 1u
+ uint32_t antireplay;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_XTS == 1u
+ uint32_t upd_handling;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t cipher_is_aes;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t hstatelen;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t capwap_out;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ uint32_t is_nat;
+#endif
+
+#ifdef TKB_STRICT_ARGS_CHECK
+ if (TokenWord32Count_p == NULL || TokenContext_p == NULL)
+ {
+ LOG_CRIT("TokenBuilder_GetSize: NULL pointer supplied\n");
+ return TKB_INVALID_PARAMETER;
+ }
+#endif
+ memcpy(TokenContext_Internal_p, TokenContext_p, sizeof(ContextCopy));
+
+redo:
+ *TokenWord32Count_p = TKB_TOKEN_HEADER_WORD_COUNT;
+
+ *TokenWord32Count_p += 3u;
+ ivhandling = EVAL_ivhandling();
+ if (ivhandling >= 8u)
+ {
+ if (ivhandling < 10u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else if (ivhandling > 13u)
+ {
+ *TokenWord32Count_p += 4u;
+ }
+ else if (ivhandling == 10u)
+ {
+ *TokenWord32Count_p += 4u;
+ }
+ else if (ivhandling == 11u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 4u;
+ }
+ }
+ *TokenWord32Count_p += 1u;
+#if TKB_HAVE_PROTO_IPSEC == 1u
+#if TKB_HAVE_EXTENDED_IPSEC == 1u
+ hproto = EVAL_hproto();
+ switch(hproto)
+ {
+ case 5: /* ipv4_out_transp */
+ *TokenWord32Count_p += 2u;
+ break;
+ case 1: /* ipv4_out_transp_nohdrproc */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 11: /* ipv6_out_transp */
+ *TokenWord32Count_p += 5u;
+ break;
+ case 2: /* ipv4_out_tunnel */
+ *TokenWord32Count_p += 6u;
+ break;
+ case 7: /* ipv6_out_tunnel */
+ *TokenWord32Count_p += 11u;
+ break;
+ case 6: /* ipv4_in_transp */
+ *TokenWord32Count_p += 2u;
+ break;
+ case 3: /* ipv4_in_transp_nohdrproc */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 12: /* ipv6_in_transp */
+ *TokenWord32Count_p += 5u;
+ break;
+ case 4: /* ipv4_in_tunnel */
+ case 8: /* ipv6_in_tunnel */
+ case 24: /* ipv4_in_tunnel_natt */
+ case 28: /* ipv6_in_tunnel_natt */
+ *TokenWord32Count_p += 2u;
+ break;
+ case 25: /* ipv4_out_transp_natt */
+ *TokenWord32Count_p += 1u;
+ is_nat = EVAL_is_nat();
+ if (is_nat != 0u)
+ {
+ *TokenWord32Count_p += 4u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 3u;
+ break;
+ case 31: /* ipv6_out_transp_natt */
+ *TokenWord32Count_p += 17u;
+ break;
+ case 22: /* ipv4_out_tunnel_natt */
+ *TokenWord32Count_p += 8u;
+ break;
+ case 27: /* ipv6_out_tunnel_natt */
+ *TokenWord32Count_p += 13u;
+ break;
+ case 26: /* ipv4_in_transp_natt */
+ *TokenWord32Count_p += 1u;
+ is_nat = EVAL_is_nat();
+ if (is_nat != 0u)
+ {
+ *TokenWord32Count_p += 5u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 1u;
+ break;
+ case 32: /* ipv6_in_transp_natt */
+ *TokenWord32Count_p += 15u;
+ break;
+ case 13: /* ipv4_out_dtls */
+ *TokenWord32Count_p += 5u;
+ break;
+ case 33: /* ipv6_out_dtls */
+ *TokenWord32Count_p += 5u;
+ break;
+ }
+#endif
+#endif
+ proto = EVAL_proto();
+ switch(proto)
+ {
+ case 0: /* esp_out */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ if (ivhandling == 2u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 1u;
+ icvlen = EVAL_icvlen();
+ if (icvlen > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq == 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 2u;
+#else
+#endif
+ break;
+ case 1: /* esp_in */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+#if TKB_HAVE_ECN_FIXUP == 1u
+ *TokenWord32Count_p += 1u;
+#endif
+ if (ivhandling == 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ icvlen = EVAL_icvlen();
+ if (icvlen > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq != 1u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+#else
+#endif
+ break;
+ case 2: /* esp_out_ccm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ *TokenWord32Count_p += 5u;
+ extseq = EVAL_extseq();
+ if (extseq == 0u)
+ {
+ *TokenWord32Count_p += 3u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 5u;
+ }
+ *TokenWord32Count_p += 9u;
+#else
+#endif
+ break;
+ case 3: /* esp_in_ccm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ *TokenWord32Count_p += 7u;
+ extseq = EVAL_extseq();
+ if (extseq != 1u)
+ {
+ *TokenWord32Count_p += 3u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 5u;
+ }
+ *TokenWord32Count_p += 1u;
+#if TKB_HAVE_ECN_FIXUP == 1u
+ *TokenWord32Count_p += 1u;
+#endif
+ *TokenWord32Count_p += 4u;
+#else
+#endif
+ break;
+ case 4: /* esp_out_gcm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ extseq = EVAL_extseq();
+ if (extseq == 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 3u;
+ }
+ *TokenWord32Count_p += 8u;
+#else
+#endif
+ break;
+ case 5: /* esp_in_gcm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ extseq = EVAL_extseq();
+ if (extseq != 1u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 4u;
+ }
+ *TokenWord32Count_p += 2u;
+#if TKB_HAVE_ECN_FIXUP == 1u
+ *TokenWord32Count_p += 1u;
+#endif
+ *TokenWord32Count_p += 3u;
+#else
+#endif
+ break;
+ case 6: /* esp_out_gmac */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ extseq = EVAL_extseq();
+ if (extseq == 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 3u;
+ }
+ *TokenWord32Count_p += 8u;
+#else
+#endif
+ break;
+ case 7: /* esp_in_gmac */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ extseq = EVAL_extseq();
+ if (extseq != 1u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 4u;
+ }
+ *TokenWord32Count_p += 2u;
+#if TKB_HAVE_ECN_FIXUP == 1u
+ *TokenWord32Count_p += 1u;
+#endif
+ *TokenWord32Count_p += 3u;
+#else
+#endif
+ break;
+ case 8: /* ssltls_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ capwap_out = EVAL_capwap_out();
+ if (capwap_out != 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ *TokenWord32Count_p += 3u;
+ antireplay = EVAL_antireplay();
+ if (antireplay != 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ extseq = EVAL_extseq();
+ if (extseq != 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ *TokenWord32Count_p += 6u;
+ upd_handling = EVAL_upd_handling();
+ switch(upd_handling)
+ {
+ case 0: /* upd_null */
+ *TokenWord32Count_p += 3u;
+ break;
+ case 1: /* upd_arc4 */
+ *TokenWord32Count_p += 4u;
+ break;
+ case 2: /* upd_iv2 */
+ *TokenWord32Count_p += 1u;
+ if (antireplay != 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 2u;
+ break;
+ case 3: /* upd_iv4 */
+ *TokenWord32Count_p += 1u;
+ if (antireplay != 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 2u;
+ break;
+ case 4: /* upd_blk */
+ *TokenWord32Count_p += 4u;
+ break;
+ }
+#else
+#endif
+ break;
+ case 9: /* ssltls_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ upd_handling = EVAL_upd_handling();
+ if (upd_handling <= 1u)
+ {
+ *TokenWord32Count_p += 3u;
+ extseq = EVAL_extseq();
+ if (extseq != 0u)
+ {
+ *TokenWord32Count_p += 7u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 2u;
+ antireplay = EVAL_antireplay();
+ if (antireplay != 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ *TokenWord32Count_p += 2u;
+ }
+ *TokenWord32Count_p += 3u;
+ switch(upd_handling)
+ {
+ case 0: /* upd_null */
+ *TokenWord32Count_p += 1u;
+ if (extseq == 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else if (extseq == 1u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ break;
+ case 1: /* upd_arc4 */
+ *TokenWord32Count_p += 5u;
+ break;
+ }
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ cipher_is_aes = EVAL_cipher_is_aes();
+ if (cipher_is_aes == 0u)
+ {
+ *TokenWord32Count_p += 6u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 10u;
+ }
+ *TokenWord32Count_p += 3u;
+ extseq = EVAL_extseq();
+ if (extseq != 0u)
+ {
+ *TokenWord32Count_p += 6u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 3u;
+ antireplay = EVAL_antireplay();
+ if (antireplay != 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 1u;
+ ivlen = EVAL_ivlen();
+ if (ivlen > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 3u;
+ switch(upd_handling)
+ {
+ case 2: /* upd_iv2 */
+ antireplay = EVAL_antireplay();
+ if (antireplay != 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 2u;
+ break;
+ case 3: /* upd_iv4 */
+ antireplay = EVAL_antireplay();
+ if (antireplay != 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 2u;
+ break;
+ case 4: /* upd_blk */
+ if (extseq == 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else if (extseq == 1u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ break;
+ }
+ }
+#else
+#endif
+ break;
+ case 21: /* ssltls_gcm_out */
+ case 37: /* ssltls_chachapoly_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ capwap_out = EVAL_capwap_out();
+ if (capwap_out != 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ *TokenWord32Count_p += 4u;
+ extseq = EVAL_extseq();
+ if (extseq != 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ *TokenWord32Count_p += 5u;
+ if (proto != 37u)
+ {
+ if (extseq != 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 4u;
+#else
+#endif
+ break;
+ case 22: /* ssltls_gcm_in */
+ case 38: /* ssltls_chachapoly_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ *TokenWord32Count_p += 11u;
+ if (proto != 38u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else
+ {
+#if TKB_HAVE_CHACHAPOLY_HW30 == 1u
+ *TokenWord32Count_p += 1u;
+#else
+ *TokenWord32Count_p += 1u;
+#endif
+ }
+ *TokenWord32Count_p += 2u;
+ extseq = EVAL_extseq();
+ if (extseq == 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else if (extseq == 1u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 2u;
+ }
+#else
+#endif
+ break;
+ case 10: /* basic_crypto */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ switch(ivhandling)
+ {
+ case 0: /* iv_inbound_ctr */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 1: /* iv_inbound_cbc */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 2: /* iv_outbound_ctr */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 5: /* iv_copy_ctr */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 4: /* iv_copy_cbc */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 6: /* iv_outbound_2words */
+ case 9: /* iv_copy_token_2words */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 7: /* iv_outbound_4words */
+ case 15: /* iv_copy_token_4words */
+ *TokenWord32Count_p += 1u;
+ break;
+ }
+ *TokenWord32Count_p += 2u;
+ upd_handling = EVAL_upd_handling();
+ switch(upd_handling)
+ {
+ case 0: /* upd_null */
+ break;
+ case 1: /* upd_arc4 */
+ *TokenWord32Count_p += 2u;
+ break;
+ case 2: /* upd_iv2 */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 3: /* upd_iv4 */
+ *TokenWord32Count_p += 1u;
+ break;
+ }
+#else
+#endif
+ break;
+ case 11: /* basic_hash */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ *TokenWord32Count_p += 17u;
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 2u;
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ hstatelen = EVAL_hstatelen();
+ if (hstatelen > 16u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ }
+#else
+#endif
+ break;
+ case 14: /* basic_crypthash */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ *TokenWord32Count_p += 17u;
+ switch(ivhandling)
+ {
+ case 0: /* iv_inbound_ctr */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 1: /* iv_inbound_cbc */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 2: /* iv_outbound_ctr */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 5: /* iv_copy_ctr */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 4: /* iv_copy_cbc */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 6: /* iv_outbound_2words */
+ case 9: /* iv_copy_token_2words */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 7: /* iv_outbound_4words */
+ case 15: /* iv_copy_token_4words */
+ *TokenWord32Count_p += 1u;
+ break;
+ }
+ *TokenWord32Count_p += 4u;
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ hstatelen = EVAL_hstatelen();
+ if (hstatelen > 16u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ }
+ upd_handling = EVAL_upd_handling();
+ switch(upd_handling)
+ {
+ case 0: /* upd_null */
+ break;
+ case 1: /* upd_arc4 */
+ *TokenWord32Count_p += 2u;
+ break;
+ case 2: /* upd_iv2 */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 3: /* upd_iv4 */
+ *TokenWord32Count_p += 1u;
+ break;
+ }
+#else
+#endif
+ break;
+ case 15: /* basic_out_ccm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ *TokenWord32Count_p += 2u;
+ if (ivhandling == 5u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 25u;
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+#else
+#endif
+ break;
+ case 16: /* basic_in_ccm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ *TokenWord32Count_p += 2u;
+ if (ivhandling == 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 25u;
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 2u;
+ }
+#else
+#endif
+ break;
+ case 17: /* basic_out_gcm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ *TokenWord32Count_p += 17u;
+ switch(ivhandling)
+ {
+ case 0: /* iv_inbound_ctr */
+ *TokenWord32Count_p += 2u;
+ break;
+ case 5: /* iv_copy_ctr */
+ *TokenWord32Count_p += 2u;
+ break;
+ case 15: /* iv_copy_token_4words */
+ case 2: /* iv_outbound_ctr */
+ *TokenWord32Count_p += 2u;
+ break;
+ default:
+ *TokenWord32Count_p += 1u;
+ ;
+ }
+ *TokenWord32Count_p += 2u;
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+#else
+#endif
+ break;
+ case 18: /* basic_in_gcm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ *TokenWord32Count_p += 17u;
+ switch(ivhandling)
+ {
+ case 0: /* iv_inbound_ctr */
+ *TokenWord32Count_p += 2u;
+ break;
+ case 5: /* iv_copy_ctr */
+ *TokenWord32Count_p += 2u;
+ break;
+ case 15: /* iv_copy_token_4words */
+ case 2: /* iv_outbound_ctr */
+ *TokenWord32Count_p += 2u;
+ break;
+ default:
+ *TokenWord32Count_p += 1u;
+ ;
+ }
+ *TokenWord32Count_p += 2u;
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 2u;
+ }
+#else
+#endif
+ break;
+ case 19: /* basic_out_gmac */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ *TokenWord32Count_p += 17u;
+ switch(ivhandling)
+ {
+ case 0: /* iv_inbound_ctr */
+ *TokenWord32Count_p += 3u;
+ break;
+ case 5: /* iv_copy_ctr */
+ *TokenWord32Count_p += 3u;
+ break;
+ case 15: /* iv_copy_token_4words */
+ case 2: /* iv_outbound_ctr */
+ *TokenWord32Count_p += 3u;
+ break;
+ default:
+ *TokenWord32Count_p += 2u;
+ ;
+ }
+ *TokenWord32Count_p += 1u;
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+#else
+#endif
+ break;
+ case 20: /* basic_in_gmac */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ *TokenWord32Count_p += 17u;
+ switch(ivhandling)
+ {
+ case 0: /* iv_inbound_ctr */
+ *TokenWord32Count_p += 3u;
+ break;
+ case 5: /* iv_copy_ctr */
+ *TokenWord32Count_p += 3u;
+ break;
+ case 15: /* iv_copy_token_4words */
+ case 2: /* iv_outbound_ctr */
+ *TokenWord32Count_p += 3u;
+ break;
+ default:
+ *TokenWord32Count_p += 2u;
+ ;
+ }
+ *TokenWord32Count_p += 1u;
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 2u;
+ }
+#else
+#endif
+ break;
+ case 23: /* basic_xts_crypto */
+#if TKB_HAVE_CRYPTO_XTS == 1u
+ *TokenWord32Count_p += 5u;
+ switch(ivhandling)
+ {
+ case 1: /* iv_inbound_cbc */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 4: /* iv_copy_cbc */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 7: /* iv_outbound_4words */
+ case 15: /* iv_copy_token_4words */
+ *TokenWord32Count_p += 1u;
+ break;
+ }
+ *TokenWord32Count_p += 2u;
+ upd_handling = EVAL_upd_handling();
+ switch(upd_handling)
+ {
+ case 0: /* upd_null */
+ break;
+ case 3: /* upd_iv4 */
+ *TokenWord32Count_p += 1u;
+ break;
+ }
+#else
+#endif
+ break;
+ case 24: /* basic_kasumi_hash */
+#if TKB_HAVE_CRYPTO_WIRELESS == 1u
+ *TokenWord32Count_p += 3u;
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 2u;
+#else
+#endif
+ break;
+ case 25: /* basic_snow_hash */
+ case 26: /* basic_zuc_hash */
+#if TKB_HAVE_CRYPTO_WIRELESS == 1u
+ *TokenWord32Count_p += 5u;
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 2u;
+#else
+#endif
+ break;
+ case 27: /* basic_hashenc */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ *TokenWord32Count_p += 17u;
+ switch(ivhandling)
+ {
+ case 4: /* iv_copy_cbc */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 6: /* iv_outbound_2words */
+ case 9: /* iv_copy_token_2words */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 7: /* iv_outbound_4words */
+ case 15: /* iv_copy_token_4words */
+ *TokenWord32Count_p += 1u;
+ break;
+ }
+ *TokenWord32Count_p += 3u;
+#else
+#endif
+ break;
+ case 28: /* basic_dechash */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ *TokenWord32Count_p += 1u;
+ cipher_is_aes = EVAL_cipher_is_aes();
+ if (cipher_is_aes == 0u)
+ {
+ *TokenWord32Count_p += 6u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 10u;
+ }
+ *TokenWord32Count_p += 21u;
+ ivlen = EVAL_ivlen();
+ if (ivlen > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 4u;
+#else
+#endif
+ break;
+ case 12: /* srtp_out */
+#if TKB_HAVE_PROTO_SRTP == 1u
+ *TokenWord32Count_p += 2u;
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 1u;
+ antireplay = EVAL_antireplay();
+ if (antireplay > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 1u;
+#else
+#endif
+ break;
+ case 13: /* srtp_in */
+#if TKB_HAVE_PROTO_SRTP == 1u
+ *TokenWord32Count_p += 2u;
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ antireplay = EVAL_antireplay();
+ if (antireplay > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ icvlen = EVAL_icvlen();
+ if (icvlen > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ if (antireplay > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ if (antireplay > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ }
+#else
+#endif
+ break;
+ case 29: /* basic_out_chachapoly */
+#if TKB_HAVE_PROTO_BASIC == 1u
+#if TKB_HAVE_CRYPTO_CHACHAPOLY == 1u
+ *TokenWord32Count_p += 19u;
+#else
+#endif
+#else
+#endif
+ break;
+ case 30: /* basic_in_chachapoly */
+#if TKB_HAVE_PROTO_BASIC == 1u
+#if TKB_HAVE_CRYPTO_CHACHAPOLY == 1u
+ *TokenWord32Count_p += 17u;
+#if TKB_HAVE_CHACHAPOLY_HW30 == 1u
+ *TokenWord32Count_p += 1u;
+#else
+ *TokenWord32Count_p += 1u;
+#endif
+ *TokenWord32Count_p += 3u;
+#else
+#endif
+#else
+#endif
+ break;
+ case 31: /* tls13_gcm_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ *TokenWord32Count_p += 12u;
+#else
+#endif
+ break;
+ case 32: /* tls13_gcm_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ *TokenWord32Count_p += 7u;
+#else
+#endif
+ break;
+ case 33: /* tls13_chachapoly_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ *TokenWord32Count_p += 10u;
+#else
+#endif
+ break;
+ case 34: /* tls13_chachapoly_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ *TokenWord32Count_p += 6u;
+#else
+#endif
+ break;
+ case 35: /* esp_out_chachapoly */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ extseq = EVAL_extseq();
+ if (extseq == 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 3u;
+ }
+ *TokenWord32Count_p += 6u;
+#else
+#endif
+ break;
+ case 36: /* esp_in_chachapoly */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ extseq = EVAL_extseq();
+ if (extseq != 1u)
+ {
+ *TokenWord32Count_p += 2u;
+#if TKB_HAVE_ECN_FIXUP == 1u
+ *TokenWord32Count_p += 1u;
+#endif
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 5u;
+#if TKB_HAVE_ECN_FIXUP == 1u
+ *TokenWord32Count_p += 1u;
+#endif
+#if TKB_HAVE_CHACHAPOLY_HW30 == 1u
+ *TokenWord32Count_p += 1u;
+#else
+ *TokenWord32Count_p += 1u;
+#endif
+ }
+ *TokenWord32Count_p += 2u;
+#else
+#endif
+ break;
+ case 39: /* ssltls_ccm_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ *TokenWord32Count_p += 1u;
+ capwap_out = EVAL_capwap_out();
+ if (capwap_out != 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ *TokenWord32Count_p += 11u;
+ extseq = EVAL_extseq();
+ if (extseq != 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ *TokenWord32Count_p += 6u;
+ if (extseq != 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ *TokenWord32Count_p += 6u;
+#else
+#endif
+ break;
+ case 40: /* ssltls_ccm_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ *TokenWord32Count_p += 24u;
+ extseq = EVAL_extseq();
+ if (extseq == 0u)
+ {
+ *TokenWord32Count_p += 2u;
+ }
+ else if (extseq == 1u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 2u;
+ }
+#else
+#endif
+ break;
+ case 41: /* tls13_ccm_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ *TokenWord32Count_p += 19u;
+#else
+#endif
+ break;
+ case 42: /* tls13_ccm_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ *TokenWord32Count_p += 14u;
+#else
+#endif
+ break;
+ case 43: /* basic_hmac_precompute */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ *TokenWord32Count_p += 4u;
+#else
+#endif
+ break;
+ case 44: /* basic_hmac_ctxprepare */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ *TokenWord32Count_p += 6u;
+#else
+#endif
+ break;
+ case 45: /* basic_bypass */
+ *TokenWord32Count_p += 1u;
+ break;
+ default:
+ ;
+ }
+#if TKB_HAVE_PROTO_IPSEC == 1u
+#if TKB_HAVE_EXTENDED_IPSEC == 1u
+ hproto = EVAL_hproto();
+ switch(hproto)
+ {
+ case 6: /* ipv4_in_transp */
+ case 26: /* ipv4_in_transp_natt */
+ *TokenWord32Count_p += 1u;
+ break;
+ case 12: /* ipv6_in_transp */
+ case 32: /* ipv6_in_transp_natt */
+ *TokenWord32Count_p += 2u;
+ break;
+ }
+#endif
+ switch(proto)
+ {
+ case 1: /* esp_in */
+ case 3: /* esp_in_ccm */
+ case 5: /* esp_in_gcm */
+ case 7: /* esp_in_gmac */
+ case 36: /* esp_in_chachapoly */
+ icvlen = EVAL_icvlen();
+ if (icvlen > 0u)
+ {
+ antireplay = EVAL_antireplay();
+ if (antireplay > 12u)
+ {
+ *TokenWord32Count_p += 1u;
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ }
+ else if (antireplay != 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ }
+ else
+ {
+ *TokenWord32Count_p += 1u;
+ }
+ break;
+ }
+#endif
+
+
+ if (Switch_Proto(TokenContext_Internal_p))
+ {
+ /* Protocol was switched (HMAC context prepare to original protocol),
+ redo size computation with original protocol.*/
+ WordCountOld = *TokenWord32Count_p;
+ goto redo;
+ }
+ *TokenWord32Count_p = MAX(*TokenWord32Count_p, WordCountOld);
+
+ return TKB_STATUS_OK;
+}
+
+
+TokenBuilder_Status_t
+TokenBuilder_BuildToken(
+ void * const TokenContext_p,
+ const uint8_t *const Packet_p,
+ const uint32_t PacketByteCount,
+ TokenBuilder_Params_t * const TKBParams_p,
+ void * const Token_p,
+ uint32_t * const TokenWord32Count_p,
+ uint32_t * const TokenHeaderWord_p)
+{
+ uint32_t *tp = (uint32_t*)Token_p;
+ uint32_t rc = TKB_STATUS_OK;
+ TokenBuilder_Context_t *TokenContext_Internal_p =
+ (TokenBuilder_Context_t*)TokenContext_p;
+ uint32_t proto;
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ uint32_t hproto;
+#endif
+ uint32_t packetsize;
+ uint32_t bypass;
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t nextheader;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ uint32_t pad_remainder;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ uint32_t pad_blocksize;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t pad_bytes;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t seq_offset;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_XTS == 1u
+ uint32_t iv_offset;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t digest_offset;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_XTS == 1u
+ uint32_t ivlen;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_WIRELESS == 1u || TKB_HAVE_PROTO_SRTP == 1u
+ uint32_t icvlen;
+#endif
+ uint32_t ivhandling;
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_WIRELESS == 1u || TKB_HAVE_PROTO_SRTP == 1u
+ uint32_t extseq;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t salt;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t basic_salt;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t paylen;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t swaplen;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t swap_fraglen;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t swap_fraglen_tls13;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t swaplen3;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t swaplen3_tls13_out;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t swaplen3_tls13_in;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t hashpad_tls13_out;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t hashpad_tls13_in;
+#endif
+#if TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t hashpad;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t aadlen_pkt;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t aadlen_tkn;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t aadlen_out;
+#endif
+#if TKB_HAVE_CRYPTO_XTS == 1u
+ uint32_t swap_j;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t basic_swaplen;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t aadlen_swap;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t aadpad;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t basic_hashpad;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_WIRELESS == 1u || TKB_HAVE_PROTO_SRTP == 1u || TKB_HAVE_PROTO_IPSEC == 1u
+ uint32_t antireplay;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_XTS == 1u
+ uint32_t upd_handling;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t cipher_is_aes;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_WIRELESS == 1u
+ uint32_t appendhash;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u || TKB_HAVE_CRYPTO_XTS == 1u
+ uint32_t pad_bytes_basic;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t hstatelen;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t capwap_out;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t capwap_in;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t hstatelen_bytes;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ uint32_t pad_bytes_hashenc;
+#endif
+#if TKB_HAVE_PROTO_SRTP == 1u
+ uint32_t srtp_offset;
+#endif
+#if TKB_HAVE_PROTO_SRTP == 1u
+ uint32_t srtp_swaproc;
+#endif
+ uint32_t srtp_iv0;
+ uint32_t srtp_iv1;
+ uint32_t srtp_iv2;
+ uint32_t srtp_iv3;
+ uint32_t count;
+ uint32_t bearer_dir_fresh;
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ uint32_t prev_nhoffset;
+#endif
+ uint32_t hdrlen;
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u) || TKB_HAVE_PROTO_IPSEC == 1u || TKB_HAVE_PROTO_SSLTLS == 1u
+ uint32_t ohdrlen;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ uint32_t outlen;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ uint32_t nh;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ uint32_t is_nat;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ uint32_t tunnel_w0_ip4;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ uint32_t tunnel_w1_ip4;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ uint32_t tunnel_w2_ip4;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ uint32_t tunnel_w0_ip6;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ uint32_t tunnel_w1_ip6;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ const uint8_t *tunnel_ip_addr;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ const uint8_t *dst_ip_addr;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_EXTENDED_IPSEC == 1u)
+ uint32_t ports_natt;
+#endif
+#if (TKB_HAVE_PROTO_IPSEC == 1u && TKB_HAVE_ECN_FIXUP == 1u)
+ uint32_t ecn_fixup_instr;
+#endif
+ uint32_t per_packet_options;
+ uint32_t u_word;
+ uint32_t cw0;
+ uint32_t cw1;
+ const uint8_t *iv;
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u
+ const uint8_t *ssltls_lastblock;
+#endif
+#if TKB_HAVE_PROTO_SSLTLS == 1u || TKB_HAVE_PROTO_BASIC == 1u
+ const uint8_t *ssltls_lastword;
+#endif
+#if TKB_HAVE_PROTO_BASIC == 1u
+ const uint8_t *aad;
+#endif
+
+ IDENTIFIER_NOT_USED(Packet_p);
+#ifdef TKB_STRICT_ARGS_CHECK
+ if (Token_p == NULL ||
+ TokenWord32Count_p == NULL ||
+ (TokenHeaderWord_p == NULL && TKB_TOKEN_HEADER_WORD_COUNT == 0))
+ {
+ LOG_CRIT("TokenBuilder: NULL pointer supplied\n");
+ return TKB_INVALID_PARAMETER;
+ }
+#endif
+ if (TokenContext_p == NULL)
+ {
+ rc = TKB_ERROR;
+ TKBParams_p->CLE = 2;
+ goto error;
+ }
+
+ if (TokenHeaderWord_p != NULL)
+ *TokenHeaderWord_p = EVAL_TokenHeaderWord();
+#if TKB_TOKEN_HEADER_WORD_COUNT > 0
+ {
+ unsigned int i;
+ *tp++ = EVAL_TokenHeaderWord();
+ for (i = 0; i < TKB_TOKEN_HEADER_WORD_COUNT - 1; i++)
+ {
+ *tp++ = 0;
+ }
+ }
+#endif
+
+ per_packet_options = EVAL_per_packet_options();
+ if (per_packet_options != 0u)
+ {
+ /* DATA32 cw0 + per_packet_options */
+ cw0 = EVAL_cw0();
+ *tp++=0x00000000 | ((cw0+per_packet_options)&0xffffffffu)<<0;
+ /* DATA32 cw1 */
+ cw1 = EVAL_cw1();
+ *tp++=0x00000000 | ((cw1)&0xffffffffu)<<0;
+ }
+ bypass = EVAL_bypass();
+ hdrlen = EVAL_hdrlen();
+ if (hdrlen == 4294967295u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, ip header parse error\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ proto = EVAL_proto();
+ u_word = EVAL_u_word();
+ if (u_word != 0u)
+ {
+ /* DATA32 u_word */
+ *tp++=0x00000000 | ((u_word)&0xffffffffu)<<0;
+ }
+ ivhandling = EVAL_ivhandling();
+ if (ivhandling >= 8u)
+ {
+ if (ivhandling < 10u)
+ {
+ iv = EVAL_iv();
+ TokenBuilder_CopyBytes(tp, iv, 8);
+ tp += 2;
+ }
+ else if (ivhandling > 13u)
+ {
+ iv = EVAL_iv();
+ TokenBuilder_CopyBytes(tp, iv, 16);
+ tp += 4;
+ }
+ else if (ivhandling == 10u)
+ {
+ /* DATA32 srtp_iv0 */
+ srtp_iv0 = EVAL_srtp_iv0();
+ *tp++=0x00000000 | ((srtp_iv0)&0xffffffffu)<<0;
+ /* DATA32 srtp_iv1 */
+ srtp_iv1 = EVAL_srtp_iv1();
+ *tp++=0x00000000 | ((srtp_iv1)&0xffffffffu)<<0;
+ /* DATA32 srtp_iv2 */
+ srtp_iv2 = EVAL_srtp_iv2();
+ *tp++=0x00000000 | ((srtp_iv2)&0xffffffffu)<<0;
+ /* DATA32 srtp_iv3 */
+ srtp_iv3 = EVAL_srtp_iv3();
+ *tp++=0x00000000 | ((srtp_iv3)&0xffffffffu)<<0;
+ }
+ else if (ivhandling == 11u)
+ {
+ /* DATA32 count */
+ count = EVAL_count();
+ *tp++=0x00000000 | ((count)&0xffffffffu)<<0;
+ /* DATA32 bearer_dir_fresh */
+ bearer_dir_fresh = EVAL_bearer_dir_fresh();
+ *tp++=0x00000000 | ((bearer_dir_fresh)&0xffffffffu)<<0;
+ }
+ else
+ {
+ /* DATA32 count */
+ count = EVAL_count();
+ *tp++=0x00000000 | ((count)&0xffffffffu)<<0;
+ /* DATA32 bearer_dir_fresh */
+ bearer_dir_fresh = EVAL_bearer_dir_fresh();
+ *tp++=0x00000000 | ((bearer_dir_fresh)&0xffffffffu)<<0;
+ /* DATA32 count */
+ *tp++=0x00000000 | ((count)&0xffffffffu)<<0;
+ /* DATA32 bearer_dir_fresh */
+ *tp++=0x00000000 | ((bearer_dir_fresh)&0xffffffffu)<<0;
+ }
+ }
+ if (bypass > 0u)
+ {
+ if (proto != 9u)
+ {
+ if (proto != 28u)
+ {
+ /* DIR OUT,bypass */
+ *tp++=0x01000000 | ((bypass)&0x1ffffu)<<0;
+ }
+ }
+ }
+ packetsize = EVAL_packetsize();
+ if (packetsize > 131071u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too long\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+#if TKB_HAVE_PROTO_IPSEC == 1u
+#if TKB_HAVE_EXTENDED_IPSEC == 1u
+ hproto = EVAL_hproto();
+ switch(hproto)
+ {
+ case 5: /* ipv4_out_transp */
+ /* IPV4CHK OUT,50,outlen */
+ outlen = EVAL_outlen();
+ *tp++=0x61000000 | ((50u)&0xffu)<<16 | ((outlen)&0xffffu)<<0;
+ /* DIR OUT,hdrlen-12 */
+ *tp++=0x01000000 | ((-12u+hdrlen)&0x1ffffu)<<0;
+ break;
+ case 1: /* ipv4_out_transp_nohdrproc */
+ /* DIR OUT,hdrlen */
+ *tp++=0x01000000 | ((hdrlen)&0x1ffffu)<<0;
+ break;
+ case 11: /* ipv6_out_transp */
+ if (hdrlen > 40u)
+ {
+ /* IPV6 OUT,nh,outlen-40 */
+ nh = EVAL_nh();
+ outlen = EVAL_outlen();
+ *tp++=0x81000000 | ((nh)&0xffu)<<16 | ((-40u+outlen)&0xffffu)<<0;
+ /* DIR OUT,prev_nhoffset-8 ; -8 to include two 32-bit words of the IPv6 header passed via IPV6 instruction */
+ prev_nhoffset = EVAL_prev_nhoffset();
+ *tp++=0x01000000 | ((-8u+prev_nhoffset)&0x1ffffu)<<0;
+ /* REPL OUT,ORIG_TOKEN,1 ; replace NH byte of the last extension header with ESP type */
+ *tp++=0x31d80000 | ((1u)&0x1ffffu)<<0;
+ /* DATA32 50 ; ESP proto */
+ *tp++=0x00000000 | ((50u)&0xffffffffu)<<0;
+ /* DIR OUT,hdrlen-prev_nhoffset-1 ; bypass the rest of the last extension header */
+ *tp++=0x01000000 | ((-1u+hdrlen-prev_nhoffset)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* IPV6 OUT,50,outlen-hdrlen */
+ outlen = EVAL_outlen();
+ *tp++=0x81000000 | ((50u)&0xffu)<<16 | ((outlen-hdrlen)&0xffffu)<<0;
+ /* DIR OUT,hdrlen-8 */
+ *tp++=0x01000000 | ((-8u+hdrlen)&0x1ffffu)<<0;
+ }
+ break;
+ case 2: /* ipv4_out_tunnel */
+ /* INS OUT,ORIG_TOKEN,20 */
+ *tp++=0x21d80000 | ((20u)&0x1ffffu)<<0;
+ /* DATA32 tunnel_w0_ip4 */
+ tunnel_w0_ip4 = EVAL_tunnel_w0_ip4();
+ *tp++=0x00000000 | ((tunnel_w0_ip4)&0xffffffffu)<<0;
+ /* DATA32 tunnel_w1_ip4 */
+ tunnel_w1_ip4 = EVAL_tunnel_w1_ip4();
+ *tp++=0x00000000 | ((tunnel_w1_ip4)&0xffffffffu)<<0;
+ /* DATA32 tunnel_w2_ip4 */
+ tunnel_w2_ip4 = EVAL_tunnel_w2_ip4();
+ *tp++=0x00000000 | ((tunnel_w2_ip4)&0xffffffffu)<<0;
+ tunnel_ip_addr = EVAL_tunnel_ip_addr();
+ TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 8);
+ tp += 2;
+ break;
+ case 7: /* ipv6_out_tunnel */
+ /* INS OUT,ORIG_TOKEN,40 */
+ *tp++=0x21d80000 | ((40u)&0x1ffffu)<<0;
+ /* DATA32 tunnel_w0_ip6 */
+ tunnel_w0_ip6 = EVAL_tunnel_w0_ip6();
+ *tp++=0x00000000 | ((tunnel_w0_ip6)&0xffffffffu)<<0;
+ /* DATA32 tunnel_w1_ip6 */
+ tunnel_w1_ip6 = EVAL_tunnel_w1_ip6();
+ *tp++=0x00000000 | ((tunnel_w1_ip6)&0xffffffffu)<<0;
+ tunnel_ip_addr = EVAL_tunnel_ip_addr();
+ TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 32);
+ tp += 8;
+ break;
+ case 6: /* ipv4_in_transp */
+ /* IPV4CHK OUT,0,0 */
+ *tp++=0x61000000 | ((0u)&0xffu)<<16 | ((0u)&0xffffu)<<0;
+ /* DIR OUT,hdrlen-12 */
+ *tp++=0x01000000 | ((-12u+hdrlen)&0x1ffffu)<<0;
+ break;
+ case 3: /* ipv4_in_transp_nohdrproc */
+ /* DIR OUT, hdrlen */
+ *tp++=0x01000000 | ((hdrlen)&0x1ffffu)<<0;
+ break;
+ case 12: /* ipv6_in_transp */
+ nh = EVAL_nh();
+ if (nh == 50u)
+ {
+ /* IPV6 OUT,00,00 ; zeroise the NH and payload length */
+ *tp++=0x81000000 | ((0u)&0xffu)<<16 | ((0u)&0xffffu)<<0;
+ /* DIR OUT,hdrlen-8 ; pass the remaining header words */
+ *tp++=0x01000000 | ((-8u+hdrlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* IPV6 OUT,nh,00 ; bypass NH, but zeroise the payload length */
+ *tp++=0x81000000 | ((nh)&0xffu)<<16 | ((0u)&0xffffu)<<0;
+ /* DIR OUT,prev_nhoffset-8 ; pass the remaining data until the next header of the last extentnio header */
+ prev_nhoffset = EVAL_prev_nhoffset();
+ *tp++=0x01000000 | ((-8u+prev_nhoffset)&0x1ffffu)<<0;
+ /* REPL OUT,ORIG_TOKEN,1 ; zeroize the NH field */
+ *tp++=0x31d80000 | ((1u)&0x1ffffu)<<0;
+ /* DATA32 00 ; */
+ *tp++=0x00000000 | ((0u)&0xffffffffu)<<0;
+ /* DIR OUT,hdrlen-prev_nhoffset-1 ; bypass the rest of the last extension header */
+ *tp++=0x01000000 | ((-1u+hdrlen-prev_nhoffset)&0x1ffffu)<<0;
+ }
+ break;
+ case 4: /* ipv4_in_tunnel */
+ case 8: /* ipv6_in_tunnel */
+ case 24: /* ipv4_in_tunnel_natt */
+ case 28: /* ipv6_in_tunnel_natt */
+ /* DIR OUT, ohdrlen ; keep (optionally) outer IP heade */
+ ohdrlen = EVAL_ohdrlen();
+ *tp++=0x01000000 | ((ohdrlen)&0x1ffffu)<<0;
+ /* REM hdrlen-ohdrlen ; remobe IP header (optionally) and NATT header. */
+ *tp++=0x40d80000 | ((hdrlen-ohdrlen)&0x1ffffu)<<0;
+ break;
+ case 25: /* ipv4_out_transp_natt */
+ /* IPV4CHK OUT,17,outlen ; include 8 byte of NAT-T */
+ outlen = EVAL_outlen();
+ *tp++=0x61000000 | ((17u)&0xffu)<<16 | ((outlen)&0xffffu)<<0;
+ is_nat = EVAL_is_nat();
+ if (is_nat != 0u)
+ {
+ /* REPL OUT,ORIG_TOKEN,8 */
+ *tp++=0x31d80000 | ((8u)&0x1ffffu)<<0;
+ tunnel_ip_addr = EVAL_tunnel_ip_addr();
+ TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 8);
+ tp += 2;
+ /* DIR OUT,hdrlen-20 */
+ *tp++=0x01000000 | ((-20u+hdrlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR OUT,hdrlen-12 */
+ *tp++=0x01000000 | ((-12u+hdrlen)&0x1ffffu)<<0;
+ }
+ /* INS OUT,ORIG_TOKEN,8 */
+ *tp++=0x21d80000 | ((8u)&0x1ffffu)<<0;
+ /* DATA32 ports_natt */
+ ports_natt = EVAL_ports_natt();
+ *tp++=0x00000000 | ((ports_natt)&0xffffffffu)<<0;
+ /* SWAP16 outlen - hdrlen ; include 8 byte of NAT-T */
+ *tp++ = ByteSwap16(outlen-hdrlen);
+ break;
+ case 31: /* ipv6_out_transp_natt */
+ if (hdrlen > 40u)
+ {
+ /* IPV6 OUT,nh,outlen-40 ; include 8 bytes of NAT-T */
+ nh = EVAL_nh();
+ outlen = EVAL_outlen();
+ *tp++=0x81000000 | ((nh)&0xffu)<<16 | ((-40u+outlen)&0xffffu)<<0;
+ is_nat = EVAL_is_nat();
+ if (is_nat != 0u)
+ {
+ /* REPL OUT,ORIG_TOKEN,32 */
+ *tp++=0x31d80000 | ((32u)&0x1ffffu)<<0;
+ tunnel_ip_addr = EVAL_tunnel_ip_addr();
+ TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 32);
+ tp += 8;
+ /* DIR OUT,prev_nhoffset-40 */
+ prev_nhoffset = EVAL_prev_nhoffset();
+ *tp++=0x01000000 | ((-40u+prev_nhoffset)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR OUT,prev_nhoffset-8 ; -8 to include two 32-bit words of the IPv6 header passed via IPV6 instruction */
+ prev_nhoffset = EVAL_prev_nhoffset();
+ *tp++=0x01000000 | ((-8u+prev_nhoffset)&0x1ffffu)<<0;
+ }
+ /* REPL OUT,ORIG_TOKEN,1 ; replace NH byte of the last extension header with UDP type */
+ *tp++=0x31d80000 | ((1u)&0x1ffffu)<<0;
+ /* DATA32 17 ; */
+ *tp++=0x00000000 | ((17u)&0xffffffffu)<<0;
+ /* DIR OUT,hdrlen-prev_nhoffset-1 ; bypass the rest data of the last extension header */
+ prev_nhoffset = EVAL_prev_nhoffset();
+ *tp++=0x01000000 | ((-1u+hdrlen-prev_nhoffset)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* IPV6 OUT,17,outlen-hdrlen ; include 8 bytes of NAT-T */
+ outlen = EVAL_outlen();
+ *tp++=0x81000000 | ((17u)&0xffu)<<16 | ((outlen-hdrlen)&0xffffu)<<0;
+ is_nat = EVAL_is_nat();
+ if (is_nat != 0u)
+ {
+ /* REPL OUT,ORIG_TOKEN,32 */
+ *tp++=0x31d80000 | ((32u)&0x1ffffu)<<0;
+ tunnel_ip_addr = EVAL_tunnel_ip_addr();
+ TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 32);
+ tp += 8;
+ /* DIR OUT,hdrlen-40 */
+ *tp++=0x01000000 | ((-40u+hdrlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR OUT,hdrlen-8 */
+ *tp++=0x01000000 | ((-8u+hdrlen)&0x1ffffu)<<0;
+ }
+ }
+ /* INS OUT,ORIG_TOKEN,8 */
+ *tp++=0x21d80000 | ((8u)&0x1ffffu)<<0;
+ /* DATA32 ports_natt */
+ ports_natt = EVAL_ports_natt();
+ *tp++=0x00000000 | ((ports_natt)&0xffffffffu)<<0;
+ outlen = EVAL_outlen();
+ /* SWAP16 outlen-hdrlen ; include 8 bytes of NAT-T */
+ *tp++ = ByteSwap16(outlen-hdrlen);
+ break;
+ case 22: /* ipv4_out_tunnel_natt */
+ /* INS OUT,ORIG_TOKEN,28 */
+ *tp++=0x21d80000 | ((28u)&0x1ffffu)<<0;
+ /* DATA32 tunnel_w0_ip4 */
+ tunnel_w0_ip4 = EVAL_tunnel_w0_ip4();
+ *tp++=0x00000000 | ((tunnel_w0_ip4)&0xffffffffu)<<0;
+ /* DATA32 tunnel_w1_ip4 */
+ tunnel_w1_ip4 = EVAL_tunnel_w1_ip4();
+ *tp++=0x00000000 | ((tunnel_w1_ip4)&0xffffffffu)<<0;
+ /* DATA32 tunnel_w2_ip4 */
+ tunnel_w2_ip4 = EVAL_tunnel_w2_ip4();
+ *tp++=0x00000000 | ((tunnel_w2_ip4)&0xffffffffu)<<0;
+ tunnel_ip_addr = EVAL_tunnel_ip_addr();
+ TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 8);
+ tp += 2;
+ /* DATA32 ports_natt */
+ ports_natt = EVAL_ports_natt();
+ *tp++=0x00000000 | ((ports_natt)&0xffffffffu)<<0;
+ outlen = EVAL_outlen();
+ ohdrlen = EVAL_ohdrlen();
+ /* SWAP16 outlen+8 - ohdrlen ; include 8 byte of NAT-T */
+ *tp++ = ByteSwap16(8u+outlen-ohdrlen);
+ break;
+ case 27: /* ipv6_out_tunnel_natt */
+ /* INS OUT,ORIG_TOKEN,48 */
+ *tp++=0x21d80000 | ((48u)&0x1ffffu)<<0;
+ /* DATA32 tunnel_w0_ip6 */
+ tunnel_w0_ip6 = EVAL_tunnel_w0_ip6();
+ *tp++=0x00000000 | ((tunnel_w0_ip6)&0xffffffffu)<<0;
+ /* DATA32 tunnel_w1_ip6 */
+ tunnel_w1_ip6 = EVAL_tunnel_w1_ip6();
+ *tp++=0x00000000 | ((tunnel_w1_ip6)&0xffffffffu)<<0;
+ tunnel_ip_addr = EVAL_tunnel_ip_addr();
+ TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 32);
+ tp += 8;
+ /* DATA32 ports_natt */
+ ports_natt = EVAL_ports_natt();
+ *tp++=0x00000000 | ((ports_natt)&0xffffffffu)<<0;
+ outlen = EVAL_outlen();
+ ohdrlen = EVAL_ohdrlen();
+ /* SWAP16 outlen+8 - ohdrlen ; include 8 byte of NAT-T */
+ *tp++ = ByteSwap16(8u+outlen-ohdrlen);
+ break;
+ case 26: /* ipv4_in_transp_natt */
+ /* IPV4CHK OUT,0,0 ; IP header update instruction */
+ *tp++=0x61000000 | ((0u)&0xffu)<<16 | ((0u)&0xffffu)<<0;
+ is_nat = EVAL_is_nat();
+ if (is_nat != 0u)
+ {
+ /* REPL OUT,ORIG_TOKEN,4 */
+ *tp++=0x31d80000 | ((4u)&0x1ffffu)<<0;
+ tunnel_ip_addr = EVAL_tunnel_ip_addr();
+ TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 4);
+ tp += 1;
+ /* REPL OUT,ORIG_TOKEN,4 */
+ *tp++=0x31d80000 | ((4u)&0x1ffffu)<<0;
+ dst_ip_addr = EVAL_dst_ip_addr();
+ TokenBuilder_CopyBytes(tp, dst_ip_addr, 4);
+ tp += 1;
+ /* DIR OUT,hdrlen-20-8 */
+ *tp++=0x01000000 | ((-28u+hdrlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR OUT,hdrlen-12-8 ; bypass the rest of IP header words */
+ *tp++=0x01000000 | ((-20u+hdrlen)&0x1ffffu)<<0;
+ }
+ /* REM 8 ; remove NAT-T UDP header */
+ *tp++=0x40d80000 | ((8u)&0x1ffffu)<<0;
+ break;
+ case 32: /* ipv6_in_transp_natt */
+ nh = EVAL_nh();
+ if (nh == 17u)
+ {
+ /* IPV6 OUT,00,00 ; bypass IPv6 header and zeroise length and protocol fields */
+ *tp++=0x81000000 | ((0u)&0xffu)<<16 | ((0u)&0xffffu)<<0;
+ is_nat = EVAL_is_nat();
+ if (is_nat != 0u)
+ {
+ /* REPL OUT,ORIG_TOKEN,32 */
+ *tp++=0x31d80000 | ((32u)&0x1ffffu)<<0;
+ tunnel_ip_addr = EVAL_tunnel_ip_addr();
+ TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 32);
+ tp += 8;
+ /* DIR OUT,hdrlen-40-8 */
+ *tp++=0x01000000 | ((-48u+hdrlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR OUT,hdrlen-8-8 ; bypass rest of the IPv6 header (hdrlen includes the UDP length) */
+ *tp++=0x01000000 | ((-16u+hdrlen)&0x1ffffu)<<0;
+ }
+ }
+ else
+ {
+ prev_nhoffset = EVAL_prev_nhoffset();
+ /* IPV6 OUT,nh,00 ; bypass IPv6 header and restore the next header */
+ *tp++=0x81000000 | ((nh)&0xffu)<<16 | ((0u)&0xffffu)<<0;
+ is_nat = EVAL_is_nat();
+ if (is_nat != 0u)
+ {
+ /* REPL OUT,ORIG_TOKEN,32 */
+ *tp++=0x31d80000 | ((32u)&0x1ffffu)<<0;
+ tunnel_ip_addr = EVAL_tunnel_ip_addr();
+ TokenBuilder_CopyBytes(tp, tunnel_ip_addr, 32);
+ tp += 8;
+ /* DIR OUT,prev_nhoffset-40 */
+ *tp++=0x01000000 | ((-40u+prev_nhoffset)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR OUT,prev_nhoffset-8 ; bypass rest of the IPv6 header (hdrlen includes the UDP length) */
+ *tp++=0x01000000 | ((-8u+prev_nhoffset)&0x1ffffu)<<0;
+ }
+ /* REPL OUT,ORIG_TOKEN,1 ; zeroise the NH byte of the last extension header */
+ *tp++=0x31d80000 | ((1u)&0x1ffffu)<<0;
+ /* DATA32 00 ; */
+ *tp++=0x00000000 | ((0u)&0xffffffffu)<<0;
+ /* DIR OUT,hdrlen-prev_nhoffset-1-8 ; bypass the rest data of the last extension header */
+ *tp++=0x01000000 | ((-9u+hdrlen-prev_nhoffset)&0x1ffffu)<<0;
+ }
+ /* REM 8 ; remove UDP NAT-T header */
+ *tp++=0x40d80000 | ((8u)&0x1ffffu)<<0;
+ break;
+ case 13: /* ipv4_out_dtls */
+ /* IPV4CHK OUT,nh,outlen+hdrlen */
+ nh = EVAL_nh();
+ outlen = EVAL_outlen();
+ *tp++=0x61000000 | ((nh)&0xffu)<<16 | ((outlen+hdrlen)&0xffffu)<<0;
+ if (nh == 136u)
+ {
+ /* DIR OUT,hdrlen-12 */
+ *tp++=0x01000000 | ((-12u+hdrlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR OUT, hdrlen-16 */
+ *tp++=0x01000000 | ((-16u+hdrlen)&0x1ffffu)<<0;
+ /* REPL OUT,ORIG_TOKEN,2 */
+ *tp++=0x31d80000 | ((2u)&0x1ffffu)<<0;
+ /* SWAP16 outlen+8 ; include 8 bytes UDP header */
+ *tp++ = ByteSwap16(8u+outlen);
+ /* DIR OUT,2 */
+ *tp++=0x01000000 | ((2u)&0x1ffffu)<<0;
+ }
+ break;
+ case 33: /* ipv6_out_dtls */
+ /* IPV6 OUT,prev_nhoffset,outlen+hdrlen-40 */
+ prev_nhoffset = EVAL_prev_nhoffset();
+ outlen = EVAL_outlen();
+ *tp++=0x81000000 | ((prev_nhoffset)&0xffu)<<16 | ((-40u+outlen+hdrlen)&0xffffu)<<0;
+ nh = EVAL_nh();
+ if (nh == 136u)
+ {
+ /* DIR OUT,hdrlen-8 */
+ *tp++=0x01000000 | ((-8u+hdrlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR OUT, hdrlen-12 */
+ *tp++=0x01000000 | ((-12u+hdrlen)&0x1ffffu)<<0;
+ /* REPL OUT,ORIG_TOKEN,2 */
+ *tp++=0x31d80000 | ((2u)&0x1ffffu)<<0;
+ /* SWAP16 outlen+8 ; include 8 bytes UDP header */
+ *tp++ = ByteSwap16(8u+outlen);
+ /* DIR OUT,2 */
+ *tp++=0x01000000 | ((2u)&0x1ffffu)<<0;
+ }
+ break;
+ }
+#endif
+#endif
+ switch(proto)
+ {
+ case 0: /* esp_out */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ if (packetsize <= bypass+hdrlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for ESP outbound\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ if (ivhandling == 2u)
+ {
+ /* INS HASH,ORIG_SPI,8 */
+ *tp++=0x23900000 | ((8u)&0x1ffffu)<<0;
+ /* INS HASH,ORIG_IV1,ivlen */
+ ivlen = EVAL_ivlen();
+ *tp++=0x23a80000 | ((ivlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASH,ORIG_SPI,8+ivlen */
+ ivlen = EVAL_ivlen();
+ *tp++=0x23900000 | ((8u+ivlen)&0x1ffffu)<<0;
+ }
+ /* DIR CRYPTHASH,packetsize-bypass-hdrlen */
+ *tp++=0x07000000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+ icvlen = EVAL_icvlen();
+ if (icvlen > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq == 0u)
+ {
+ /* INS CRYPTHASH,PAD_IPSEC,nextheader,pad_bytes,LAST,LASTHASH */
+ nextheader = EVAL_nextheader();
+ pad_bytes = EVAL_pad_bytes();
+ *tp++=0x2f220000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+ }
+ else
+ {
+ /* INS CRYPTHASH,PAD_IPSEC,nextheader,pad_bytes,LAST */
+ nextheader = EVAL_nextheader();
+ pad_bytes = EVAL_pad_bytes();
+ *tp++=0x2f200000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+ /* INS HASHONLY,ORIG_EXTSEQNUM_RES2,4,LASTHASH */
+ *tp++=0x224a0000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS CRYPT,PAD_IPSEC,nextheader,pad_bytes,LAST,LASTHASHPKT */
+ nextheader = EVAL_nextheader();
+ pad_bytes = EVAL_pad_bytes();
+ *tp++=0x2d260000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+ }
+ /* VERIFY 0 ; Causes any sequence number rollover error to fail the packet. */
+ *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,1+extseq */
+ seq_offset = EVAL_seq_offset();
+ extseq = EVAL_extseq();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 1: /* esp_in */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ ivlen = EVAL_ivlen();
+ icvlen = EVAL_icvlen();
+ pad_blocksize = EVAL_pad_blocksize();
+ if (packetsize < 8u+ivlen+icvlen+pad_blocksize+bypass+hdrlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for ESP inbound\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ pad_remainder = EVAL_pad_remainder();
+ if (pad_remainder != 0u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, pad alignment ESP inbound\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+#if TKB_HAVE_ECN_FIXUP == 1u
+ /* DATA32 ecn_fixup_instr */
+ ecn_fixup_instr = EVAL_ecn_fixup_instr();
+ *tp++=0x00000000 | ((ecn_fixup_instr)&0xffffffffu)<<0;
+#endif
+ if (ivhandling == 0u)
+ {
+ /* RETR HASHONLY,ORIG_SPI,8 */
+ *tp++=0x42900000 | ((8u)&0x1ffffu)<<0;
+ /* RETR HASHONLY,ORIG_IV1,ivlen */
+ *tp++=0x42a80000 | ((ivlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* RETR HASHONLY,ORIG_SPI,8+ivlen */
+ *tp++=0x42900000 | ((8u+ivlen)&0x1ffffu)<<0;
+ }
+ if (icvlen > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq != 1u)
+ {
+ /* DIR CRYPTHASH,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST,LASTHASH */
+ *tp++=0x0f020000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR CRYPTHASH,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST */
+ *tp++=0x0f000000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+ /* INS HASHONLY, ORIG_EXTSEQNUM_RES2,4,LASTHASH */
+ *tp++=0x224a0000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+ *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR CRYPT,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST,LASTHASHPKT */
+ *tp++=0x0d060000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 2: /* esp_out_ccm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ if (packetsize <= bypass+hdrlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for ESP outbound CCM\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* INS HASHONLY,ORIG_TOKEN,4 */
+ *tp++=0x22d80000 | ((4u)&0x1ffffu)<<0;
+ /* DATA32 salt */
+ salt = EVAL_salt();
+ *tp++=0x00000000 | ((salt)&0xffffffffu)<<0;
+ /* INS HASHONLY,ORIG_IV1,8 */
+ *tp++=0x22a80000 | ((8u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_TOKEN,6 ; Insert message length + AAD length. */
+ *tp++=0x22d80000 | ((6u)&0x1ffffu)<<0;
+ /* DATA32 swaplen ; Message length, byte-swapped */
+ swaplen = EVAL_swaplen();
+ *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+ extseq = EVAL_extseq();
+ if (extseq == 0u)
+ {
+ /* DATA32 0x0800 ; AAD length, byte-swapped */
+ *tp++=0x00000000 | ((2048u)&0xffffffffu)<<0;
+ /* INS HASH,ORIG_SPI,8 */
+ *tp++=0x23900000 | ((8u)&0x1ffffu)<<0;
+ /* INS HASHONLY, PAD_ZERO, 0, 6 */
+ *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((6u)&0xffffu)<<0;
+ }
+ else
+ {
+ /* DATA32 0x0c00 ; AAD length, byte-swapped */
+ *tp++=0x00000000 | ((3072u)&0xffffffffu)<<0;
+ /* INS HASH,ORIG_SPI,4 */
+ *tp++=0x23900000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_EXTSEQNUM_RES2, 4 */
+ *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASH,ORIG_SEQNUM_RES, 4 */
+ *tp++=0x23980000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY, PAD_ZERO, 0, 2 */
+ *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((2u)&0xffffu)<<0;
+ }
+ /* INS OUT,ORIG_IV1,ivlen */
+ ivlen = EVAL_ivlen();
+ *tp++=0x21a80000 | ((ivlen)&0x1ffffu)<<0;
+ /* REMRES bypass+ohdrlen+8+ivlen, 16 */
+ ohdrlen = EVAL_ohdrlen();
+ *tp++=0xa0000000 | ((8u+bypass+ohdrlen+ivlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ /* DIR CRYPTHASH, packetsize-bypass-hdrlen */
+ *tp++=0x07000000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+ hashpad = EVAL_hashpad();
+ if (hashpad == 0u)
+ {
+ /* INS CRYPTHASH,PAD_IPSEC,nextheader,pad_bytes,LAST,LASTHASH */
+ nextheader = EVAL_nextheader();
+ pad_bytes = EVAL_pad_bytes();
+ *tp++=0x2f220000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+ }
+ else
+ {
+ /* INS CRYPTHASH,PAD_IPSEC,nextheader,pad_bytes,LAST */
+ nextheader = EVAL_nextheader();
+ pad_bytes = EVAL_pad_bytes();
+ *tp++=0x2f200000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+ /* INS HASHONLY,PAD_ZERO,0,hashpad,LASTHASH */
+ *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((hashpad)&0xffffu)<<0;
+ }
+ /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ /* VERIFY 0 ; Causes any sequence number rollover error to fail the packet. */
+ *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,1+extseq */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 3: /* esp_in_ccm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ ivlen = EVAL_ivlen();
+ icvlen = EVAL_icvlen();
+ pad_blocksize = EVAL_pad_blocksize();
+ if (packetsize < 8u+ivlen+icvlen+pad_blocksize+bypass+hdrlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for ESP inbound CCM\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ pad_remainder = EVAL_pad_remainder();
+ if (pad_remainder != 0u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, pad alignment ESP inbound CCM\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* RETR NONE,ORIG_SPI,8 */
+ *tp++=0x40900000 | ((8u)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_IV1,ivlen */
+ *tp++=0x40a80000 | ((ivlen)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_TOKEN,4 */
+ *tp++=0x22d80000 | ((4u)&0x1ffffu)<<0;
+ /* DATA32 salt */
+ salt = EVAL_salt();
+ *tp++=0x00000000 | ((salt)&0xffffffffu)<<0;
+ /* INS HASHONLY,ORIG_IV1,8 */
+ *tp++=0x22a80000 | ((8u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_TOKEN,6 ; Insert message length + AAD length. */
+ *tp++=0x22d80000 | ((6u)&0x1ffffu)<<0;
+ /* DATA32 swaplen ; Message length, byte-swapped */
+ swaplen = EVAL_swaplen();
+ *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+ extseq = EVAL_extseq();
+ if (extseq != 1u)
+ {
+ /* DATA32 0x0800 ; AAD length, byte-swapped */
+ *tp++=0x00000000 | ((2048u)&0xffffffffu)<<0;
+ /* INS HASHONLY,ORIG_SPI,8 */
+ *tp++=0x22900000 | ((8u)&0x1ffffu)<<0;
+ /* INS HASHONLY, PAD_ZERO, 0, 6 */
+ *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((6u)&0xffffu)<<0;
+ }
+ else
+ {
+ /* DATA32 0x0c00 ; AAD length, byte-swapped */
+ *tp++=0x00000000 | ((3072u)&0xffffffffu)<<0;
+ /* INS HASHONLY,ORIG_SPI,4 */
+ *tp++=0x22900000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_EXTSEQNUM_RES2, 4 */
+ *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SEQNUM_RES, 4 */
+ *tp++=0x22980000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY, PAD_ZERO, 0, 2 */
+ *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((2u)&0xffffu)<<0;
+ }
+ /* REMRES bypass+ohdrlen, 16 */
+ ohdrlen = EVAL_ohdrlen();
+ *tp++=0xa0000000 | ((bypass+ohdrlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+#if TKB_HAVE_ECN_FIXUP == 1u
+ /* DATA32 ecn_fixup_instr */
+ ecn_fixup_instr = EVAL_ecn_fixup_instr();
+ *tp++=0x00000000 | ((ecn_fixup_instr)&0xffffffffu)<<0;
+#endif
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ hashpad = EVAL_hashpad();
+ if (hashpad == 0u)
+ {
+ /* DIR CRYPTHASH,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST,LASTHASH */
+ *tp++=0x0f020000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR CRYPTHASH,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST */
+ *tp++=0x0f000000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+ /* INS HASHONLY,PAD_ZERO,0,hashpad,LASTHASH */
+ *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((hashpad)&0xffffu)<<0;
+ }
+ /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+ *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 4: /* esp_out_gcm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ if (packetsize <= bypass+hdrlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for ESP outbound GCM\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ extseq = EVAL_extseq();
+ if (extseq == 0u)
+ {
+ /* INS HASH,ORIG_SPI,8,LAST */
+ *tp++=0x2b900000 | ((8u)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASH,ORIG_SPI,4 */
+ *tp++=0x23900000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY, ORIG_EXTSEQNUM_RES2, 4 */
+ *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASH,ORIG_SEQNUM_RES, 4, LAST */
+ *tp++=0x2b980000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* INS OUT,ORIG_IV1,ivlen */
+ ivlen = EVAL_ivlen();
+ *tp++=0x21a80000 | ((ivlen)&0x1ffffu)<<0;
+ /* REMRES bypass+ohdrlen+8+ivlen, 16 */
+ ohdrlen = EVAL_ohdrlen();
+ *tp++=0xa0000000 | ((8u+bypass+ohdrlen+ivlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ /* DIR CRYPTHASH, packetsize-bypass-hdrlen */
+ *tp++=0x07000000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+ /* INS CRYPTHASH,PAD_IPSEC,nextheader,pad_bytes,LAST,LASTHASH */
+ nextheader = EVAL_nextheader();
+ pad_bytes = EVAL_pad_bytes();
+ *tp++=0x2f220000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+ /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ /* VERIFY 0 ; Causes any sequence number rollover error to fail the packet. */
+ *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,1+extseq */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 5: /* esp_in_gcm */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ ivlen = EVAL_ivlen();
+ icvlen = EVAL_icvlen();
+ pad_blocksize = EVAL_pad_blocksize();
+ if (packetsize < 8u+ivlen+icvlen+pad_blocksize+bypass+hdrlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for ESP inbound GCM\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ pad_remainder = EVAL_pad_remainder();
+ if (pad_remainder != 0u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, pad alignment ESP inbound GCM\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ extseq = EVAL_extseq();
+ if (extseq != 1u)
+ {
+ /* RETR HASHONLY,ORIG_SPI,8,LAST */
+ *tp++=0x4a900000 | ((8u)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* RETR HASHONLY,ORIG_SPI,4 */
+ *tp++=0x42900000 | ((4u)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_SEQNUM_RES,4 */
+ *tp++=0x40980000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_EXTSEQNUM_RES2, 4 */
+ *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SEQNUM_RES,4,LAST */
+ *tp++=0x2a980000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* RETR NONE,ORIG_IV1,ivlen */
+ *tp++=0x40a80000 | ((ivlen)&0x1ffffu)<<0;
+ /* REMRES bypass+ohdrlen, 16 */
+ ohdrlen = EVAL_ohdrlen();
+ *tp++=0xa0000000 | ((bypass+ohdrlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+#if TKB_HAVE_ECN_FIXUP == 1u
+ /* DATA32 ecn_fixup_instr */
+ ecn_fixup_instr = EVAL_ecn_fixup_instr();
+ *tp++=0x00000000 | ((ecn_fixup_instr)&0xffffffffu)<<0;
+#endif
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ /* DIR CRYPTHASH,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST,LASTHASH */
+ *tp++=0x0f020000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+ *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 6: /* esp_out_gmac */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ if (packetsize <= bypass+hdrlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for ESP outbound GMAC\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ extseq = EVAL_extseq();
+ if (extseq == 0u)
+ {
+ /* INS HASH,ORIG_SPI,8 */
+ *tp++=0x23900000 | ((8u)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASH,ORIG_SPI,4 */
+ *tp++=0x23900000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY, ORIG_EXTSEQNUM_RES2, 4 */
+ *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASH,ORIG_SEQNUM_RES, 4 */
+ *tp++=0x23980000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* INS HASH,ORIG_IV1,ivlen */
+ ivlen = EVAL_ivlen();
+ *tp++=0x23a80000 | ((ivlen)&0x1ffffu)<<0;
+ /* REMRES bypass+ohdrlen+8+ivlen, 16 */
+ ohdrlen = EVAL_ohdrlen();
+ *tp++=0xa0000000 | ((8u+bypass+ohdrlen+ivlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ /* DIR HASH, packetsize-bypass-hdrlen */
+ *tp++=0x03000000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+ /* INS HASH,PAD_IPSEC,nextheader,pad_bytes,LAST,LASTHASH */
+ nextheader = EVAL_nextheader();
+ pad_bytes = EVAL_pad_bytes();
+ *tp++=0x2b220000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+ /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ /* VERIFY 0 ; Causes any sequence number rollover error to fail the packet. */
+ *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,1+extseq */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 7: /* esp_in_gmac */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ ivlen = EVAL_ivlen();
+ icvlen = EVAL_icvlen();
+ pad_blocksize = EVAL_pad_blocksize();
+ if (packetsize < 8u+ivlen+icvlen+pad_blocksize+bypass+hdrlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for ESP inbound GMAC\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ pad_remainder = EVAL_pad_remainder();
+ if (pad_remainder != 0u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, pad alignment ESP inbound GMAC\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ extseq = EVAL_extseq();
+ if (extseq != 1u)
+ {
+ /* RETR HASHONLY,ORIG_SPI,8 */
+ *tp++=0x42900000 | ((8u)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* RETR HASHONLY,ORIG_SPI,4 */
+ *tp++=0x42900000 | ((4u)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_SEQNUM_RES,4 */
+ *tp++=0x40980000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_EXTSEQNUM_RES2, 4 */
+ *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SEQNUM_RES,4 */
+ *tp++=0x22980000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* RETR HASHONLY,ORIG_IV1,ivlen */
+ *tp++=0x42a80000 | ((ivlen)&0x1ffffu)<<0;
+ /* REMRES bypass+ohdrlen, 16 */
+ ohdrlen = EVAL_ohdrlen();
+ *tp++=0xa0000000 | ((bypass+ohdrlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+#if TKB_HAVE_ECN_FIXUP == 1u
+ /* DATA32 ecn_fixup_instr */
+ ecn_fixup_instr = EVAL_ecn_fixup_instr();
+ *tp++=0x00000000 | ((ecn_fixup_instr)&0xffffffffu)<<0;
+#endif
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ /* DIR HASH,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST,LASTHASH */
+ *tp++=0x0b020000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+ *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 8: /* ssltls_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ if (packetsize < bypass+hdrlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS outbound\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ capwap_out = EVAL_capwap_out();
+ if (capwap_out != 0u)
+ {
+ /* INS OUT,ORIG_TOKEN,4 */
+ *tp++=0x21d80000 | ((4u)&0x1ffffu)<<0;
+ /* DATA32 0x0000001 ; Insert DTLS/CAPWAP header. */
+ *tp++=0x00000000 | ((1u)&0xffffffffu)<<0;
+ }
+ /* INS HASHONLY,ORIG_EXTSEQNUM,4 */
+ *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SEQNUM,4 */
+ *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASH,PAD_CONST,nextheader,1 ; Type field */
+ nextheader = EVAL_nextheader();
+ *tp++=0x23100000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ antireplay = EVAL_antireplay();
+ if (antireplay != 0u)
+ {
+ /* INS HASH,ORIG_SPI,2 ; For TLS/DTLS, hash version field. */
+ *tp++=0x23900000 | ((2u)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS OUT,ORIG_SPI,2 ; For SSL, do not hash version field. */
+ *tp++=0x21900000 | ((2u)&0x1ffffu)<<0;
+ }
+ extseq = EVAL_extseq();
+ if (extseq != 0u)
+ {
+ /* INS OUT,ORIG_EXTSEQNUM,4 */
+ *tp++=0x21580000 | ((4u)&0x1ffffu)<<0;
+ /* INS OUT,ORIG_SEQNUM,4 */
+ *tp++=0x21500000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* INS HASHONLY,ORIG_TOKEN,2 */
+ *tp++=0x22d80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swaplen ; Payload length to hash. */
+ swaplen = EVAL_swaplen();
+ *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+ /* INS OUT,ORIG_TOKEN,2 */
+ *tp++=0x21d80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swap_fraglen ; Fragment length to output. */
+ swap_fraglen = EVAL_swap_fraglen();
+ *tp++=0x00000000 | ((swap_fraglen)&0xffffffffu)<<0;
+ /* INS OUT,ORIG_IV0,ivlen */
+ ivlen = EVAL_ivlen();
+ *tp++=0x21a00000 | ((ivlen)&0x1ffffu)<<0;
+ if (packetsize != bypass+hdrlen)
+ {
+ /* DIR CRYPTHASH, packetsize-bypass-hdrlen,LASTHASH */
+ *tp++=0x07020000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS CRYPTHASH, PAD_ZERO, 0, 0, LASTHASH */
+ *tp++=0x27020000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ }
+ upd_handling = EVAL_upd_handling();
+ switch(upd_handling)
+ {
+ case 0: /* upd_null */
+ /* INS CRYPT,ORIG_HASH,icvlen,LAST,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x2de60000 | ((icvlen)&0x1ffffu)<<0;
+ /* VERIFY 0 ; Causes any sequence number rollover error to fail the packet. */
+ *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2 */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ break;
+ case 1: /* upd_arc4 */
+ /* INS CRYPT,ORIG_HASH,icvlen,LAST,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x2de60000 | ((icvlen)&0x1ffffu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2 */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ /* CTX ORIG_CHKSUM,iv_offset,1,P ; Update IJ pointer */
+ iv_offset = EVAL_iv_offset();
+ *tp++=0xe0ce1800 | ((iv_offset)&0xffu)<<0 | ((1u)&0xfu)<<24;
+ /* CTX ORIG_CHKSUM_STORE,0,1,P ; Update ARC4 state. */
+ *tp++=0xe0d61800 | ((0u)&0xffu)<<0 | ((1u)&0xfu)<<24;
+ break;
+ case 2: /* upd_iv2 */
+ /* INS CRYPT,ORIG_HASH,icvlen,LASTHASH */
+ icvlen = EVAL_icvlen();
+ *tp++=0x25e20000 | ((icvlen)&0x1ffffu)<<0;
+ if (antireplay != 0u)
+ {
+ /* INS CRYPT,PAD_TLS,0,pad_bytes,LAST,LASTHASHPKT */
+ pad_bytes = EVAL_pad_bytes();
+ *tp++=0x2d2e0000 | ((0u)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+ }
+ else
+ {
+ /* INS CRYPT,PAD_SSL,0,pad_bytes,LAST,LASTHASHPKT */
+ pad_bytes = EVAL_pad_bytes();
+ *tp++=0x2d360000 | ((0u)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+ }
+ /* CTX ORIG_SEQNUM,seq_offset,2 */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ /* CTX ORIG_IV0,iv_offset,2,P */
+ iv_offset = EVAL_iv_offset();
+ *tp++=0xe0a61800 | ((iv_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ break;
+ case 3: /* upd_iv4 */
+ /* INS CRYPT,ORIG_HASH,icvlen,LASTHASH */
+ icvlen = EVAL_icvlen();
+ *tp++=0x25e20000 | ((icvlen)&0x1ffffu)<<0;
+ if (antireplay != 0u)
+ {
+ /* INS CRYPT,PAD_TLS,0,pad_bytes,LAST,LASTHASHPKT */
+ pad_bytes = EVAL_pad_bytes();
+ *tp++=0x2d2e0000 | ((0u)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+ }
+ else
+ {
+ /* INS CRYPT,PAD_SSL,0,pad_bytes,LAST,LASTHASHPKT */
+ pad_bytes = EVAL_pad_bytes();
+ *tp++=0x2d360000 | ((0u)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+ }
+ /* CTX ORIG_SEQNUM,seq_offset,2 */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ /* CTX ORIG_IV0,iv_offset,4,P */
+ iv_offset = EVAL_iv_offset();
+ *tp++=0xe0a61800 | ((iv_offset)&0xffu)<<0 | ((4u)&0xfu)<<24;
+ break;
+ case 4: /* upd_blk */
+ /* INS CRYPT,ORIG_HASH,icvlen,LASTHASH */
+ icvlen = EVAL_icvlen();
+ *tp++=0x25e20000 | ((icvlen)&0x1ffffu)<<0;
+ /* INS CRYPT,PAD_TLS,0,pad_bytes,LAST,LASTHASHPKT */
+ pad_bytes = EVAL_pad_bytes();
+ *tp++=0x2d2e0000 | ((0u)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+ /* VERIFY 0 ; Causes any sequence number rollover error to fail the packet. */
+ *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2 */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ break;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 9: /* ssltls_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ paylen = EVAL_paylen();
+ if (paylen == 4294967295u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, payload size for SSLTLS inbound\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ upd_handling = EVAL_upd_handling();
+ if (upd_handling <= 1u)
+ {
+ if (bypass > 0u)
+ {
+ /* DIR OUT,bypass */
+ *tp++=0x01000000 | ((bypass)&0x1ffffu)<<0;
+ }
+ if (hdrlen > 0u)
+ {
+ /* DIR OUT,hdrlen */
+ *tp++=0x01000000 | ((hdrlen)&0x1ffffu)<<0;
+ }
+ capwap_in = EVAL_capwap_in();
+ if (capwap_in != 0u)
+ {
+ /* REM 4 ; Remove DTLS/CAPWAP header. */
+ *tp++=0x40d80000 | ((4u)&0x1ffffu)<<0;
+ }
+ extseq = EVAL_extseq();
+ if (extseq != 0u)
+ {
+ ohdrlen = EVAL_ohdrlen();
+ if (ohdrlen > hdrlen)
+ {
+ /* RETR OUT,ORIG_SPI,3 ; Extract Type and Version. */
+ *tp++=0x41900000 | ((3u)&0x1ffffu)<<0;
+ /* RETR HASHONLY,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+ *tp++=0x42480000 | ((4u)&0x1ffffu)<<0;
+ /* RETR HASHONLY,ORIG_SEQNUM_RES2,4 */
+ *tp++=0x42400000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SPI_RES,3 ; Hash type and version. */
+ *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+ /* INS HASH,ORIG_TOKEN,2 */
+ *tp++=0x23d80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swaplen */
+ swaplen = EVAL_swaplen();
+ *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+ if (ohdrlen-hdrlen > 5u)
+ {
+ /* INS OUT,PAD_ZERO,0,ohdrlen-hdrlen-5 */
+ *tp++=0x21000000 | ((0u)&0x1u)<<16 | ((-5u+ohdrlen-hdrlen)&0xffffu)<<0;
+ }
+ }
+ else
+ {
+ /* RETR NONE,ORIG_SPI,3 ; Extract Type and Version. */
+ *tp++=0x40900000 | ((3u)&0x1ffffu)<<0;
+ /* RETR HASHONLY,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+ *tp++=0x42480000 | ((4u)&0x1ffffu)<<0;
+ /* RETR HASHONLY,ORIG_SEQNUM_RES2,4 */
+ *tp++=0x42400000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SPI_RES,3 ; Hash type and version. */
+ *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_TOKEN,2 */
+ *tp++=0x22d80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swaplen */
+ swaplen = EVAL_swaplen();
+ *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+ }
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_EXTSEQNUM,4 ; Extract from SA. */
+ *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SEQNUM,4 */
+ *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+ antireplay = EVAL_antireplay();
+ if (antireplay != 0u)
+ {
+ /* DIR HASHONLY,3 ; Hash type and version number */
+ *tp++=0x02000000 | ((3u)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASHONLY,1 ; Hash type only for SSL */
+ *tp++=0x02000000 | ((1u)&0x1ffffu)<<0;
+ /* REM 2 */
+ *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+ }
+ /* INS HASHONLY,ORIG_TOKEN,2 */
+ *tp++=0x22d80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swaplen */
+ swaplen = EVAL_swaplen();
+ *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+ }
+ /* REM 2 ; Remove fragment length. */
+ *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+ /* REMRES bypass+ohdrlen+paylen,icvlen ; Cause the MAC to be removed */
+ ohdrlen = EVAL_ohdrlen();
+ icvlen = EVAL_icvlen();
+ *tp++=0xa0000000 | ((bypass+ohdrlen+paylen)&0xffffu)<<0 | ((icvlen)&0x3fu)<<19;
+ /* DIR CRYPTHASH,paylen,LASTHASH */
+ *tp++=0x07020000 | ((paylen)&0x1ffffu)<<0;
+ switch(upd_handling)
+ {
+ case 0: /* upd_null */
+ /* DIR CRYPT,icvlen,LAST,LASTHASHPKT */
+ *tp++=0x0d060000 | ((icvlen)&0x1ffffu)<<0;
+ if (extseq == 0u)
+ {
+ /* VERIFY icvlen,H */
+ *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ }
+ else if (extseq == 1u)
+ {
+ /* VERIFY icvlen,H */
+ *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+ }
+ else
+ {
+ /* VERIFY icvlen,S,H */
+ *tp++=0xd8070000 | ((icvlen)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,1+extseq,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+ }
+ break;
+ case 1: /* upd_arc4 */
+ /* DIR CRYPT,icvlen,LAST,LASTHASHPKT */
+ *tp++=0x0d060000 | ((icvlen)&0x1ffffu)<<0;
+ /* VERIFY icvlen,H */
+ *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ /* CTX ORIG_CHKSUM,iv_offset,1,P ; Update IJ pointer */
+ iv_offset = EVAL_iv_offset();
+ *tp++=0xe0ce1800 | ((iv_offset)&0xffu)<<0 | ((1u)&0xfu)<<24;
+ /* CTX ORIG_CHKSUM_STORE,0,1,P ; Update ARC4 state. */
+ *tp++=0xe0d61800 | ((0u)&0xffu)<<0 | ((1u)&0xfu)<<24;
+ break;
+ }
+ }
+ else
+ {
+ /* REMRES 0,4,NOUPDCHK */
+ *tp++=0xa0020000 | ((0u)&0xffffu)<<0 | ((4u)&0x3fu)<<19;
+ cipher_is_aes = EVAL_cipher_is_aes();
+ if (cipher_is_aes == 0u)
+ {
+ /* INS CRYPTONLY,ORIG_TOKEN,12 */
+ *tp++=0x24d80000 | ((12u)&0x1ffffu)<<0;
+ ssltls_lastblock = EVAL_ssltls_lastblock();
+ TokenBuilder_CopyBytes(tp, ssltls_lastblock, 12);
+ tp += 3;
+ /* INS CRYPT,ORIG_TOKEN,4 */
+ *tp++=0x25d80000 | ((4u)&0x1ffffu)<<0;
+ ssltls_lastword = EVAL_ssltls_lastword();
+ TokenBuilder_CopyBytes(tp, ssltls_lastword, 4);
+ tp += 1;
+ }
+ else
+ {
+ /* INS CRYPTONLY,ORIG_TOKEN,28 */
+ *tp++=0x24d80000 | ((28u)&0x1ffffu)<<0;
+ ssltls_lastblock = EVAL_ssltls_lastblock();
+ TokenBuilder_CopyBytes(tp, ssltls_lastblock, 28);
+ tp += 7;
+ /* INS CRYPT,ORIG_TOKEN,4 */
+ *tp++=0x25d80000 | ((4u)&0x1ffffu)<<0;
+ ssltls_lastword = EVAL_ssltls_lastword();
+ TokenBuilder_CopyBytes(tp, ssltls_lastword, 4);
+ tp += 1;
+ }
+ /* DIR NONE,0,LAST */
+ *tp++=0x08000000 | ((0u)&0x1ffffu)<<0;
+ if (bypass+hdrlen > 0u)
+ {
+ /* DIR OUT,bypass+hdrlen */
+ *tp++=0x01000000 | ((bypass+hdrlen)&0x1ffffu)<<0;
+ }
+ capwap_in = EVAL_capwap_in();
+ if (capwap_in != 0u)
+ {
+ /* REM 4 ; Remove DTLS/CAPWAP header. */
+ *tp++=0x40d80000 | ((4u)&0x1ffffu)<<0;
+ }
+ extseq = EVAL_extseq();
+ if (extseq != 0u)
+ {
+ ohdrlen = EVAL_ohdrlen();
+ if (ohdrlen > hdrlen)
+ {
+ /* RETR OUT,ORIG_SPI,3 ; Extract Type and Version. */
+ *tp++=0x41900000 | ((3u)&0x1ffffu)<<0;
+ /* RETR HASHONLY,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+ *tp++=0x42480000 | ((4u)&0x1ffffu)<<0;
+ /* RETR HASHONLY,ORIG_SEQNUM_RES2,4 */
+ *tp++=0x42400000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SPI_RES,3 ; Hash type and version. */
+ *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+ /* INS HASH,ORIG_LENCOR,paylen-1 */
+ *tp++=0x23780000 | ((-1u+paylen)&0x1ffffu)<<0;
+ if (ohdrlen-hdrlen > 5u)
+ {
+ /* INS OUT,PAD_ZERO,0,ohdrlen-hdrlen-5 */
+ *tp++=0x21000000 | ((0u)&0x1u)<<16 | ((-5u+ohdrlen-hdrlen)&0xffffu)<<0;
+ }
+ }
+ else
+ {
+ /* RETR NONE,ORIG_SPI,3 ; Extract Type and Version. */
+ *tp++=0x40900000 | ((3u)&0x1ffffu)<<0;
+ /* RETR HASHONLY,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+ *tp++=0x42480000 | ((4u)&0x1ffffu)<<0;
+ /* RETR HASHONLY,ORIG_SEQNUM_RES2,4 */
+ *tp++=0x42400000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SPI_RES,3 ; Hash type and version. */
+ *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_LENCOR,paylen-1 */
+ *tp++=0x22780000 | ((-1u+paylen)&0x1ffffu)<<0;
+ }
+ }
+ else
+ {
+ /* RETR NONE,ORIG_SPI,3 ; Extract Type and Version. */
+ *tp++=0x40900000 | ((3u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_EXTSEQNUM,4 ; Extract from SA. */
+ *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SEQNUM,4 */
+ *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+ antireplay = EVAL_antireplay();
+ if (antireplay != 0u)
+ {
+ /* INS HASHONLY,ORIG_SPI_RES,3 ; Hash type and version number */
+ *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_SPI_RES,1 ; Hash type only. */
+ *tp++=0x22c00000 | ((1u)&0x1ffffu)<<0;
+ }
+ /* INS HASHONLY,ORIG_LENCOR,paylen-1 */
+ *tp++=0x22780000 | ((-1u+paylen)&0x1ffffu)<<0;
+ }
+ /* REM 2 ; Remove fragment length. */
+ *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+ ivlen = EVAL_ivlen();
+ if (ivlen > 0u)
+ {
+ /* RETR NONE,ORIG_IV0,ivlen */
+ *tp++=0x40a00000 | ((ivlen)&0x1ffffu)<<0;
+ }
+ /* REMRES bypass+ohdrlen,icvlen,NOUPDCHK ; Cause the MAC to be removed */
+ ohdrlen = EVAL_ohdrlen();
+ icvlen = EVAL_icvlen();
+ *tp++=0xa0020000 | ((bypass+ohdrlen)&0xffffu)<<0 | ((icvlen)&0x3fu)<<19;
+ /* DIRX CRYPTHASH,ORIG_LENCOR,0,LASTHASH */
+ *tp++=0x077a0000 | ((0u)&0x1ffffu)<<0;
+ /* DIRX CRYPT,ORIG_LENCOR,icvlen+1,LAST,LASTHASHPKT */
+ *tp++=0x0d7e0000 | ((1u+icvlen)&0x1ffffu)<<0;
+ switch(upd_handling)
+ {
+ case 2: /* upd_iv2 */
+ antireplay = EVAL_antireplay();
+ if (antireplay != 0u)
+ {
+ /* VERIFY icvlen,P,H */
+ *tp++=0xd1070000 | ((icvlen)&0x7fu)<<0;
+ }
+ else
+ {
+ /* VERIFY icvlen,H */
+ *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+ }
+ /* CTX ORIG_SEQNUM,seq_offset,2,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ /* CTX ORIG_IV0,iv_offset,2,P */
+ iv_offset = EVAL_iv_offset();
+ *tp++=0xe0a61800 | ((iv_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ break;
+ case 3: /* upd_iv4 */
+ antireplay = EVAL_antireplay();
+ if (antireplay != 0u)
+ {
+ /* VERIFY icvlen,P,H */
+ *tp++=0xd1070000 | ((icvlen)&0x7fu)<<0;
+ }
+ else
+ {
+ /* VERIFY icvlen,H */
+ *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+ }
+ /* CTX ORIG_SEQNUM,seq_offset,2,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ /* CTX ORIG_IV0,iv_offset,4,P */
+ iv_offset = EVAL_iv_offset();
+ *tp++=0xe0a61800 | ((iv_offset)&0xffu)<<0 | ((4u)&0xfu)<<24;
+ break;
+ case 4: /* upd_blk */
+ if (extseq == 0u)
+ {
+ /* VERIFY icvlen,P,H */
+ *tp++=0xd1070000 | ((icvlen)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ }
+ else if (extseq == 1u)
+ {
+ /* VERIFY icvlen,P,H */
+ *tp++=0xd1070000 | ((icvlen)&0x7fu)<<0;
+ }
+ else
+ {
+ /* VERIFY icvlen,P,S,H */
+ *tp++=0xd9070000 | ((icvlen)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,1+extseq,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+ }
+ break;
+ }
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 21: /* ssltls_gcm_out */
+ case 37: /* ssltls_chachapoly_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ if (packetsize < bypass+hdrlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS outbound GCM or ChaChaPoly\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ capwap_out = EVAL_capwap_out();
+ if (capwap_out != 0u)
+ {
+ /* INS OUT,ORIG_TOKEN,4 */
+ *tp++=0x21d80000 | ((4u)&0x1ffffu)<<0;
+ /* DATA32 0x0000001 ; Insert DTLS/CAPWAP header. */
+ *tp++=0x00000000 | ((1u)&0xffffffffu)<<0;
+ }
+ /* INS HASHONLY,ORIG_EXTSEQNUM,4 */
+ *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SEQNUM,4 */
+ *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASH,PAD_CONST,nextheader,1 ; Type field */
+ nextheader = EVAL_nextheader();
+ *tp++=0x23100000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ /* INS HASH,ORIG_SPI,2 ; For TLS/DTLS, hash version field. */
+ *tp++=0x23900000 | ((2u)&0x1ffffu)<<0;
+ extseq = EVAL_extseq();
+ if (extseq != 0u)
+ {
+ /* INS OUT,ORIG_EXTSEQNUM,4 ; Output sequence number for DTLS */
+ *tp++=0x21580000 | ((4u)&0x1ffffu)<<0;
+ /* INS OUT,ORIG_SEQNUM,4 */
+ *tp++=0x21500000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* INS HASHONLY,ORIG_TOKEN,2,LAST */
+ *tp++=0x2ad80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swaplen ; Payload length to hash. */
+ swaplen = EVAL_swaplen();
+ *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+ /* INS OUT,ORIG_TOKEN,2 */
+ *tp++=0x21d80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swap_fraglen ; Fragment length to output. */
+ swap_fraglen = EVAL_swap_fraglen();
+ *tp++=0x00000000 | ((swap_fraglen)&0xffffffffu)<<0;
+ /* INS OUT,ORIG_IV1,ivlen */
+ ivlen = EVAL_ivlen();
+ *tp++=0x21a80000 | ((ivlen)&0x1ffffu)<<0;
+ if (proto != 37u)
+ {
+ if (extseq != 0u)
+ {
+ /* REMRES bypass + hdrlen + capwap_out + 5 + 8 + 8, 16 */
+ *tp++=0xa0000000 | ((21u+bypass+hdrlen+capwap_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ }
+ else
+ {
+ /* REMRES bypass + hdrlen + 5 + 8, 16 */
+ *tp++=0xa0000000 | ((13u+bypass+hdrlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ }
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ }
+ if (packetsize != bypass+hdrlen)
+ {
+ /* DIR CRYPTHASH, packetsize-bypass-hdrlen,LAST,LASTHASH */
+ *tp++=0x0f020000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS CRYPTHASH, PAD_ZERO, 0, 0, LAST, LASTHASH */
+ *tp++=0x2f020000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ }
+ /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ /* VERIFY 0 ; Causes any sequence number rollover error to fail the packet. */
+ *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2 */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 22: /* ssltls_gcm_in */
+ case 38: /* ssltls_chachapoly_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ paylen = EVAL_paylen();
+ if (paylen == 4294967295u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS inbound GCM or ChaChaPoly\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ if (hdrlen > 0u)
+ {
+ /* DIR OUT,hdrlen */
+ *tp++=0x01000000 | ((hdrlen)&0x1ffffu)<<0;
+ }
+ capwap_in = EVAL_capwap_in();
+ if (capwap_in != 0u)
+ {
+ /* REM 4 ; Remove DTLS/CAPWAP header. */
+ *tp++=0x40d80000 | ((4u)&0x1ffffu)<<0;
+ }
+ ohdrlen = EVAL_ohdrlen();
+ if (ohdrlen > hdrlen)
+ {
+ /* RETR OUT,ORIG_SPI,3 ; Extract Type and Version. */
+ *tp++=0x41900000 | ((3u)&0x1ffffu)<<0;
+ /* RETR HASHONLY,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+ *tp++=0x42480000 | ((4u)&0x1ffffu)<<0;
+ /* RETR HASHONLY,ORIG_SEQNUM_RES2,4 */
+ *tp++=0x42400000 | ((4u)&0x1ffffu)<<0;
+ /* REM 2 ; Remove fragment length. */
+ *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_IV1,ivlen */
+ ivlen = EVAL_ivlen();
+ *tp++=0x40a80000 | ((ivlen)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SPI_RES,3 ; Hash type and version. */
+ *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+ /* INS HASH,ORIG_TOKEN,2,LAST */
+ *tp++=0x2bd80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swaplen */
+ swaplen = EVAL_swaplen();
+ *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+ if (ohdrlen-hdrlen > 5u)
+ {
+ /* INS OUT,PAD_ZERO,0,ohdrlen-hdrlen-5 */
+ *tp++=0x21000000 | ((0u)&0x1u)<<16 | ((-5u+ohdrlen-hdrlen)&0xffffu)<<0;
+ }
+ }
+ else
+ {
+ /* RETR NONE,ORIG_SPI,3 ; Extract Type and Version. */
+ *tp++=0x40900000 | ((3u)&0x1ffffu)<<0;
+ extseq = EVAL_extseq();
+ if (extseq != 0u)
+ {
+ /* RETR HASHONLY,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+ *tp++=0x42480000 | ((4u)&0x1ffffu)<<0;
+ /* RETR HASHONLY,ORIG_SEQNUM_RES2,4 */
+ *tp++=0x42400000 | ((4u)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_EXTSEQNUM,4 ; Extract from SA. */
+ *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SEQNUM,4 */
+ *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* REM 2 ; Remove fragment length. */
+ *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_IV1,ivlen */
+ ivlen = EVAL_ivlen();
+ *tp++=0x40a80000 | ((ivlen)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SPI_RES,3 ; Hash type and version. */
+ *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_TOKEN,2,LAST */
+ *tp++=0x2ad80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swaplen */
+ swaplen = EVAL_swaplen();
+ *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+ }
+ if (proto != 38u)
+ {
+ /* REMRES bypass+ohdrlen, 16 */
+ *tp++=0xa0000000 | ((bypass+ohdrlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ }
+ else
+ {
+#if TKB_HAVE_CHACHAPOLY_HW30 == 1u
+ /* INS NONE, PAD_ZERO, 0, 160 */
+ *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((160u)&0xffffu)<<0;
+#else
+ /* INS NONE, PAD_ZERO, 0, 16 */
+ *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+#endif
+ }
+ /* DIR CRYPTHASH, paylen,LAST,LASTHASH */
+ *tp++=0x0f020000 | ((paylen)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+ extseq = EVAL_extseq();
+ if (extseq == 0u)
+ {
+ /* VERIFY icvlen,H */
+ *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ }
+ else if (extseq == 1u)
+ {
+ /* VERIFY icvlen,H */
+ *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+ }
+ else
+ {
+ /* VERIFY icvlen,S,H */
+ *tp++=0xd8070000 | ((icvlen)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,1+extseq,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 10: /* basic_crypto */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ ivlen = EVAL_ivlen();
+ if (packetsize < ivlen+bypass)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic crypto\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ switch(ivhandling)
+ {
+ case 0: /* iv_inbound_ctr */
+ /* RETR NONE,ORIG_IV1,8 ; IV from input packet, CTR. */
+ *tp++=0x40a80000 | ((8u)&0x1ffffu)<<0;
+ break;
+ case 1: /* iv_inbound_cbc */
+ /* RETR NONE,ORIG_IV0,ivlen ; IV from input packet CBC */
+ *tp++=0x40a00000 | ((ivlen)&0x1ffffu)<<0;
+ break;
+ case 2: /* iv_outbound_ctr */
+ /* INS OUT,ORIG_IV1,8 */
+ *tp++=0x21a80000 | ((8u)&0x1ffffu)<<0;
+ break;
+ case 5: /* iv_copy_ctr */
+ /* RETR OUT,ORIG_IV1,8 ; IV from input packet, CTR. */
+ *tp++=0x41a80000 | ((8u)&0x1ffffu)<<0;
+ break;
+ case 4: /* iv_copy_cbc */
+ /* RETR OUT,ORIG_IV0,ivlen ; IV from input packet CBC */
+ *tp++=0x41a00000 | ((ivlen)&0x1ffffu)<<0;
+ break;
+ case 6: /* iv_outbound_2words */
+ case 9: /* iv_copy_token_2words */
+ /* INS OUT,ORIG_IV0,8 */
+ *tp++=0x21a00000 | ((8u)&0x1ffffu)<<0;
+ break;
+ case 7: /* iv_outbound_4words */
+ case 15: /* iv_copy_token_4words */
+ /* INS OUT,ORIG_IV0,16 */
+ *tp++=0x21a00000 | ((16u)&0x1ffffu)<<0;
+ break;
+ }
+ /* DIR CRYPT,packetsize-ivlen-bypass */
+ *tp++=0x05000000 | ((packetsize-ivlen-bypass)&0x1ffffu)<<0;
+ /* INS CRYPT,PAD_ZERO,0,pad_bytes_basic,LAST,LASTHASHPKT */
+ pad_bytes_basic = EVAL_pad_bytes_basic();
+ *tp++=0x2d060000 | ((0u)&0x1u)<<16 | ((pad_bytes_basic)&0xffffu)<<0;
+ upd_handling = EVAL_upd_handling();
+ switch(upd_handling)
+ {
+ case 0: /* upd_null */
+ break;
+ case 1: /* upd_arc4 */
+ /* CTX ORIG_CHKSUM,iv_offset,1,P,F ; Update IJ pointer */
+ iv_offset = EVAL_iv_offset();
+ *tp++=0xe0ce3800 | ((iv_offset)&0xffu)<<0 | ((1u)&0xfu)<<24;
+ /* CTX ORIG_CHKSUM_STORE,0,1,P,F ; Update ARC4 state. */
+ *tp++=0xe0d63800 | ((0u)&0xffu)<<0 | ((1u)&0xfu)<<24;
+ break;
+ case 2: /* upd_iv2 */
+ /* CTX ORIG_IV0,iv_offset,2,P,F */
+ iv_offset = EVAL_iv_offset();
+ *tp++=0xe0a63800 | ((iv_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ break;
+ case 3: /* upd_iv4 */
+ /* CTX ORIG_IV0,iv_offset,4,P,F */
+ iv_offset = EVAL_iv_offset();
+ *tp++=0xe0a63800 | ((iv_offset)&0xffu)<<0 | ((4u)&0xfu)<<24;
+ break;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 11: /* basic_hash */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ antireplay = EVAL_antireplay();
+ if (packetsize < bypass+antireplay)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic hash\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ aadlen_tkn = EVAL_aadlen_tkn();
+ if (aadlen_tkn > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* INS HASH,ORIG_TOKEN,aadlen_tkn */
+ *tp++=0x23d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn */
+ *tp++=0x22d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ aad = EVAL_aad();
+ if (aadlen_tkn > 64)
+ {
+ LOG_CRIT("Field too large\n");
+ return TKB_BAD_FIELD_SIZE;
+ }
+ TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+ tp += (aadlen_tkn + 3)/4;
+ }
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* DIR HASH,packetsize-bypass-antireplay,LASTHASH */
+ *tp++=0x03020000 | ((packetsize-bypass-antireplay)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASHONLY,packetsize-bypass-antireplay,LASTHASH */
+ *tp++=0x02020000 | ((packetsize-bypass-antireplay)&0x1ffffu)<<0;
+ }
+ appendhash = EVAL_appendhash();
+ if (antireplay > 0u)
+ {
+ /* RETR NONE,ORIG_HASH,antireplay,LASTHASHPKT */
+ *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+ /* VERIFY antireplay,H */
+ *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+ }
+ else if (appendhash > 0u)
+ {
+ /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+ *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ }
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+ hstatelen = EVAL_hstatelen();
+ *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+ if (hstatelen > 16u)
+ {
+ /* CTX ORIG_SPI_RES,seq_offset+hstatelen-16,1,P,F ; Update block counter */
+ *tp++=0xe0c63800 | ((-16u+seq_offset+hstatelen)&0xffu)<<0 | ((1u)&0xfu)<<24;
+ }
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 14: /* basic_crypthash */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ aadlen_pkt = EVAL_aadlen_pkt();
+ ivlen = EVAL_ivlen();
+ antireplay = EVAL_antireplay();
+ if (packetsize < bypass+aadlen_pkt+ivlen+antireplay)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic crypthash\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ aadlen_tkn = EVAL_aadlen_tkn();
+ if (aadlen_tkn > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* INS HASH,ORIG_TOKEN,aadlen_tkn */
+ *tp++=0x23d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn */
+ *tp++=0x22d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ aad = EVAL_aad();
+ if (aadlen_tkn > 64)
+ {
+ LOG_CRIT("Field too large\n");
+ return TKB_BAD_FIELD_SIZE;
+ }
+ TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+ tp += (aadlen_tkn + 3)/4;
+ }
+ else if (aadlen_pkt > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* DIR HASH,aadlen_pkt */
+ *tp++=0x03000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASHONLY,aadlen_pkt */
+ *tp++=0x02000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ }
+ switch(ivhandling)
+ {
+ case 0: /* iv_inbound_ctr */
+ /* RETR HASHONLY,ORIG_IV1,8 ; IV from input packet, CTR. */
+ *tp++=0x42a80000 | ((8u)&0x1ffffu)<<0;
+ break;
+ case 1: /* iv_inbound_cbc */
+ /* RETR HASHONLY,ORIG_IV0,ivlen ; IV from input packet CBC */
+ *tp++=0x42a00000 | ((ivlen)&0x1ffffu)<<0;
+ break;
+ case 2: /* iv_outbound_ctr */
+ /* INS HASH,ORIG_IV1,8 */
+ *tp++=0x23a80000 | ((8u)&0x1ffffu)<<0;
+ break;
+ case 5: /* iv_copy_ctr */
+ /* RETR HASH,ORIG_IV1,8 ; IV from input packet, CTR. */
+ *tp++=0x43a80000 | ((8u)&0x1ffffu)<<0;
+ break;
+ case 4: /* iv_copy_cbc */
+ /* RETR HASH,ORIG_IV0,ivlen ; IV from input packet CBC */
+ *tp++=0x43a00000 | ((ivlen)&0x1ffffu)<<0;
+ break;
+ case 6: /* iv_outbound_2words */
+ case 9: /* iv_copy_token_2words */
+ /* INS HASH,ORIG_IV0,8 */
+ *tp++=0x23a00000 | ((8u)&0x1ffffu)<<0;
+ break;
+ case 7: /* iv_outbound_4words */
+ case 15: /* iv_copy_token_4words */
+ /* INS HASH,ORIG_IV0,16 */
+ *tp++=0x23a00000 | ((16u)&0x1ffffu)<<0;
+ break;
+ }
+ pad_bytes_basic = EVAL_pad_bytes_basic();
+ if (pad_bytes_basic > 0u)
+ {
+ /* DIR CRYPTHASH,packetsize-ivlen-bypass-aadlen_pkt-antireplay */
+ *tp++=0x07000000 | ((packetsize-ivlen-bypass-aadlen_pkt-antireplay)&0x1ffffu)<<0;
+ /* INS CRYPTHASH,PAD_ZERO,0,pad_bytes_basic,LAST,LASTHASH */
+ *tp++=0x2f020000 | ((0u)&0x1u)<<16 | ((pad_bytes_basic)&0xffffu)<<0;
+ }
+ else
+ {
+ /* DIR CRYPTHASH,packetsize-ivlen-bypass-aadlen_pkt-antireplay,LAST,LASTHASH */
+ *tp++=0x0f020000 | ((packetsize-ivlen-bypass-aadlen_pkt-antireplay)&0x1ffffu)<<0;
+ }
+ appendhash = EVAL_appendhash();
+ if (antireplay > 0u)
+ {
+ /* RETR NONE,ORIG_HASH,antireplay,LASTHASHPKT */
+ *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+ /* VERIFY antireplay,H */
+ *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+ }
+ else if (appendhash > 0u)
+ {
+ /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+ *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ }
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+ hstatelen = EVAL_hstatelen();
+ *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+ if (hstatelen > 16u)
+ {
+ /* CTX ORIG_SPI_RES,seq_offset+hstatelen-16,1,P,F ; Update block counter */
+ *tp++=0xe0c63800 | ((-16u+seq_offset+hstatelen)&0xffu)<<0 | ((1u)&0xfu)<<24;
+ }
+ }
+ upd_handling = EVAL_upd_handling();
+ switch(upd_handling)
+ {
+ case 0: /* upd_null */
+ break;
+ case 1: /* upd_arc4 */
+ /* CTX ORIG_CHKSUM,iv_offset,1,P,F ; Update IJ pointer */
+ iv_offset = EVAL_iv_offset();
+ *tp++=0xe0ce3800 | ((iv_offset)&0xffu)<<0 | ((1u)&0xfu)<<24;
+ /* CTX ORIG_CHKSUM_STORE,0,1,P,F ; Update ARC4 state. */
+ *tp++=0xe0d63800 | ((0u)&0xffu)<<0 | ((1u)&0xfu)<<24;
+ break;
+ case 2: /* upd_iv2 */
+ /* CTX ORIG_IV0,iv_offset,2,P,F */
+ iv_offset = EVAL_iv_offset();
+ *tp++=0xe0a63800 | ((iv_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ break;
+ case 3: /* upd_iv4 */
+ /* CTX ORIG_IV0,iv_offset,4,P,F */
+ iv_offset = EVAL_iv_offset();
+ *tp++=0xe0a63800 | ((iv_offset)&0xffu)<<0 | ((4u)&0xfu)<<24;
+ break;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 15: /* basic_out_ccm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ aadlen_pkt = EVAL_aadlen_pkt();
+ ivlen = EVAL_ivlen();
+ if (packetsize < bypass+aadlen_pkt+ivlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic out ccm\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* INS HASHONLY,ORIG_TOKEN,4 */
+ *tp++=0x22d80000 | ((4u)&0x1ffffu)<<0;
+ /* DATA32 basic_salt */
+ basic_salt = EVAL_basic_salt();
+ *tp++=0x00000000 | ((basic_salt)&0xffffffffu)<<0;
+ if (ivhandling == 5u)
+ {
+ /* RETR HASH,ORIG_IV1,8 ; IV from input packet, CTR. */
+ *tp++=0x43a80000 | ((8u)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASH, ORIG_IV1,8 */
+ *tp++=0x23a80000 | ((8u)&0x1ffffu)<<0;
+ }
+ aadlen_swap = EVAL_aadlen_swap();
+ if (aadlen_swap > 0u)
+ {
+ /* INS HASHONLY,ORIG_TOKEN,6 */
+ *tp++=0x22d80000 | ((6u)&0x1ffffu)<<0;
+ /* DATA32 basic_swaplen */
+ basic_swaplen = EVAL_basic_swaplen();
+ *tp++=0x00000000 | ((basic_swaplen)&0xffffffffu)<<0;
+ /* DATA32 aadlen_swap */
+ *tp++=0x00000000 | ((aadlen_swap)&0xffffffffu)<<0;
+ aadlen_tkn = EVAL_aadlen_tkn();
+ if (aadlen_tkn > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* INS HASH,ORIG_TOKEN,aadlen_tkn */
+ *tp++=0x23d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn */
+ *tp++=0x22d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ aad = EVAL_aad();
+ if (aadlen_tkn > 64)
+ {
+ LOG_CRIT("Field too large\n");
+ return TKB_BAD_FIELD_SIZE;
+ }
+ TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+ tp += (aadlen_tkn + 3)/4;
+ }
+ else if (aadlen_pkt > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* DIR HASH,aadlen_pkt */
+ *tp++=0x03000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASHONLY,aadlen_pkt */
+ *tp++=0x02000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ }
+ /* INS HASHONLY,PAD_ZERO,0,aadpad */
+ aadpad = EVAL_aadpad();
+ *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((aadpad)&0xffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_TOKEN,4 */
+ *tp++=0x22d80000 | ((4u)&0x1ffffu)<<0;
+ /* DATA32 basic_swaplen */
+ basic_swaplen = EVAL_basic_swaplen();
+ *tp++=0x00000000 | ((basic_swaplen)&0xffffffffu)<<0;
+ }
+ /* REMRES bypass+8+aadlen_out,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((8u+bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ /* INS CRYPT,PAD_ZERO,0,16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ basic_hashpad = EVAL_basic_hashpad();
+ if (basic_hashpad == 0u)
+ {
+ /* DIR CRYPTHASH,packetsize-aadlen_pkt-ivlen-bypass,LAST,LASTHASH */
+ *tp++=0x0f020000 | ((packetsize-aadlen_pkt-ivlen-bypass)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR CRYPTHASH,packetsize-aadlen_pkt-ivlen-bypass,LAST */
+ *tp++=0x0f000000 | ((packetsize-aadlen_pkt-ivlen-bypass)&0x1ffffu)<<0;
+ /* INS HASHONLY,PAD_ZERO,0,basic_hashpad,LASTHASH */
+ *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((basic_hashpad)&0xffffu)<<0;
+ }
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+ *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+ hstatelen = EVAL_hstatelen();
+ *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+ }
+ else
+ {
+ /* INS OUT, ORIG_HASH, icvlen, LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 16: /* basic_in_ccm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ aadlen_pkt = EVAL_aadlen_pkt();
+ ivlen = EVAL_ivlen();
+ antireplay = EVAL_antireplay();
+ if (packetsize < bypass+aadlen_pkt+ivlen+antireplay)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic in ccm\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* INS HASHONLY,ORIG_TOKEN,4 */
+ *tp++=0x22d80000 | ((4u)&0x1ffffu)<<0;
+ /* DATA32 basic_salt */
+ basic_salt = EVAL_basic_salt();
+ *tp++=0x00000000 | ((basic_salt)&0xffffffffu)<<0;
+ if (ivhandling == 0u)
+ {
+ /* RETR HASHONLY,ORIG_IV1,8 ; IV from input packet, CTR. */
+ *tp++=0x42a80000 | ((8u)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_IV1,8 */
+ *tp++=0x22a80000 | ((8u)&0x1ffffu)<<0;
+ }
+ aadlen_swap = EVAL_aadlen_swap();
+ if (aadlen_swap > 0u)
+ {
+ /* INS HASHONLY,ORIG_TOKEN,6 */
+ *tp++=0x22d80000 | ((6u)&0x1ffffu)<<0;
+ /* DATA32 basic_swaplen */
+ basic_swaplen = EVAL_basic_swaplen();
+ *tp++=0x00000000 | ((basic_swaplen)&0xffffffffu)<<0;
+ /* DATA32 aadlen_swap */
+ *tp++=0x00000000 | ((aadlen_swap)&0xffffffffu)<<0;
+ aadlen_tkn = EVAL_aadlen_tkn();
+ if (aadlen_tkn > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* INS HASH,ORIG_TOKEN,aadlen_tkn */
+ *tp++=0x23d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn */
+ *tp++=0x22d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ aad = EVAL_aad();
+ if (aadlen_tkn > 64)
+ {
+ LOG_CRIT("Field too large\n");
+ return TKB_BAD_FIELD_SIZE;
+ }
+ TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+ tp += (aadlen_tkn + 3)/4;
+ }
+ else if (aadlen_pkt > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* DIR HASH,aadlen_pkt */
+ *tp++=0x03000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASHONLY,aadlen_pkt */
+ *tp++=0x02000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ }
+ /* INS HASHONLY,PAD_ZERO,0,aadpad */
+ aadpad = EVAL_aadpad();
+ *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((aadpad)&0xffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_TOKEN,4 */
+ *tp++=0x22d80000 | ((4u)&0x1ffffu)<<0;
+ /* DATA32 basic_swaplen */
+ basic_swaplen = EVAL_basic_swaplen();
+ *tp++=0x00000000 | ((basic_swaplen)&0xffffffffu)<<0;
+ }
+ /* REMRES bypass+aadlen_out,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ /* INS CRYPT,PAD_ZERO,0,16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ basic_hashpad = EVAL_basic_hashpad();
+ if (basic_hashpad == 0u)
+ {
+ /* DIR CRYPTHASH,packetsize-aadlen_pkt-ivlen-bypass-icvlen,LAST,LASTHASH */
+ icvlen = EVAL_icvlen();
+ *tp++=0x0f020000 | ((packetsize-aadlen_pkt-ivlen-bypass-icvlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR CRYPTHASH,packetsize-aadlen_pkt-ivlen-bypass-icvlen,LAST */
+ icvlen = EVAL_icvlen();
+ *tp++=0x0f000000 | ((packetsize-aadlen_pkt-ivlen-bypass-icvlen)&0x1ffffu)<<0;
+ /* INS HASHONLY,PAD_ZERO,0,basic_hashpad,LASTHASH */
+ *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((basic_hashpad)&0xffffu)<<0;
+ }
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+ *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+ hstatelen = EVAL_hstatelen();
+ *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+ }
+ else
+ {
+ /* RETR NONE, ORIG_HASH, antireplay, LASTHASHPKT */
+ *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+ /* VERIFY antireplay,H */
+ *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 17: /* basic_out_gcm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ aadlen_pkt = EVAL_aadlen_pkt();
+ ivlen = EVAL_ivlen();
+ if (packetsize < bypass+aadlen_pkt+ivlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic out gcm\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ aadlen_tkn = EVAL_aadlen_tkn();
+ if (aadlen_tkn > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* INS HASH,ORIG_TOKEN,aadlen_tkn,LAST */
+ *tp++=0x2bd80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn,LAST */
+ *tp++=0x2ad80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ aad = EVAL_aad();
+ if (aadlen_tkn > 64)
+ {
+ LOG_CRIT("Field too large\n");
+ return TKB_BAD_FIELD_SIZE;
+ }
+ TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+ tp += (aadlen_tkn + 3)/4;
+ }
+ else
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* DIR HASH,aadlen_pkt,LAST */
+ *tp++=0x0b000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASHONLY,aadlen_pkt,LAST */
+ *tp++=0x0a000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ }
+ switch(ivhandling)
+ {
+ case 0: /* iv_inbound_ctr */
+ /* RETR NONE,ORIG_IV1,8 ; IV from input packet, CTR. */
+ *tp++=0x40a80000 | ((8u)&0x1ffffu)<<0;
+ /* REMRES bypass+aadlen_out,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ break;
+ case 5: /* iv_copy_ctr */
+ if (aadlen_pkt+aadlen_tkn == 0u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, null aad illegal for gcm and copy iv\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* RETR OUT,ORIG_IV1,8 ; IV from input packet, copy iv */
+ *tp++=0x41a80000 | ((8u)&0x1ffffu)<<0;
+ /* REMRES bypass+aadlen_out+8,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((8u+bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ break;
+ case 15: /* iv_copy_token_4words */
+ case 2: /* iv_outbound_ctr */
+ if (aadlen_pkt+aadlen_tkn == 0u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, null aad illegal for gcm and copy iv\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* INS OUT,ORIG_IV1,8 ; IV from token, copy iv */
+ *tp++=0x21a80000 | ((8u)&0x1ffffu)<<0;
+ /* REMRES bypass+aadlen_out+8,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((8u+bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ break;
+ default:
+ /* REMRES bypass+aadlen_out,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ }
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ /* DIR CRYPTHASH,packetsize - bypass - aadlen_pkt - ivlen, LAST,LASTHASH */
+ *tp++=0x0f020000 | ((packetsize-bypass-aadlen_pkt-ivlen)&0x1ffffu)<<0;
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+ *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+ hstatelen = EVAL_hstatelen();
+ *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+ }
+ else
+ {
+ /* INS OUT, ORIG_HASH, icvlen, LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 18: /* basic_in_gcm */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ aadlen_pkt = EVAL_aadlen_pkt();
+ ivlen = EVAL_ivlen();
+ antireplay = EVAL_antireplay();
+ if (packetsize < bypass+aadlen_pkt+ivlen+antireplay)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic in gcm\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ aadlen_tkn = EVAL_aadlen_tkn();
+ if (aadlen_tkn > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* INS HASH,ORIG_TOKEN,aadlen_tkn,LAST */
+ *tp++=0x2bd80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn,LAST */
+ *tp++=0x2ad80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ aad = EVAL_aad();
+ if (aadlen_tkn > 64)
+ {
+ LOG_CRIT("Field too large\n");
+ return TKB_BAD_FIELD_SIZE;
+ }
+ TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+ tp += (aadlen_tkn + 3)/4;
+ }
+ else
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* DIR HASH,aadlen_pkt,LAST */
+ *tp++=0x0b000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASHONLY,aadlen_pkt,LAST */
+ *tp++=0x0a000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ }
+ switch(ivhandling)
+ {
+ case 0: /* iv_inbound_ctr */
+ /* RETR NONE,ORIG_IV1,8 ; IV from input packet, CTR. */
+ *tp++=0x40a80000 | ((8u)&0x1ffffu)<<0;
+ /* REMRES bypass+aadlen_out,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ break;
+ case 5: /* iv_copy_ctr */
+ if (aadlen_pkt+aadlen_tkn == 0u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, null aad illegal for gcm and copy iv\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* RETR OUT,ORIG_IV1,8 ; IV from input packet, copy iv */
+ *tp++=0x41a80000 | ((8u)&0x1ffffu)<<0;
+ /* REMRES bypass+aadlen_out+8,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((8u+bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ break;
+ case 15: /* iv_copy_token_4words */
+ case 2: /* iv_outbound_ctr */
+ if (aadlen_pkt+aadlen_tkn == 0u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, null aad illegal for gcm and copy iv\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* INS OUT,ORIG_IV1,8 ; IV from token, copy iv */
+ *tp++=0x21a80000 | ((8u)&0x1ffffu)<<0;
+ /* REMRES bypass+aadlen_out+8,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((8u+bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ break;
+ default:
+ /* REMRES bypass+aadlen_out,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((bypass+aadlen_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ }
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ /* DIR CRYPTHASH,packetsize - bypass - aadlen_pkt - ivlen - icvlen, LAST,LASTHASH */
+ icvlen = EVAL_icvlen();
+ *tp++=0x0f020000 | ((packetsize-bypass-aadlen_pkt-ivlen-icvlen)&0x1ffffu)<<0;
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+ *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+ hstatelen = EVAL_hstatelen();
+ *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+ }
+ else
+ {
+ /* RETR NONE, ORIG_HASH, antireplay, LASTHASHPKT */
+ *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+ /* VERIFY antireplay,H */
+ *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 19: /* basic_out_gmac */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ aadlen_pkt = EVAL_aadlen_pkt();
+ ivlen = EVAL_ivlen();
+ if (packetsize < bypass+aadlen_pkt+ivlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic out gmac\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ aadlen_tkn = EVAL_aadlen_tkn();
+ if (aadlen_tkn > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* INS HASH,ORIG_TOKEN,aadlen_tkn */
+ *tp++=0x23d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn */
+ *tp++=0x22d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ aad = EVAL_aad();
+ if (aadlen_tkn > 64)
+ {
+ LOG_CRIT("Field too large\n");
+ return TKB_BAD_FIELD_SIZE;
+ }
+ TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+ tp += (aadlen_tkn + 3)/4;
+ }
+ else if (aadlen_pkt > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* DIR HASH,aadlen_pkt */
+ *tp++=0x03000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASHONLY,aadlen_pkt */
+ *tp++=0x02000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ }
+ switch(ivhandling)
+ {
+ case 0: /* iv_inbound_ctr */
+ /* RETR HASHONLY,ORIG_IV1,8 ; IV from input packet, CTR. */
+ *tp++=0x42a80000 | ((8u)&0x1ffffu)<<0;
+ /* DIR HASH,packetsize - bypass - aadlen_pkt - ivlen, LAST,LASTHASH */
+ *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen)&0x1ffffu)<<0;
+ /* REMRES packetsize+aadlen_out-aadlen_pkt-ivlen,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((packetsize+aadlen_out-aadlen_pkt-ivlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ break;
+ case 5: /* iv_copy_ctr */
+ /* RETR HASH,ORIG_IV1,8 ; IV from input packet, copy iv */
+ *tp++=0x43a80000 | ((8u)&0x1ffffu)<<0;
+ /* DIR HASH,packetsize - bypass - aadlen_pkt - ivlen, LAST,LASTHASH */
+ *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen)&0x1ffffu)<<0;
+ /* REMRES packetsize+aadlen_out-aadlen_pkt-ivlen+8,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((8u+packetsize+aadlen_out-aadlen_pkt-ivlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ break;
+ case 15: /* iv_copy_token_4words */
+ case 2: /* iv_outbound_ctr */
+ /* INS OUT,ORIG_IV1,8 ; IV from token, copy iv. */
+ *tp++=0x21a80000 | ((8u)&0x1ffffu)<<0;
+ /* DIR HASH,packetsize - bypass - aadlen_pkt - ivlen, LAST,LASTHASH */
+ *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen)&0x1ffffu)<<0;
+ /* REMRES packetsize+aadlen_out-aadlen_pkt-ivlen+8,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((8u+packetsize+aadlen_out-aadlen_pkt-ivlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ break;
+ default:
+ /* DIR HASH,packetsize - bypass - aadlen_pkt - ivlen, LAST,LASTHASH */
+ *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen)&0x1ffffu)<<0;
+ /* REMRES packetsize+aadlen_out-aadlen_pkt-ivlen,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((packetsize+aadlen_out-aadlen_pkt-ivlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ }
+ /* INS CRYPT, PAD_ZERO, 0, 16,LAST */
+ *tp++=0x2d000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+ *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+ hstatelen = EVAL_hstatelen();
+ *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+ }
+ else
+ {
+ /* INS OUT, ORIG_HASH, icvlen, LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 20: /* basic_in_gmac */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ aadlen_pkt = EVAL_aadlen_pkt();
+ ivlen = EVAL_ivlen();
+ antireplay = EVAL_antireplay();
+ if (packetsize < bypass+aadlen_pkt+ivlen+antireplay)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic in gmac\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ aadlen_tkn = EVAL_aadlen_tkn();
+ if (aadlen_tkn > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* INS HASH,ORIG_TOKEN,aadlen_tkn */
+ *tp++=0x23d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn */
+ *tp++=0x22d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ aad = EVAL_aad();
+ if (aadlen_tkn > 64)
+ {
+ LOG_CRIT("Field too large\n");
+ return TKB_BAD_FIELD_SIZE;
+ }
+ TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+ tp += (aadlen_tkn + 3)/4;
+ }
+ else if (aadlen_pkt > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* DIR HASH,aadlen_pkt */
+ *tp++=0x03000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASHONLY,aadlen_pkt */
+ *tp++=0x02000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ }
+ switch(ivhandling)
+ {
+ case 0: /* iv_inbound_ctr */
+ /* RETR HASHONLY,ORIG_IV1,8 ; IV from input packet, CTR. */
+ *tp++=0x42a80000 | ((8u)&0x1ffffu)<<0;
+ /* DIR HASH,packetsize - bypass - aadlen_pkt - ivlen - icvlen, LAST,LASTHASH */
+ icvlen = EVAL_icvlen();
+ *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen-icvlen)&0x1ffffu)<<0;
+ /* REMRES packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ break;
+ case 5: /* iv_copy_ctr */
+ /* RETR HASH,ORIG_IV1,8 ; IV from input packet, copy iv */
+ *tp++=0x43a80000 | ((8u)&0x1ffffu)<<0;
+ /* DIR HASH,packetsize - bypass - aadlen_pkt - ivlen - icvlen, LAST,LASTHASH */
+ icvlen = EVAL_icvlen();
+ *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen-icvlen)&0x1ffffu)<<0;
+ /* REMRES packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen+8,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((8u+packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ break;
+ case 15: /* iv_copy_token_4words */
+ case 2: /* iv_outbound_ctr */
+ /* INS OUT,ORIG_IV1,8 ; IV from token, copy iv Do not authenticate IV */
+ *tp++=0x21a80000 | ((8u)&0x1ffffu)<<0;
+ /* DIR HASH,packetsize - bypass - aadlen_pkt - ivlen - icvlen, LAST,LASTHASH */
+ icvlen = EVAL_icvlen();
+ *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen-icvlen)&0x1ffffu)<<0;
+ /* REMRES packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen+8,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((8u+packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ break;
+ default:
+ /* DIR HASH,packetsize - bypass - aadlen_pkt - ivlen - icvlen, LAST,LASTHASH */
+ icvlen = EVAL_icvlen();
+ *tp++=0x0b020000 | ((packetsize-bypass-aadlen_pkt-ivlen-icvlen)&0x1ffffu)<<0;
+ /* REMRES packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen,16 */
+ aadlen_out = EVAL_aadlen_out();
+ *tp++=0xa0000000 | ((packetsize+aadlen_out-aadlen_pkt-ivlen-icvlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ }
+ /* INS CRYPT, PAD_ZERO, 0, 16,LAST */
+ *tp++=0x2d000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ seq_offset = EVAL_seq_offset();
+ if (seq_offset > 0u)
+ {
+ /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+ *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ /* CTX ORIG_HASH,seq_offset,hstatelen,P,F */
+ hstatelen = EVAL_hstatelen();
+ *tp++=0xe0e63800 | ((seq_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+ }
+ else
+ {
+ /* RETR NONE, ORIG_HASH, antireplay, LASTHASHPKT */
+ *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+ /* VERIFY antireplay,H */
+ *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 23: /* basic_xts_crypto */
+#if TKB_HAVE_CRYPTO_XTS == 1u
+ ivlen = EVAL_ivlen();
+ if (packetsize < ivlen+bypass)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic crypto\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ swap_j = EVAL_swap_j();
+ if (swap_j != 0u)
+ {
+ /* INSCTX NONE,ORIG_TOKEN,10,16 */
+ *tp++=0x90d80000 | ((10u)&0x1fu)<<12 | ((16u)&0x1ffu)<<0;
+ /* DATA32 0 */
+ *tp++=0x00000000 | ((0u)&0xffffffffu)<<0;
+ /* DATA32 0 */
+ *tp++=0x00000000 | ((0u)&0xffffffffu)<<0;
+ /* DATA32 0 */
+ *tp++=0x00000000 | ((0u)&0xffffffffu)<<0;
+ /* DATA32 swap_j */
+ *tp++=0x00000000 | ((swap_j)&0xffffffffu)<<0;
+ }
+ switch(ivhandling)
+ {
+ case 1: /* iv_inbound_cbc */
+ /* RETR NONE,ORIG_IV0,ivlen ; IV from input packet CBC */
+ *tp++=0x40a00000 | ((ivlen)&0x1ffffu)<<0;
+ break;
+ case 4: /* iv_copy_cbc */
+ /* RETR OUT,ORIG_IV0,ivlen ; IV from input packet CBC */
+ *tp++=0x41a00000 | ((ivlen)&0x1ffffu)<<0;
+ break;
+ case 7: /* iv_outbound_4words */
+ case 15: /* iv_copy_token_4words */
+ /* INS OUT,ORIG_IV0,16 */
+ *tp++=0x21a00000 | ((16u)&0x1ffffu)<<0;
+ break;
+ }
+ /* DIR CRYPT,packetsize-ivlen-bypass */
+ *tp++=0x05000000 | ((packetsize-ivlen-bypass)&0x1ffffu)<<0;
+ /* INS CRYPT,PAD_ZERO,0,pad_bytes_basic,LAST,LASTHASHPKT */
+ pad_bytes_basic = EVAL_pad_bytes_basic();
+ *tp++=0x2d060000 | ((0u)&0x1u)<<16 | ((pad_bytes_basic)&0xffffu)<<0;
+ upd_handling = EVAL_upd_handling();
+ switch(upd_handling)
+ {
+ case 0: /* upd_null */
+ break;
+ case 3: /* upd_iv4 */
+ /* CTX ORIG_IV0,iv_offset,4,P,F */
+ iv_offset = EVAL_iv_offset();
+ *tp++=0xe0a63800 | ((iv_offset)&0xffu)<<0 | ((4u)&0xfu)<<24;
+ break;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 24: /* basic_kasumi_hash */
+#if TKB_HAVE_CRYPTO_WIRELESS == 1u
+ antireplay = EVAL_antireplay();
+ if (packetsize < bypass+antireplay)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic hash\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* INS HASHONLY,ORIG_TOKEN,8 */
+ *tp++=0x22d80000 | ((8u)&0x1ffffu)<<0;
+ /* DATA32 count */
+ count = EVAL_count();
+ *tp++=0x00000000 | ((count)&0xffffffffu)<<0;
+ /* DATA32 bearer_dir_fresh */
+ bearer_dir_fresh = EVAL_bearer_dir_fresh();
+ *tp++=0x00000000 | ((bearer_dir_fresh)&0xffffffffu)<<0;
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* DIR HASH,packetsize-bypass-antireplay,LASTHASH */
+ *tp++=0x03020000 | ((packetsize-bypass-antireplay)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASHONLY,packetsize-bypass-antireplay,LASTHASH */
+ *tp++=0x02020000 | ((packetsize-bypass-antireplay)&0x1ffffu)<<0;
+ }
+ appendhash = EVAL_appendhash();
+ if (antireplay > 0u)
+ {
+ /* RETR NONE,ORIG_HASH,antireplay,LASTHASHPKT */
+ *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+ /* VERIFY antireplay,H */
+ *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+ }
+ else if (appendhash > 0u)
+ {
+ /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+ *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 25: /* basic_snow_hash */
+ case 26: /* basic_zuc_hash */
+#if TKB_HAVE_CRYPTO_WIRELESS == 1u
+ antireplay = EVAL_antireplay();
+ if (packetsize < bypass+antireplay)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic hash\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* INSCTX NONE,ORIG_TOKEN,10,16 */
+ *tp++=0x90d80000 | ((10u)&0x1fu)<<12 | ((16u)&0x1ffu)<<0;
+ /* DATA32 count */
+ count = EVAL_count();
+ *tp++=0x00000000 | ((count)&0xffffffffu)<<0;
+ /* DATA32 bearer_dir_fresh */
+ bearer_dir_fresh = EVAL_bearer_dir_fresh();
+ *tp++=0x00000000 | ((bearer_dir_fresh)&0xffffffffu)<<0;
+ /* DATA32 count */
+ *tp++=0x00000000 | ((count)&0xffffffffu)<<0;
+ /* DATA32 bearer_dir_fresh */
+ *tp++=0x00000000 | ((bearer_dir_fresh)&0xffffffffu)<<0;
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* DIR HASH,packetsize-bypass-antireplay,LASTHASH */
+ *tp++=0x03020000 | ((packetsize-bypass-antireplay)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASHONLY,packetsize-bypass-antireplay,LASTHASH */
+ *tp++=0x02020000 | ((packetsize-bypass-antireplay)&0x1ffffu)<<0;
+ }
+ appendhash = EVAL_appendhash();
+ if (antireplay > 0u)
+ {
+ /* RETR NONE,ORIG_HASH,antireplay,LASTHASHPKT */
+ *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+ /* VERIFY antireplay,H */
+ *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+ }
+ else if (appendhash > 0u)
+ {
+ /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS OUT,PAD_ZERO,0,0,LASTHASHPKT */
+ *tp++=0x21060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 27: /* basic_hashenc */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ aadlen_pkt = EVAL_aadlen_pkt();
+ ivlen = EVAL_ivlen();
+ if (packetsize < bypass+aadlen_pkt+ivlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic crypthash\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ aadlen_tkn = EVAL_aadlen_tkn();
+ if (aadlen_tkn > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* INS HASH,ORIG_TOKEN,aadlen_tkn */
+ *tp++=0x23d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn */
+ *tp++=0x22d80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ aad = EVAL_aad();
+ if (aadlen_tkn > 64)
+ {
+ LOG_CRIT("Field too large\n");
+ return TKB_BAD_FIELD_SIZE;
+ }
+ TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+ tp += (aadlen_tkn + 3)/4;
+ }
+ else if (aadlen_pkt > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* DIR HASH,aadlen_pkt */
+ *tp++=0x03000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASHONLY,aadlen_pkt */
+ *tp++=0x02000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ }
+ switch(ivhandling)
+ {
+ case 4: /* iv_copy_cbc */
+ /* RETR OUT,ORIG_IV0,ivlen ; IV from input packet CBC */
+ *tp++=0x41a00000 | ((ivlen)&0x1ffffu)<<0;
+ break;
+ case 6: /* iv_outbound_2words */
+ case 9: /* iv_copy_token_2words */
+ /* INS OUT,ORIG_IV0,8 */
+ *tp++=0x21a00000 | ((8u)&0x1ffffu)<<0;
+ break;
+ case 7: /* iv_outbound_4words */
+ case 15: /* iv_copy_token_4words */
+ /* INS OUT,ORIG_IV0,16 */
+ *tp++=0x21a00000 | ((16u)&0x1ffffu)<<0;
+ break;
+ }
+ /* DIR CRYPTHASH,packetsize-ivlen-bypass-aadlen_pkt,LASTHASH */
+ *tp++=0x07020000 | ((packetsize-ivlen-bypass-aadlen_pkt)&0x1ffffu)<<0;
+ /* INS CRYPT,ORIG_HASH,icvlen,LASTHASH */
+ icvlen = EVAL_icvlen();
+ *tp++=0x25e20000 | ((icvlen)&0x1ffffu)<<0;
+ /* INS CRYPT,PAD_TLS,0,pad_bytes_hashenc,LAST,LASTHASHPKT */
+ pad_bytes_hashenc = EVAL_pad_bytes_hashenc();
+ *tp++=0x2d2e0000 | ((0u)&0xffu)<<9 | ((pad_bytes_hashenc)&0x1ffu)<<0;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 28: /* basic_dechash */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ aadlen_pkt = EVAL_aadlen_pkt();
+ aadlen_tkn = EVAL_aadlen_tkn();
+ if (aadlen_pkt+aadlen_tkn < 2u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, aad too short\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* REMRES 0,4,NOUPDCHK */
+ *tp++=0xa0020000 | ((0u)&0xffffu)<<0 | ((4u)&0x3fu)<<19;
+ cipher_is_aes = EVAL_cipher_is_aes();
+ if (cipher_is_aes == 0u)
+ {
+ ivlen = EVAL_ivlen();
+ if (packetsize < 16u+bypass+aadlen_pkt+ivlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic dechash\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* INS CRYPTONLY,ORIG_TOKEN,12 */
+ *tp++=0x24d80000 | ((12u)&0x1ffffu)<<0;
+ ssltls_lastblock = EVAL_ssltls_lastblock();
+ TokenBuilder_CopyBytes(tp, ssltls_lastblock, 12);
+ tp += 3;
+ /* INS CRYPT,ORIG_TOKEN,4 */
+ *tp++=0x25d80000 | ((4u)&0x1ffffu)<<0;
+ ssltls_lastword = EVAL_ssltls_lastword();
+ TokenBuilder_CopyBytes(tp, ssltls_lastword, 4);
+ tp += 1;
+ }
+ else
+ {
+ ivlen = EVAL_ivlen();
+ if (packetsize < 32u+bypass+aadlen_pkt+ivlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic dechash\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* INS CRYPTONLY,ORIG_TOKEN,28 */
+ *tp++=0x24d80000 | ((28u)&0x1ffffu)<<0;
+ ssltls_lastblock = EVAL_ssltls_lastblock();
+ TokenBuilder_CopyBytes(tp, ssltls_lastblock, 28);
+ tp += 7;
+ /* INS CRYPT,ORIG_TOKEN,4 */
+ *tp++=0x25d80000 | ((4u)&0x1ffffu)<<0;
+ ssltls_lastword = EVAL_ssltls_lastword();
+ TokenBuilder_CopyBytes(tp, ssltls_lastword, 4);
+ tp += 1;
+ }
+ /* DIR NONE,0,LAST */
+ *tp++=0x08000000 | ((0u)&0x1ffffu)<<0;
+ if (bypass > 0u)
+ {
+ /* DIR OUT,bypass */
+ *tp++=0x01000000 | ((bypass)&0x1ffffu)<<0;
+ }
+ if (aadlen_tkn > 0u)
+ {
+ /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn-2 */
+ *tp++=0x22d80000 | ((-2u+aadlen_tkn)&0x1ffffu)<<0;
+ aad = EVAL_aad();
+ if (-2u+aadlen_tkn > 64)
+ {
+ LOG_CRIT("Field too large\n");
+ return TKB_BAD_FIELD_SIZE;
+ }
+ TokenBuilder_CopyBytes(tp, aad, -2u+aadlen_tkn);
+ tp += (-2u+aadlen_tkn + 3)/4;
+ }
+ else if (aadlen_pkt > 0u)
+ {
+ /* DIR HASHONLY,aadlen_pkt-2 */
+ *tp++=0x02000000 | ((-2u+aadlen_pkt)&0x1ffffu)<<0;
+ }
+ /* INS HASHONLY,ORIG_LENCOR,packetsize-bypass-aadlen_pkt-ivlen-icvlen-1 */
+ ivlen = EVAL_ivlen();
+ icvlen = EVAL_icvlen();
+ *tp++=0x22780000 | ((-1u+packetsize-bypass-aadlen_pkt-ivlen-icvlen)&0x1ffffu)<<0;
+ /* REM 2 */
+ *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+ if (ivlen > 0u)
+ {
+ /* RETR NONE,ORIG_IV0,ivlen */
+ *tp++=0x40a00000 | ((ivlen)&0x1ffffu)<<0;
+ }
+ /* REMRES bypass,icvlen,NOUPDCHK ; Cause the MAC to be removed */
+ *tp++=0xa0020000 | ((bypass)&0xffffu)<<0 | ((icvlen)&0x3fu)<<19;
+ /* DIRX CRYPTHASH,ORIG_LENCOR,0,LASTHASH */
+ *tp++=0x077a0000 | ((0u)&0x1ffffu)<<0;
+ /* DIRX CRYPT,ORIG_LENCOR,icvlen+1,LAST,LASTHASHPKT */
+ *tp++=0x0d7e0000 | ((1u+icvlen)&0x1ffffu)<<0;
+ /* VERIFY icvlen,P,H */
+ *tp++=0xd1070000 | ((icvlen)&0x7fu)<<0;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 12: /* srtp_out */
+#if TKB_HAVE_PROTO_SRTP == 1u
+ srtp_offset = EVAL_srtp_offset();
+ if (packetsize <= bypass+srtp_offset)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for SRTP outbound\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ if (srtp_offset > 0u)
+ {
+ /* DIR HASH, srtp_offset */
+ *tp++=0x03000000 | ((srtp_offset)&0x1ffffu)<<0;
+ /* DIR CRYPTHASH, packetsize - bypass - srtp_offset,LAST */
+ *tp++=0x0f000000 | ((packetsize-bypass-srtp_offset)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASH, packetsize - bypass,LAST */
+ *tp++=0x0b000000 | ((packetsize-bypass)&0x1ffffu)<<0;
+ }
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* INS HASH, ORIG_TOKEN, 4, LASTHASH ; SCTCP, index gets appended */
+ *tp++=0x23da0000 | ((4u)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY, ORIG_TOKEN, 4, LASTHASH ; SRTP, ROC gets hashed, not appended */
+ *tp++=0x22da0000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* DATA32 srtp_swaproc */
+ srtp_swaproc = EVAL_srtp_swaproc();
+ *tp++=0x00000000 | ((srtp_swaproc)&0xffffffffu)<<0;
+ antireplay = EVAL_antireplay();
+ if (antireplay > 0u)
+ {
+ /* INS OUT,ORIG_SPI,4,LASTHASH */
+ *tp++=0x21920000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* INS OUT, ORIG_HASH, icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 13: /* srtp_in */
+#if TKB_HAVE_PROTO_SRTP == 1u
+ srtp_offset = EVAL_srtp_offset();
+ icvlen = EVAL_icvlen();
+ extseq = EVAL_extseq();
+ antireplay = EVAL_antireplay();
+ if (packetsize <= bypass+srtp_offset+icvlen+extseq+antireplay)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for SRTP inbound\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ if (srtp_offset > 0u)
+ {
+ /* DIR HASH, srtp_offset */
+ *tp++=0x03000000 | ((srtp_offset)&0x1ffffu)<<0;
+ /* DIR CRYPTHASH, packetsize - bypass - srtp_offset - icvlen - extseq -antireplay,LAST */
+ *tp++=0x0f000000 | ((packetsize-bypass-srtp_offset-icvlen-extseq-antireplay)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASH, packetsize - bypass - icvlen - extseq -antireplay,LAST */
+ *tp++=0x0b000000 | ((packetsize-bypass-icvlen-extseq-antireplay)&0x1ffffu)<<0;
+ }
+ if (extseq > 0u)
+ {
+ /* DIR HASHONLY, 4, LASTHASH ; SCTCP extraxt from packet. */
+ *tp++=0x02020000 | ((4u)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY, ORIG_TOKEN, 4, LASTHASH ; SRTP, ROC gets hashed, not appended */
+ *tp++=0x22da0000 | ((4u)&0x1ffffu)<<0;
+ /* DATA32 srtp_swaproc */
+ srtp_swaproc = EVAL_srtp_swaproc();
+ *tp++=0x00000000 | ((srtp_swaproc)&0xffffffffu)<<0;
+ }
+ if (antireplay > 0u)
+ {
+ /* RETR NONE,ORIG_SPI,4 */
+ *tp++=0x40900000 | ((4u)&0x1ffffu)<<0;
+ }
+ if (icvlen > 0u)
+ {
+ /* RETR NONE,ORIG_HASH, icvlen,LASTHASHPKT */
+ *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+ if (antireplay > 0u)
+ {
+ /* VERIFY icvlen,H,SP */
+ *tp++=0xd4070000 | ((icvlen)&0x7fu)<<0;
+ }
+ else
+ {
+ /* VERIFY icvlen,H */
+ *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+ }
+ }
+ else
+ {
+ /* INS NONE,PAD_ZERO,0,0,LASTHASHPKT */
+ *tp++=0x20060000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ if (antireplay > 0u)
+ {
+ /* VERIFY 0,SP */
+ *tp++=0xd4060000 | ((0u)&0x7fu)<<0;
+ }
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 29: /* basic_out_chachapoly */
+#if TKB_HAVE_PROTO_BASIC == 1u
+#if TKB_HAVE_CRYPTO_CHACHAPOLY == 1u
+ aadlen_pkt = EVAL_aadlen_pkt();
+ ivlen = EVAL_ivlen();
+ if (packetsize < bypass+aadlen_pkt+ivlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic out ccm\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ aadlen_tkn = EVAL_aadlen_tkn();
+ if (aadlen_tkn > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* INS HASH,ORIG_TOKEN,aadlen_tkn,LAST */
+ *tp++=0x2bd80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn,LAST */
+ *tp++=0x2ad80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ aad = EVAL_aad();
+ if (aadlen_tkn > 64)
+ {
+ LOG_CRIT("Field too large\n");
+ return TKB_BAD_FIELD_SIZE;
+ }
+ TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+ tp += (aadlen_tkn + 3)/4;
+ }
+ else if (aadlen_pkt > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* DIR HASH,aadlen_pkt,LAST */
+ *tp++=0x0b000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASHONLY,aadlen_pkt,LAST */
+ *tp++=0x0a000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ }
+ else
+ {
+ /* INS HASHONLY,PAD_ZERO,0,0,LAST */
+ *tp++=0x2a000000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ }
+ /* DIR CRYPTHASH,packetsize-aadlen_pkt-ivlen-bypass,LAST,LASTHASH */
+ *tp++=0x0f020000 | ((packetsize-aadlen_pkt-ivlen-bypass)&0x1ffffu)<<0;
+ /* INS OUT, ORIG_HASH, icvlen, LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+#else
+ LOG_WARN("TokenBuilder: bad crypto\n");
+ rc = TKB_BAD_CRYPTO; goto error;
+#endif
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 30: /* basic_in_chachapoly */
+#if TKB_HAVE_PROTO_BASIC == 1u
+#if TKB_HAVE_CRYPTO_CHACHAPOLY == 1u
+ aadlen_pkt = EVAL_aadlen_pkt();
+ ivlen = EVAL_ivlen();
+ if (packetsize < bypass+aadlen_pkt+ivlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic out ccm\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ aadlen_tkn = EVAL_aadlen_tkn();
+ if (aadlen_tkn > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* INS HASH,ORIG_TOKEN,aadlen_tkn,LAST */
+ *tp++=0x2bd80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_TOKEN,aadlen_tkn,LAST */
+ *tp++=0x2ad80000 | ((aadlen_tkn)&0x1ffffu)<<0;
+ }
+ aad = EVAL_aad();
+ if (aadlen_tkn > 64)
+ {
+ LOG_CRIT("Field too large\n");
+ return TKB_BAD_FIELD_SIZE;
+ }
+ TokenBuilder_CopyBytes(tp, aad, aadlen_tkn);
+ tp += (aadlen_tkn + 3)/4;
+ }
+ else if (aadlen_pkt > 0u)
+ {
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* DIR HASH,aadlen_pkt,LAST */
+ *tp++=0x0b000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* DIR HASHONLY,aadlen_pkt,LAST */
+ *tp++=0x0a000000 | ((aadlen_pkt)&0x1ffffu)<<0;
+ }
+ }
+ else
+ {
+ /* INS HASHONLY,PAD_ZERO,0,0,LAST */
+ *tp++=0x2a000000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ }
+#if TKB_HAVE_CHACHAPOLY_HW30 == 1u
+ /* INS NONE,PAD_ZERO,0,176 */
+ *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((176u)&0xffffu)<<0;
+#else
+ /* INS NONE,PAD_ZERO,0,16 */
+ *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+#endif
+ /* DIR CRYPTHASH,packetsize-aadlen_pkt-ivlen-bypass-icvlen,LAST,LASTHASH */
+ icvlen = EVAL_icvlen();
+ *tp++=0x0f020000 | ((packetsize-aadlen_pkt-ivlen-bypass-icvlen)&0x1ffffu)<<0;
+ /* RETR NONE, ORIG_HASH, antireplay, LASTHASHPKT */
+ antireplay = EVAL_antireplay();
+ *tp++=0x40e60000 | ((antireplay)&0x1ffffu)<<0;
+ /* VERIFY antireplay,H */
+ *tp++=0xd0070000 | ((antireplay)&0x7fu)<<0;
+#else
+ LOG_WARN("TokenBuilder: bad crypto\n");
+ rc = TKB_BAD_CRYPTO; goto error;
+#endif
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 31: /* tls13_gcm_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ if (packetsize < bypass)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS outbound GCM\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* INS HASH,PAD_CONST,0x17,1 ; Type field */
+ *tp++=0x23100000 | ((23u)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ /* INS HASH,ORIG_SPI,2 ; For TLS1.3 hash fixed type/version field. */
+ *tp++=0x23900000 | ((2u)&0x1ffffu)<<0;
+ /* INS HASH,ORIG_TOKEN,2,LAST */
+ *tp++=0x2bd80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swap_fraglen_tls13 ; Fragment length to output and hash. */
+ swap_fraglen_tls13 = EVAL_swap_fraglen_tls13();
+ *tp++=0x00000000 | ((swap_fraglen_tls13)&0xffffffffu)<<0;
+ /* REMRES bypass + 5, 16 */
+ *tp++=0xa0000000 | ((5u+bypass)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ /* DIR CRYPTHASH, packetsize-bypass */
+ *tp++=0x07000000 | ((packetsize-bypass)&0x1ffffu)<<0;
+ count = EVAL_count();
+ if (count == 0u)
+ {
+ /* INS CRYPTHASH, PAD_CONST, nextheader, 1, LAST, LASTHASH */
+ nextheader = EVAL_nextheader();
+ *tp++=0x2f120000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ }
+ else
+ {
+ /* INS CRYPTHASH, PAD_CONST, nextheader, 1 */
+ nextheader = EVAL_nextheader();
+ *tp++=0x27100000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ /* INS CRYPTHASH, PAD_ZERO, 0, count, LAST, LASTHASH */
+ *tp++=0x2f020000 | ((0u)&0x1u)<<16 | ((count)&0xffffu)<<0;
+ }
+ /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ /* VERIFY 0 ; Causes any sequence number rollover error to fail the packet. */
+ *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2 */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 32: /* tls13_gcm_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ icvlen = EVAL_icvlen();
+ if (packetsize < 5u+bypass+icvlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS inbound GCM\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* DIR HASHONLY,5,LAST ; Hash type and version number and length */
+ *tp++=0x0a000000 | ((5u)&0x1ffffu)<<0;
+ /* REMRES bypass, 16 */
+ *tp++=0xa0000000 | ((bypass)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ /* DIR CRYPTHASH, packetsize-bypass-icvlen-5,LAST,LASTHASH */
+ *tp++=0x0f020000 | ((-5u+packetsize-bypass-icvlen)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+ *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+ /* VERIFY icvlen,H */
+ *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 33: /* tls13_chachapoly_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ if (packetsize < bypass)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS outbound ChaChaPoly\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* INS HASH,PAD_CONST,0x17,1 ; Type field */
+ *tp++=0x23100000 | ((23u)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ /* INS HASH,ORIG_SPI,2 ; For TLS1.3 hash fixed type/version field. */
+ *tp++=0x23900000 | ((2u)&0x1ffffu)<<0;
+ /* INS HASH,ORIG_TOKEN,2,LAST */
+ *tp++=0x2bd80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swap_fraglen_tls13 ; Fragment length to output and hash. */
+ swap_fraglen_tls13 = EVAL_swap_fraglen_tls13();
+ *tp++=0x00000000 | ((swap_fraglen_tls13)&0xffffffffu)<<0;
+ /* DIR CRYPTHASH, packetsize-bypass */
+ *tp++=0x07000000 | ((packetsize-bypass)&0x1ffffu)<<0;
+ count = EVAL_count();
+ if (count == 0u)
+ {
+ /* INS CRYPTHASH, PAD_CONST, nextheader, 1, LAST, LASTHASH */
+ nextheader = EVAL_nextheader();
+ *tp++=0x2f120000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ }
+ else
+ {
+ /* INS CRYPTHASH, PAD_CONST, nextheader, 1 */
+ nextheader = EVAL_nextheader();
+ *tp++=0x27100000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ /* INS CRYPTHASH, PAD_ZERO, 0, count, LAST, LASTHASH */
+ *tp++=0x2f020000 | ((0u)&0x1u)<<16 | ((count)&0xffffu)<<0;
+ }
+ /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ /* VERIFY 0 ; Causes any sequence number rollover error to fail the packet. */
+ *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2 */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 34: /* tls13_chachapoly_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ icvlen = EVAL_icvlen();
+ if (packetsize < 5u+bypass+icvlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS inbound ChaChaPoly\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* DIR HASHONLY,5,LAST ; Hash type and version number and length */
+ *tp++=0x0a000000 | ((5u)&0x1ffffu)<<0;
+ /* INS NONE, PAD_ZERO, 0, 16 */
+ *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ /* DIR CRYPTHASH, packetsize-bypass-icvlen-5,LAST,LASTHASH */
+ *tp++=0x0f020000 | ((-5u+packetsize-bypass-icvlen)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+ *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+ /* VERIFY icvlen,H */
+ *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 35: /* esp_out_chachapoly */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ if (packetsize <= bypass+hdrlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for ESP outbound ChaChaPoly\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ extseq = EVAL_extseq();
+ if (extseq == 0u)
+ {
+ /* INS HASH,ORIG_SPI,8,LAST */
+ *tp++=0x2b900000 | ((8u)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASH,ORIG_SPI,4 */
+ *tp++=0x23900000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY, ORIG_EXTSEQNUM_RES2, 4 */
+ *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASH,ORIG_SEQNUM_RES, 4, LAST */
+ *tp++=0x2b980000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* INS OUT,ORIG_IV1,ivlen */
+ ivlen = EVAL_ivlen();
+ *tp++=0x21a80000 | ((ivlen)&0x1ffffu)<<0;
+ /* DIR CRYPTHASH, packetsize-bypass-hdrlen */
+ *tp++=0x07000000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+ /* INS CRYPTHASH,PAD_IPSEC,nextheader,pad_bytes,LAST,LASTHASH */
+ nextheader = EVAL_nextheader();
+ pad_bytes = EVAL_pad_bytes();
+ *tp++=0x2f220000 | ((nextheader)&0xffu)<<9 | ((pad_bytes)&0x1ffu)<<0;
+ /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ /* VERIFY 0 ; Causes any sequence number rollover error to fail the packet. */
+ *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,1+extseq */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 36: /* esp_in_chachapoly */
+#if TKB_HAVE_PROTO_IPSEC == 1u
+ ivlen = EVAL_ivlen();
+ icvlen = EVAL_icvlen();
+ pad_blocksize = EVAL_pad_blocksize();
+ if (packetsize < 8u+ivlen+icvlen+pad_blocksize+bypass+hdrlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for ESP inbound ChaChaPoly\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ pad_remainder = EVAL_pad_remainder();
+ if (pad_remainder != 0u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, pad alignment ESP inbound ChaChaPoly\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ extseq = EVAL_extseq();
+ if (extseq != 1u)
+ {
+ /* RETR HASHONLY,ORIG_SPI,8,LAST */
+ *tp++=0x4a900000 | ((8u)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_IV1,ivlen */
+ *tp++=0x40a80000 | ((ivlen)&0x1ffffu)<<0;
+#if TKB_HAVE_ECN_FIXUP == 1u
+ /* DATA32 ecn_fixup_instr */
+ ecn_fixup_instr = EVAL_ecn_fixup_instr();
+ *tp++=0x00000000 | ((ecn_fixup_instr)&0xffffffffu)<<0;
+#endif
+ /* INS NONE, PAD_ZERO, 0, 16 */
+ *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ }
+ else
+ {
+ /* RETR HASHONLY,ORIG_SPI,4 */
+ *tp++=0x42900000 | ((4u)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_SEQNUM_RES,4 */
+ *tp++=0x40980000 | ((4u)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_IV1,ivlen */
+ *tp++=0x40a80000 | ((ivlen)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_EXTSEQNUM_RES2, 4 */
+ *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SEQNUM_RES,4,LAST */
+ *tp++=0x2a980000 | ((4u)&0x1ffffu)<<0;
+#if TKB_HAVE_ECN_FIXUP == 1u
+ /* DATA32 ecn_fixup_instr */
+ ecn_fixup_instr = EVAL_ecn_fixup_instr();
+ *tp++=0x00000000 | ((ecn_fixup_instr)&0xffffffffu)<<0;
+#endif
+#if TKB_HAVE_CHACHAPOLY_HW30 == 1u
+ /* INS NONE, PAD_ZERO, 0, 160 */
+ *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((160u)&0xffffu)<<0;
+#else
+ /* INS NONE, PAD_ZERO, 0, 16 */
+ *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+#endif
+ }
+ /* DIR CRYPTHASH,packetsize - ivlen - 8 - icvlen - bypass - hdrlen,LAST,LASTHASH */
+ *tp++=0x0f020000 | ((-8u+packetsize-ivlen-icvlen-bypass-hdrlen)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+ *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 39: /* ssltls_ccm_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ if (packetsize < bypass+hdrlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS outbound CCM\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ if (hdrlen > 0u)
+ {
+ /* DIR OUT,hdrlen */
+ *tp++=0x01000000 | ((hdrlen)&0x1ffffu)<<0;
+ }
+ capwap_out = EVAL_capwap_out();
+ if (capwap_out != 0u)
+ {
+ /* INS OUT,ORIG_TOKEN,4 */
+ *tp++=0x21d80000 | ((4u)&0x1ffffu)<<0;
+ /* DATA32 0x0000001 ; Insert DTLS/CAPWAP header. */
+ *tp++=0x00000000 | ((1u)&0xffffffffu)<<0;
+ }
+ /* INS HASHONLY,PAD_CONST,salt,1 ; Form b0 block, flag byte */
+ salt = EVAL_salt();
+ *tp++=0x22100000 | ((salt)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ /* INS HASHONLY,ORIG_IV0,4 */
+ *tp++=0x22a00000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_EXTSEQNUM,4 */
+ *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SEQNUM,4 */
+ *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_TOKEN,5 */
+ *tp++=0x22d80000 | ((5u)&0x1ffffu)<<0;
+ /* DATA32 swaplen3 ; 3-byte length in b0 block. */
+ swaplen3 = EVAL_swaplen3();
+ *tp++=0x00000000 | ((swaplen3)&0xffffffffu)<<0;
+ /* DATA32 0x0d ; and swapped 2-byte AAD length just after */
+ *tp++=0x00000000 | ((13u)&0xffffffffu)<<0;
+ /* INS HASHONLY,ORIG_EXTSEQNUM,4 */
+ *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SEQNUM,4 */
+ *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASH,PAD_CONST,nextheader,1 ; Type field */
+ nextheader = EVAL_nextheader();
+ *tp++=0x23100000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ /* INS HASH,ORIG_SPI,2 ; For TLS/DTLS, hash version field. */
+ *tp++=0x23900000 | ((2u)&0x1ffffu)<<0;
+ extseq = EVAL_extseq();
+ if (extseq != 0u)
+ {
+ /* INS OUT,ORIG_EXTSEQNUM,4 ; Output sequence number for DTLS */
+ *tp++=0x21580000 | ((4u)&0x1ffffu)<<0;
+ /* INS OUT,ORIG_SEQNUM,4 */
+ *tp++=0x21500000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* INS HASHONLY,ORIG_TOKEN,2 */
+ *tp++=0x22d80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swaplen ; Payload length to hash. */
+ swaplen = EVAL_swaplen();
+ *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+ /* INS HASHONLY,PAD_ZERO,0,1 ; Pad AAD to 16 bytes. */
+ *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((1u)&0xffffu)<<0;
+ /* INS OUT,ORIG_TOKEN,2 */
+ *tp++=0x21d80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swap_fraglen ; Fragment length to output. */
+ swap_fraglen = EVAL_swap_fraglen();
+ *tp++=0x00000000 | ((swap_fraglen)&0xffffffffu)<<0;
+ /* INS OUT,ORIG_IV1,ivlen */
+ ivlen = EVAL_ivlen();
+ *tp++=0x21a80000 | ((ivlen)&0x1ffffu)<<0;
+ if (extseq != 0u)
+ {
+ /* REMRES bypass + hdrlen + capwap_out + 5 + 8 + 8, 16 */
+ *tp++=0xa0000000 | ((21u+bypass+hdrlen+capwap_out)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ }
+ else
+ {
+ /* REMRES bypass + hdrlen + 5 + 8, 16 */
+ *tp++=0xa0000000 | ((13u+bypass+hdrlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ }
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ if (packetsize != bypass+hdrlen)
+ {
+ /* DIR CRYPTHASH, packetsize-bypass-hdrlen,LAST */
+ *tp++=0x0f000000 | ((packetsize-bypass-hdrlen)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS CRYPTHASH, PAD_ZERO, 0, 0,LAST */
+ *tp++=0x2f000000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ }
+ /* INS HASHONLY,PAD_ZERO,0,hashpad,LASTHASH */
+ hashpad = EVAL_hashpad();
+ *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((hashpad)&0xffffu)<<0;
+ /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ /* VERIFY 0 ; Causes any sequence number rollover error to fail the packet. */
+ *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2 */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 40: /* ssltls_ccm_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ paylen = EVAL_paylen();
+ if (paylen == 4294967295u)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS inbound CCM\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ if (hdrlen > 0u)
+ {
+ /* DIR OUT,hdrlen */
+ *tp++=0x01000000 | ((hdrlen)&0x1ffffu)<<0;
+ }
+ capwap_in = EVAL_capwap_in();
+ if (capwap_in != 0u)
+ {
+ /* REM 4 ; Remove DTLS/CAPWAP header. */
+ *tp++=0x40d80000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* INS HASHONLY,PAD_CONST,salt,1 ; Form b0 block, flag byte */
+ salt = EVAL_salt();
+ *tp++=0x22100000 | ((salt)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ /* INS HASHONLY,ORIG_IV0,4 */
+ *tp++=0x22a00000 | ((4u)&0x1ffffu)<<0;
+ ohdrlen = EVAL_ohdrlen();
+ if (ohdrlen > hdrlen)
+ {
+ /* RETR OUT,ORIG_SPI,3 ; Extract Type and Version. */
+ *tp++=0x41900000 | ((3u)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+ *tp++=0x40480000 | ((4u)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_SEQNUM_RES2,4 */
+ *tp++=0x40400000 | ((4u)&0x1ffffu)<<0;
+ /* REM 2 ; Remove fragment length. */
+ *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+ /* RETR HASHONLY,ORIG_IV1,ivlen */
+ ivlen = EVAL_ivlen();
+ *tp++=0x42a80000 | ((ivlen)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_TOKEN,5 */
+ *tp++=0x22d80000 | ((5u)&0x1ffffu)<<0;
+ /* DATA32 swaplen3 ; 3-byte length in b0 block. */
+ swaplen3 = EVAL_swaplen3();
+ *tp++=0x00000000 | ((swaplen3)&0xffffffffu)<<0;
+ /* DATA32 0x0d ; and swapped 2-byte AAD length just after */
+ *tp++=0x00000000 | ((13u)&0xffffffffu)<<0;
+ /* INS HASHONLY, ORIG_EXTSEQNUM_RES2,4 */
+ *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY, ORIG_SEQNUM_RES2,4 */
+ *tp++=0x22400000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SPI_RES,3 ; Hash type and version. */
+ *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+ /* INS HASH,ORIG_TOKEN,2 */
+ *tp++=0x23d80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swaplen */
+ swaplen = EVAL_swaplen();
+ *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+ if (ohdrlen-hdrlen > 5u)
+ {
+ /* INS OUT,PAD_ZERO,0,ohdrlen-hdrlen-5 */
+ *tp++=0x21000000 | ((0u)&0x1u)<<16 | ((-5u+ohdrlen-hdrlen)&0xffffu)<<0;
+ }
+ }
+ else
+ {
+ /* RETR NONE,ORIG_SPI,3 ; Extract Type and Version. */
+ *tp++=0x40900000 | ((3u)&0x1ffffu)<<0;
+ extseq = EVAL_extseq();
+ if (extseq != 0u)
+ {
+ /* RETR NONE,ORIG_EXTSEQNUM_RES2,4 ; Extract seq numbers from packet. */
+ *tp++=0x40480000 | ((4u)&0x1ffffu)<<0;
+ /* RETR NONE,ORIG_SEQNUM_RES2,4 */
+ *tp++=0x40400000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* REM 2 ; Remove fragment length. */
+ *tp++=0x40d80000 | ((2u)&0x1ffffu)<<0;
+ /* RETR HASHONLY,ORIG_IV1,ivlen */
+ ivlen = EVAL_ivlen();
+ *tp++=0x42a80000 | ((ivlen)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_TOKEN,5 */
+ *tp++=0x22d80000 | ((5u)&0x1ffffu)<<0;
+ /* DATA32 swaplen3 ; 3-byte length in b0 block. */
+ swaplen3 = EVAL_swaplen3();
+ *tp++=0x00000000 | ((swaplen3)&0xffffffffu)<<0;
+ /* DATA32 0x0d ; and swapped 2-byte AAD length just after */
+ *tp++=0x00000000 | ((13u)&0xffffffffu)<<0;
+ if (extseq != 0u)
+ {
+ /* INS HASHONLY,ORIG_EXTSEQNUM_RES2,4 ; Extract from SA. */
+ *tp++=0x22480000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SEQNUM_RES2,4 */
+ *tp++=0x22400000 | ((4u)&0x1ffffu)<<0;
+ }
+ else
+ {
+ /* INS HASHONLY,ORIG_EXTSEQNUM,4 ; Extract from SA. */
+ *tp++=0x22580000 | ((4u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_SEQNUM,4 */
+ *tp++=0x22500000 | ((4u)&0x1ffffu)<<0;
+ }
+ /* INS HASHONLY,ORIG_SPI_RES,3 ; Hash type and version. */
+ *tp++=0x22c00000 | ((3u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_TOKEN,2 */
+ *tp++=0x22d80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swaplen */
+ swaplen = EVAL_swaplen();
+ *tp++=0x00000000 | ((swaplen)&0xffffffffu)<<0;
+ }
+ /* INS HASHONLY,PAD_ZERO,0,1 ; Pad AAD to 16 bytes. */
+ *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((1u)&0xffffu)<<0;
+ /* REMRES bypass+ohdrlen, 16 */
+ *tp++=0xa0000000 | ((bypass+ohdrlen)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ /* DIR CRYPTHASH, paylen,LAST */
+ *tp++=0x0f000000 | ((paylen)&0x1ffffu)<<0;
+ /* INS HASHONLY,PAD_ZERO,0,hashpad,LASTHASH */
+ hashpad = EVAL_hashpad();
+ *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((hashpad)&0xffffu)<<0;
+ /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+ extseq = EVAL_extseq();
+ if (extseq == 0u)
+ {
+ /* VERIFY icvlen,H */
+ *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+ }
+ else if (extseq == 1u)
+ {
+ /* VERIFY icvlen,H */
+ *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+ }
+ else
+ {
+ /* VERIFY icvlen,S,H */
+ *tp++=0xd8070000 | ((icvlen)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,1+extseq,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((1u+extseq)&0xfu)<<24;
+ }
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 41: /* tls13_ccm_out */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ if (packetsize < bypass)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS outbound GCM\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* INS HASHONLY,PAD_CONST,salt,1 ; Form b0 block, flag byte */
+ salt = EVAL_salt();
+ *tp++=0x22100000 | ((salt)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ /* INS HASHONLY,ORIG_IV0,12 */
+ *tp++=0x22a00000 | ((12u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_TOKEN,5 */
+ *tp++=0x22d80000 | ((5u)&0x1ffffu)<<0;
+ /* DATA32 swaplen3_tls13_out ; 3-byte length in b0 block. */
+ swaplen3_tls13_out = EVAL_swaplen3_tls13_out();
+ *tp++=0x00000000 | ((swaplen3_tls13_out)&0xffffffffu)<<0;
+ /* DATA32 0x05 ; and swapped 2-byte AAD length just after */
+ *tp++=0x00000000 | ((5u)&0xffffffffu)<<0;
+ /* INS HASH,PAD_CONST,0x17,1 ; Type field */
+ *tp++=0x23100000 | ((23u)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ /* INS HASH,ORIG_SPI,2 ; For TLS1.3 hash fixed type/version field. */
+ *tp++=0x23900000 | ((2u)&0x1ffffu)<<0;
+ /* INS HASH,ORIG_TOKEN,2 */
+ *tp++=0x23d80000 | ((2u)&0x1ffffu)<<0;
+ /* DATA32 swap_fraglen_tls13 ; Fragment length to output and hash. */
+ swap_fraglen_tls13 = EVAL_swap_fraglen_tls13();
+ *tp++=0x00000000 | ((swap_fraglen_tls13)&0xffffffffu)<<0;
+ /* INS HASHONLY,PAD_ZERO,0,9 ; Pad AAD block */
+ *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((9u)&0xffffu)<<0;
+ /* REMRES bypass + 5, 16 */
+ *tp++=0xa0000000 | ((5u+bypass)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ /* DIR CRYPTHASH, packetsize-bypass */
+ *tp++=0x07000000 | ((packetsize-bypass)&0x1ffffu)<<0;
+ count = EVAL_count();
+ if (count == 0u)
+ {
+ /* INS CRYPTHASH, PAD_CONST, nextheader, 1,LAST */
+ nextheader = EVAL_nextheader();
+ *tp++=0x2f100000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ }
+ else
+ {
+ /* INS CRYPTHASH, PAD_CONST, nextheader, 1 */
+ nextheader = EVAL_nextheader();
+ *tp++=0x27100000 | ((nextheader)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ /* INS CRYPTHASH, PAD_ZERO, 0, count, LAST */
+ *tp++=0x2f000000 | ((0u)&0x1u)<<16 | ((count)&0xffffu)<<0;
+ }
+ /* INS HASHONLY,PAD_ZERO, 0, hashpad_tls13_out, LASTHASH */
+ hashpad_tls13_out = EVAL_hashpad_tls13_out();
+ *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((hashpad_tls13_out)&0xffffu)<<0;
+ /* INS OUT,ORIG_HASH,icvlen,LASTHASHPKT */
+ icvlen = EVAL_icvlen();
+ *tp++=0x21e60000 | ((icvlen)&0x1ffffu)<<0;
+ /* VERIFY 0 ; Causes any sequence number rollover error to fail the packet. */
+ *tp++=0xd0060000 | ((0u)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2 */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0560800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 42: /* tls13_ccm_in */
+#if TKB_HAVE_PROTO_SSLTLS == 1u
+ icvlen = EVAL_icvlen();
+ if (packetsize < 5u+bypass+icvlen)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for SSLTLS inbound GCM\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* INS HASHONLY,PAD_CONST,salt,1 ; Form b0 block, flag byte */
+ salt = EVAL_salt();
+ *tp++=0x22100000 | ((salt)&0xffu)<<9 | ((1u)&0x1ffu)<<0;
+ /* INS HASHONLY,ORIG_IV0,12 */
+ *tp++=0x22a00000 | ((12u)&0x1ffffu)<<0;
+ /* INS HASHONLY,ORIG_TOKEN,5 */
+ *tp++=0x22d80000 | ((5u)&0x1ffffu)<<0;
+ /* DATA32 swaplen3_tls13_in ; 3-byte length in b0 block. */
+ swaplen3_tls13_in = EVAL_swaplen3_tls13_in();
+ *tp++=0x00000000 | ((swaplen3_tls13_in)&0xffffffffu)<<0;
+ /* DATA32 0x05 ; and swapped 2-byte AAD length just after */
+ *tp++=0x00000000 | ((5u)&0xffffffffu)<<0;
+ /* DIR HASHONLY,5 ; Hash type and version number and length */
+ *tp++=0x02000000 | ((5u)&0x1ffffu)<<0;
+ /* INS HASHONLY,PAD_ZERO,0,9 ; Pad AAD block */
+ *tp++=0x22000000 | ((0u)&0x1u)<<16 | ((9u)&0xffffu)<<0;
+ /* REMRES bypass, 16 */
+ *tp++=0xa0000000 | ((bypass)&0xffffu)<<0 | ((16u)&0x3fu)<<19;
+ /* INS CRYPT, PAD_ZERO, 0, 16 */
+ *tp++=0x25000000 | ((0u)&0x1u)<<16 | ((16u)&0xffffu)<<0;
+ /* DIR CRYPTHASH, packetsize-bypass-icvlen-5,LAST */
+ *tp++=0x0f000000 | ((-5u+packetsize-bypass-icvlen)&0x1ffffu)<<0;
+ /* INS HASHONLY,PAD_ZERO, 0, hashpad_tls13_in, LASTHASH */
+ hashpad_tls13_in = EVAL_hashpad_tls13_in();
+ *tp++=0x22020000 | ((0u)&0x1u)<<16 | ((hashpad_tls13_in)&0xffffu)<<0;
+ /* RETR NONE,ORIG_HASH,icvlen,LASTHASHPKT */
+ *tp++=0x40e60000 | ((icvlen)&0x1ffffu)<<0;
+ /* VERIFY icvlen,H */
+ *tp++=0xd0070000 | ((icvlen)&0x7fu)<<0;
+ /* CTX ORIG_SEQNUM,seq_offset,2,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u)&0xfu)<<24;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 43: /* basic_hmac_precompute */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ if (packetsize < bypass)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic hash precompute\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* DIR HASHONLY,packetsize-bypass,LASTHASH */
+ *tp++=0x02020000 | ((packetsize-bypass)&0x1ffffu)<<0;
+ /* INS OUT, ORIG_HASH,hstatelen_bytes */
+ hstatelen_bytes = EVAL_hstatelen_bytes();
+ *tp++=0x21e00000 | ((hstatelen_bytes)&0x1ffffu)<<0;
+ /* INS NONE,PAD_ZERO, 0, 0 */
+ *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ /* INS OUT,ORIG_HASH,hstatelen_bytes,LASTHASHPKT */
+ *tp++=0x21e60000 | ((hstatelen_bytes)&0x1ffffu)<<0;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 44: /* basic_hmac_ctxprepare */
+#if TKB_HAVE_PROTO_BASIC == 1u
+ if (packetsize < bypass)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic hash precompute\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* DIR HASHONLY,packetsize-bypass,LASTHASH */
+ *tp++=0x02020000 | ((packetsize-bypass)&0x1ffffu)<<0;
+ /* INS NONE, ORIG_HASH,hstatelen_bytes */
+ hstatelen_bytes = EVAL_hstatelen_bytes();
+ *tp++=0x20e00000 | ((hstatelen_bytes)&0x1ffffu)<<0;
+ /* INS NONE,PAD_ZERO, 0, 0 */
+ *tp++=0x20000000 | ((0u)&0x1u)<<16 | ((0u)&0xffffu)<<0;
+ /* INS NONE,ORIG_HASH,hstatelen_bytes,LASTHASHPKT */
+ *tp++=0x20e60000 | ((hstatelen_bytes)&0x1ffffu)<<0;
+ /* CTX ORIG_HASH_INNER,digest_offset,hstatelen,P,F */
+ digest_offset = EVAL_digest_offset();
+ hstatelen = EVAL_hstatelen();
+ *tp++=0xe0ee3800 | ((digest_offset)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+ /* CTX ORIG_HASH,digest_offset+hstatelen,hstatelen,P,F */
+ *tp++=0xe0e63800 | ((digest_offset+hstatelen)&0xffu)<<0 | ((hstatelen)&0xfu)<<24;
+#else
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+#endif
+ break;
+ case 45: /* basic_bypass */
+ if (packetsize < bypass)
+ {
+ LOG_WARN("TokenBuilder: bad packet, too short for basic bypass\n");
+ rc = TKB_BAD_PACKET; goto error;
+ }
+ /* DIR OUT,packetsize-bypass,LASTHASHPKT */
+ *tp++=0x01060000 | ((packetsize-bypass)&0x1ffffu)<<0;
+ break;
+ default:
+ LOG_WARN("TokenBuilder: bad protocol\n");
+ rc = TKB_BAD_PROTOCOL; goto error;
+ }
+#if TKB_HAVE_PROTO_IPSEC == 1u
+#if TKB_HAVE_EXTENDED_IPSEC == 1u
+ hproto = EVAL_hproto();
+ switch(hproto)
+ {
+ case 6: /* ipv4_in_transp */
+ case 26: /* ipv4_in_transp_natt */
+ /* INSRES 2+bypass,7,L,NH,CS,LASTINS */
+ *tp++=0xae050000 | ((2u+bypass)&0xffffu)<<0 | ((7u)&0x3fu)<<19;
+ break;
+ case 12: /* ipv6_in_transp */
+ case 32: /* ipv6_in_transp_natt */
+ /* INSRES 4+bypass,40,L,NOUPDCHK */
+ *tp++=0xa8030000 | ((4u+bypass)&0xffffu)<<0 | ((40u)&0x3fu)<<19;
+ /* INSRES bypass+prev_nhoffset,0,NH,NOUPDCHK,LASTINS */
+ prev_nhoffset = EVAL_prev_nhoffset();
+ *tp++=0xa4070000 | ((bypass+prev_nhoffset)&0xffffu)<<0 | ((0u)&0x3fu)<<19;
+ break;
+ }
+#endif
+ switch(proto)
+ {
+ case 1: /* esp_in */
+ case 3: /* esp_in_ccm */
+ case 5: /* esp_in_gcm */
+ case 7: /* esp_in_gmac */
+ case 36: /* esp_in_chachapoly */
+ icvlen = EVAL_icvlen();
+ if (icvlen > 0u)
+ {
+ antireplay = EVAL_antireplay();
+ if (antireplay > 12u)
+ {
+ /* VERIFY icvlen,S,SP,P,H */
+ *tp++=0xdd070000 | ((icvlen)&0x7fu)<<0;
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* CTX ORIG_SEQNUM,seq_offset,0,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((0u)&0xfu)<<24;
+ }
+ else
+ {
+ /* CTX ORIG_SEQNUM_INBOUND,seq_offset,0,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe02e1800 | ((seq_offset)&0xffu)<<0 | ((0u)&0xfu)<<24;
+ }
+ }
+ else if (antireplay != 0u)
+ {
+ /* VERIFY icvlen,S,SP,P,H */
+ *tp++=0xdd070000 | ((icvlen)&0x7fu)<<0;
+ extseq = EVAL_extseq();
+ if (extseq > 0u)
+ {
+ /* CTX ORIG_SEQNUM,seq_offset,2+antireplay,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe0561800 | ((seq_offset)&0xffu)<<0 | ((2u+antireplay)&0xfu)<<24;
+ }
+ else
+ {
+ /* CTX ORIG_SEQNUM_INBOUND,seq_offset,1+antireplay,P */
+ seq_offset = EVAL_seq_offset();
+ *tp++=0xe02e1800 | ((seq_offset)&0xffu)<<0 | ((1u+antireplay)&0xfu)<<24;
+ }
+ }
+ else
+ {
+ /* VERIFY icvlen,SP,P,H */
+ *tp++=0xd5070000 | ((icvlen)&0x7fu)<<0;
+ }
+ }
+ else
+ {
+ /* VERIFY 0,SP,P */
+ *tp++=0xd5060000 | ((0u)&0x7fu)<<0;
+ }
+ break;
+ }
+#endif
+
+
+ Switch_Proto(TokenContext_Internal_p);
+
+error:
+ if (rc != TKB_STATUS_OK)
+ {
+ tp = (uint32_t *)Token_p + TKB_TOKEN_HEADER_WORD_COUNT;
+ /* Include CCW0 and CCW1 in token. */
+ *tp++ = 0;
+ *tp++ = 0;
+ /* DIR OUT,PacketByteCount,LASTHASHPKT pass packet unchanged */
+ *tp++ = 0x01060000 | (PacketByteCount & 0x1ffff);
+ *TokenHeaderWord_p = TKB_HEADER_DEFAULT | TKB_HEADER_C | (PacketByteCount & 0x1ffff);
+ }
+ *TokenWord32Count_p = tp - (uint32_t*)Token_p;
+ return rc;
+}
+
+/* end of file token_builder_core.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip201.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip201.c
new file mode 100644
index 0000000..753a1cb
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip201.c
@@ -0,0 +1,567 @@
+/* eip201_sl.c
+ *
+ * Driver Library for the Security-IP-201 Advanced Interrupt Controller.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+// Top-level Interrupt controller configuration
+#include "c_eip201.h" // configuration
+
+// Driver Framework Basic Defs API
+#include "basic_defs.h" // uint32_t, inline, etc.
+
+// Interrupt controller API
+#include "eip201.h" // the API we will implement
+
+// Driver Framework Device API
+#include "device_rw.h" // Device_Read32/Write32
+
+// create a constant where all unused interrupts are '1'
+#if (EIP201_STRICT_ARGS_MAX_NUM_OF_INTERRUPTS < 32)
+#define EIP201_NOTUSEDIRQ_MASK (uint32_t) \
+ (~((1 << EIP201_STRICT_ARGS_MAX_NUM_OF_INTERRUPTS)-1))
+#else
+#define EIP201_NOTUSEDIRQ_MASK 0
+#endif
+
+#ifdef EIP201_STRICT_ARGS
+#define EIP201_CHECK_IF_IRQ_SUPPORTED(_irqs) \
+ if (_irqs & EIP201_NOTUSEDIRQ_MASK) \
+ return EIP201_STATUS_UNSUPPORTED_IRQ;
+#else
+#define EIP201_CHECK_IF_IRQ_SUPPORTED(_irqs)
+#endif /* EIP201_STRICT_ARGS */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201 registers
+ */
+enum
+{
+ EIP201_REGISTER_OFFSET_POL_CTRL = EIP201_LO_REG_BASE+0,
+ EIP201_REGISTER_OFFSET_TYPE_CTRL = EIP201_LO_REG_BASE+4,
+ EIP201_REGISTER_OFFSET_ENABLE_CTRL = EIP201_LO_REG_BASE+8,
+ EIP201_REGISTER_OFFSET_RAW_STAT = EIP201_HI_REG_BASE+12,
+ EIP201_REGISTER_OFFSET_ENABLE_SET = EIP201_LO_REG_BASE+12,
+ EIP201_REGISTER_OFFSET_ENABLED_STAT = EIP201_HI_REG_BASE+16,
+ EIP201_REGISTER_OFFSET_ACK = EIP201_LO_REG_BASE+16,
+ EIP201_REGISTER_OFFSET_ENABLE_CLR = EIP201_LO_REG_BASE+20,
+ EIP201_REGISTER_OFFSET_OPTIONS = EIP201_HI_REG_BASE+24,
+ EIP201_REGISTER_OFFSET_VERSION = EIP201_HI_REG_BASE+28
+};
+
+// this implementation supports only the EIP-201 HW1.1 and HW1.2
+// 0xC9 = 201
+// 0x39 = binary inverse of 0xC9
+#define EIP201_SIGNATURE 0x36C9
+#define EIP201_SIGNATURE_MASK 0xffff
+
+/*----------------------------------------------------------------------------
+ * EIP201_Read32
+ *
+ * This routine reads from a Register location in the EIP201, applying
+ * endianness swapping when required (depending on configuration).
+ */
+static inline int
+EIP201_Read32(
+ Device_Handle_t Device,
+ const unsigned int Offset,
+ uint32_t * const Value_p)
+{
+ return Device_Read32Check(Device, Offset, Value_p);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_Write32
+ *
+ * This routine writes to a Register location in the EIP201, applying
+ * endianness swapping when required (depending on configuration).
+ */
+static inline int
+EIP201_Write32(
+ Device_Handle_t Device,
+ const unsigned int Offset,
+ const uint32_t Value)
+{
+ return Device_Write32(Device, Offset, Value);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_Config_Change
+ */
+#ifndef EIP201_REMOVE_CONFIG_CHANGE
+EIP201_Status_t
+EIP201_Config_Change(
+ Device_Handle_t Device,
+ const EIP201_SourceBitmap_t Sources,
+ const EIP201_Config_t Config)
+{
+ uint32_t Value;
+ uint32_t NewPol = 0;
+ uint32_t NewType = 0;
+ int rc;
+ EIP201_CHECK_IF_IRQ_SUPPORTED(Sources);
+
+ /*
+ EIP201_CONFIG_ACTIVE_LOW, // Type=0, Pol=0
+ EIP201_CONFIG_ACTIVE_HIGH, // Type=0, Pol=1
+ EIP201_CONFIG_FALLING_EDGE, // Type=1, Pol=0
+ EIP201_CONFIG_RISING_EDGE // Type=1, Pol=1
+ */
+
+ // do we want Type=1?
+ if (Config == EIP201_CONFIG_FALLING_EDGE ||
+ Config == EIP201_CONFIG_RISING_EDGE)
+ {
+ NewType = Sources;
+ }
+
+ // do we want Pol=1?
+ if (Config == EIP201_CONFIG_ACTIVE_HIGH ||
+ Config == EIP201_CONFIG_RISING_EDGE)
+ {
+ NewPol = Sources;
+ }
+
+ if (Sources)
+ {
+ // modify polarity register
+ rc = EIP201_Read32(Device, EIP201_REGISTER_OFFSET_POL_CTRL, &Value);
+ if (rc) return rc;
+ Value &= ~Sources;
+ Value |= NewPol;
+ rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_POL_CTRL, Value);
+ if (rc) return rc;
+
+ // modify type register
+ rc = EIP201_Read32(Device, EIP201_REGISTER_OFFSET_TYPE_CTRL, &Value);
+ if (rc) return rc;
+ Value &= ~Sources;
+ Value |= NewType;
+ rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_TYPE_CTRL, Value);
+ if (rc) return rc;
+ }
+
+ return EIP201_STATUS_SUCCESS;
+}
+#endif /* EIP201_REMOVE_CONFIG_CHANGE */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_Config_Read
+ */
+#ifndef EIP201_REMOVE_CONFIG_READ
+
+static const EIP201_Config_t EIP201_Setting2Config[4] =
+{
+ EIP201_CONFIG_ACTIVE_LOW, // Type=0, Pol=0
+ EIP201_CONFIG_ACTIVE_HIGH, // Type=0, Pol=1
+ EIP201_CONFIG_FALLING_EDGE, // Type=1, Pol=0
+ EIP201_CONFIG_RISING_EDGE // Type=1, Pol=1
+};
+
+EIP201_Config_t
+EIP201_Config_Read(
+ Device_Handle_t Device,
+ const EIP201_Source_t Source)
+{
+ uint32_t Value;
+ unsigned char Setting = 0;
+ int rc = 0;
+
+ rc = EIP201_Read32(Device, EIP201_REGISTER_OFFSET_TYPE_CTRL, &Value);
+ if (rc) return rc;
+ if (Value & Source)
+ {
+ // Type=1, thus edge
+ Setting += 2;
+ }
+
+ EIP201_Read32(Device, EIP201_REGISTER_OFFSET_POL_CTRL, &Value);
+ if (Value & Source)
+ {
+ // Pol=1, this rising edge or active high
+ Setting++;
+ }
+
+ return EIP201_Setting2Config[Setting];
+}
+#endif /* EIP201_REMOVE_CONFIG_READ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceMask_EnableSource
+ *
+ * See header file for function specifications.
+ */
+#ifndef EIP201_REMOVE_SOURCEMASK_ENABLESOURCE
+EIP201_Status_t
+EIP201_SourceMask_EnableSource(
+ Device_Handle_t Device,
+ const EIP201_SourceBitmap_t Sources)
+{
+ int rc;
+ EIP201_CHECK_IF_IRQ_SUPPORTED(Sources);
+
+ rc = EIP201_Write32(
+ Device,
+ EIP201_REGISTER_OFFSET_ENABLE_SET,
+ Sources);
+
+ return rc;
+}
+#endif /* EIP201_REMOVE_SOURCEMASK_ENABLESOURCE */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceMask_DisableSource
+ */
+#ifndef EIP201_REMOVE_SOURCEMASK_DISABLESOURCE
+EIP201_Status_t
+EIP201_SourceMask_DisableSource(
+ Device_Handle_t Device,
+ const EIP201_SourceBitmap_t Sources)
+{
+ int rc;
+ rc = EIP201_Write32(
+ Device,
+ EIP201_REGISTER_OFFSET_ENABLE_CLR,
+ Sources);
+
+ return rc;
+}
+#endif /* EIP201_REMOVE_SOURCEMASK_DISABLESOURCE */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceMask_SourceIsEnabled
+ */
+#ifndef EIP201_REMOVE_SOURCEMASK_SOURCEISENABLED
+bool
+EIP201_SourceMask_SourceIsEnabled(
+ Device_Handle_t Device,
+ const EIP201_Source_t Source)
+{
+ int rc;
+ uint32_t SourceMasks;
+
+ rc = EIP201_Read32(
+ Device,
+ EIP201_REGISTER_OFFSET_ENABLE_CTRL, &SourceMasks);
+
+ if (rc) return false;
+ if (SourceMasks & Source)
+ return true;
+
+ return false;
+}
+#endif /* EIP201_REMOVE_SOURCEMASK_SOURCEISENABLED */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceMask_ReadAll
+ */
+#ifndef EIP201_REMOVE_SOURCEMASK_READALL
+EIP201_SourceBitmap_t
+EIP201_SourceMask_ReadAll(
+ Device_Handle_t Device)
+{
+ uint32_t Value;
+ EIP201_Read32(Device, EIP201_REGISTER_OFFSET_ENABLE_CTRL, &Value);
+ return Value;
+}
+#endif /* EIP201_REMOVE_SOURCEMASK_READALL */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceStatus_IsEnabledSourcePending
+ */
+#ifndef EIP201_REMOVE_SOURCESTATUS_ISENABLEDSOURCEPENDING
+bool
+EIP201_SourceStatus_IsEnabledSourcePending(
+ Device_Handle_t Device,
+ const EIP201_Source_t Source)
+{
+ uint32_t Statuses;
+ int rc;
+
+ rc = EIP201_Read32(Device, EIP201_REGISTER_OFFSET_ENABLED_STAT, &Statuses);
+ if (rc) return false;
+
+ if (Statuses & Source)
+ return true;
+
+ return false;
+}
+#endif /* EIP201_REMOVE_SOURCESTATUS_ISENABLEDSOURCEPENDING */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceStatus_IsRawSourcePending
+ */
+#ifndef EIP201_REMOVE_SOURCESTATUS_ISRAWSOURCEPENDING
+bool
+EIP201_SourceStatus_IsRawSourcePending(
+ Device_Handle_t Device,
+ const EIP201_Source_t Source)
+{
+ uint32_t Statuses;
+ int rc;
+
+ rc = EIP201_Read32(Device, EIP201_REGISTER_OFFSET_RAW_STAT, &Statuses);
+ if (rc) return false;
+
+ if (Statuses & Source)
+ return true;
+
+ return false;
+}
+#endif /* EIP201_REMOVE_SOURCESTATUS_ISRAWSOURCEPENDING */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceStatus_ReadAllEnabled
+ */
+#ifndef EIP201_REMOVE_SOURCESTATUS_READALLENABLED
+EIP201_SourceBitmap_t
+EIP201_SourceStatus_ReadAllEnabled(
+ Device_Handle_t Device)
+{
+ uint32_t Value;
+ EIP201_Read32(Device, EIP201_REGISTER_OFFSET_ENABLED_STAT, &Value);
+ return Value;
+}
+#endif /* EIP201_REMOVE_SOURCESTATUS_READALLENABLED */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceStatus_ReadAllRaw
+ */
+#ifndef EIP201_REMOVE_SOURCESTATUS_READALLRAW
+EIP201_SourceBitmap_t
+EIP201_SourceStatus_ReadAllRaw(
+ Device_Handle_t Device)
+{
+ uint32_t Value;
+ EIP201_Read32(Device, EIP201_REGISTER_OFFSET_RAW_STAT, &Value);
+ return Value;
+}
+#endif /* EIP201_REMOVE_SOURCESTATUS_READALLRAW */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceStatus_ReadAllEnabledCheck
+ */
+#ifndef EIP201_REMOVE_SOURCESTATUS_READALLENABLED
+EIP201_Status_t
+EIP201_SourceStatus_ReadAllEnabledCheck(
+ Device_Handle_t Device,
+ EIP201_SourceBitmap_t * const Statuses_p)
+{
+ return EIP201_Read32(Device, EIP201_REGISTER_OFFSET_ENABLED_STAT, Statuses_p);
+}
+#endif /* EIP201_REMOVE_SOURCESTATUS_READALLENABLED */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_SourceStatus_ReadAllRawCheck
+ */
+#ifndef EIP201_REMOVE_SOURCESTATUS_READALLRAW
+EIP201_Status_t
+EIP201_SourceStatus_ReadAllRawCheck(
+ Device_Handle_t Device,
+ EIP201_SourceBitmap_t * const Statuses_p)
+{
+ return EIP201_Read32(Device, EIP201_REGISTER_OFFSET_RAW_STAT, Statuses_p);
+}
+#endif /* EIP201_REMOVE_SOURCESTATUS_READALLRAW */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201Lib_Detect
+ *
+ * Detect the presence of EIP201 hardware.
+ */
+#ifndef EIP201_REMOVE_INITIALIZE
+static EIP201_Status_t
+EIP201Lib_Detect(
+ Device_Handle_t Device)
+{
+ uint32_t Value;
+ int rc;
+
+ rc = EIP201_Read32(Device, EIP201_REGISTER_OFFSET_VERSION, &Value);
+ if (rc) return rc;
+ Value &= EIP201_SIGNATURE_MASK;
+ if ( Value != EIP201_SIGNATURE)
+ return EIP201_STATUS_UNSUPPORTED_HARDWARE_VERSION;
+
+ // Prevent interrupts going of by disabling them
+ rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_ENABLE_CTRL, 0);
+ if (rc) return rc;
+
+ // Get the number of interrupt sources
+ rc = EIP201_Read32(Device, EIP201_REGISTER_OFFSET_OPTIONS, &Value);
+ if (rc) return rc;
+ // lowest 6 bits contain the number of inputs, which should be between 1-32
+ Value &= MASK_6_BITS;
+ if (Value == 0 || Value > 32)
+ return EIP201_STATUS_UNSUPPORTED_HARDWARE_VERSION;
+
+ return EIP201_STATUS_SUCCESS;
+}
+#endif /* EIP201_REMOVE_INITIALIZE */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_Initialize API
+ *
+ * See header file for function specification.
+ */
+#ifndef EIP201_REMOVE_INITIALIZE
+EIP201_Status_t
+EIP201_Initialize(
+ Device_Handle_t Device,
+ const EIP201_SourceSettings_t * SettingsArray_p,
+ const unsigned int SettingsCount)
+{
+ EIP201_SourceBitmap_t ActiveLowSources = 0;
+ EIP201_SourceBitmap_t ActiveHighSources = 0;
+ EIP201_SourceBitmap_t FallingEdgeSources = 0;
+ EIP201_SourceBitmap_t RisingEdgeSources = 0;
+ EIP201_SourceBitmap_t EnabledSources = 0;
+ int rc;
+
+ // check presence of EIP201 hardware
+ rc = EIP201Lib_Detect(Device);
+ if (rc) return rc;
+
+ // disable all interrupts and set initial configuration
+ rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_ENABLE_CTRL, 0);
+ if (rc) return rc;
+ rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_POL_CTRL, 0);
+ if (rc) return rc;
+ rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_TYPE_CTRL, 0);
+ if (rc) return rc;
+
+ // process the setting, if provided
+ if (SettingsArray_p != NULL)
+ {
+ unsigned int i;
+
+ for (i = 0; i < SettingsCount; i++)
+ {
+ // check
+ const EIP201_Source_t Source = SettingsArray_p[i].Source;
+ EIP201_CHECK_IF_IRQ_SUPPORTED(Source);
+
+ // determine polarity
+ switch(SettingsArray_p[i].Config)
+ {
+ case EIP201_CONFIG_ACTIVE_LOW:
+ ActiveLowSources |= Source;
+ break;
+
+ case EIP201_CONFIG_ACTIVE_HIGH:
+ ActiveHighSources |= Source;
+ break;
+
+ case EIP201_CONFIG_FALLING_EDGE:
+ FallingEdgeSources |= Source;
+ break;
+
+ case EIP201_CONFIG_RISING_EDGE:
+ RisingEdgeSources |= Source;
+ break;
+
+ default:
+ // invalid parameter
+ break;
+ } // switch
+
+ // determine enabled mask
+ if (SettingsArray_p[i].fEnable)
+ EnabledSources |= Source;
+ } // for
+ }
+
+ // program source configuration
+ rc = EIP201_Config_Change(
+ Device,
+ ActiveLowSources,
+ EIP201_CONFIG_ACTIVE_LOW);
+ if (rc) return rc;
+
+ rc = EIP201_Config_Change(
+ Device,
+ ActiveHighSources,
+ EIP201_CONFIG_ACTIVE_HIGH);
+ if (rc) return rc;
+
+ rc = EIP201_Config_Change(
+ Device,
+ FallingEdgeSources,
+ EIP201_CONFIG_FALLING_EDGE);
+ if (rc) return rc;
+
+ rc = EIP201_Config_Change(
+ Device,
+ RisingEdgeSources,
+ EIP201_CONFIG_RISING_EDGE);
+ if (rc) return rc;
+
+ // the configuration change could have triggered the edge-detection logic
+ // so acknowledge all edge-based interrupts immediately
+ {
+ const uint32_t Value = FallingEdgeSources | RisingEdgeSources;
+ rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_ACK, Value);
+ if (rc) return rc;
+ }
+
+ // set mask (enable required interrupts)
+ rc = EIP201_SourceMask_EnableSource(Device, EnabledSources);
+
+ return rc;
+}
+#endif /* EIP201_REMOVE_INITIALIZE */
+
+
+/*----------------------------------------------------------------------------
+ * EIP201_Acknowledge
+ *
+ * See header file for function specification.
+ */
+#ifndef EIP201_REMOVE_ACKNOWLEDGE
+EIP201_Status_t
+EIP201_Acknowledge(
+ Device_Handle_t Device,
+ const EIP201_SourceBitmap_t Sources)
+{
+ int rc;
+ EIP201_CHECK_IF_IRQ_SUPPORTED(Sources);
+
+ rc = EIP201_Write32(Device, EIP201_REGISTER_OFFSET_ACK, Sources);
+
+ return rc;
+}
+#endif /* EIP201_REMOVE_ACKNOWLEDGE */
+
+/* end of file eip201_sl.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cd_format.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cd_format.c
new file mode 100644
index 0000000..1190450
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cd_format.c
@@ -0,0 +1,185 @@
+/* eip202_cd_format.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * Command Descriptor Internal interface
+ *
+ * This module contains the EIP-202 Command Descriptor specific functionality
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_cd_format.h"
+
+// Descriptor I/O Driver Library API implementation
+#include "eip202_cdr.h" // EIP202_ARM_CommandDescriptor_t
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // bool, uint32_t, uint8_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h" // DMAResource_Handle_t
+#include "dmares_rw.h" // DMAResource_Write/Read
+
+// Standard IOToken API
+#include "iotoken.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CD_Make_ControlWord
+ */
+uint32_t
+EIP202_CD_Make_ControlWord(
+ const uint8_t TokenWordCount,
+ const uint32_t SegmentByteCount,
+ const bool fFirstSegment,
+ const bool fLastSegment,
+ const bool fForceEngine,
+ const uint8_t EngineId)
+{
+ uint32_t Value = 0;
+
+ if(fFirstSegment)
+ Value |= BIT_23;
+
+ if(fLastSegment)
+ Value |= BIT_22;
+
+ Value |= ((((uint32_t)TokenWordCount) & MASK_8_BITS) << 24);
+ Value |= ((((uint32_t)SegmentByteCount) & MASK_16_BITS));
+ if (fForceEngine)
+ Value |= BIT_21 | (((uint32_t)EngineId & MASK_5_BITS) << 16);
+
+ return Value;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CD_Write
+ */
+void
+EIP202_CD_Write(
+ DMAResource_Handle_t Handle,
+ const unsigned int WordOffset,
+ const EIP202_ARM_CommandDescriptor_t * const Descr_p,
+ const bool fATP)
+
+{
+ unsigned int InTokenWordOffset;
+
+#ifdef EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
+ IOToken_Mark_Set(Descr_p->Token_p);
+#endif
+
+#ifdef EIP202_64BIT_DEVICE
+ // Write Control Word
+ DMAResource_Write32(Handle, WordOffset, Descr_p->ControlWord);
+
+ // Lengths greater than 20 bits not supported yet.
+#ifndef EIP202_CDR_OPT1
+ DMAResource_Write32(Handle, WordOffset + 1, 0);
+#endif
+
+ // Write Source Packet Data address
+ DMAResource_Write32(Handle, WordOffset + 2, Descr_p->SrcPacketAddr.Addr);
+ DMAResource_Write32(Handle, WordOffset + 3, Descr_p->SrcPacketAddr.UpperAddr);
+
+ if (fATP)
+ {
+#ifndef EIP202_CDR_OPT2
+ // Write Token Data address
+ DMAResource_Write32(Handle,
+ WordOffset + 4,
+ Descr_p->TokenDataAddr.Addr);
+ DMAResource_Write32(Handle,
+ WordOffset + 5,
+ Descr_p->TokenDataAddr.UpperAddr);
+#endif
+ InTokenWordOffset = WordOffset + 6;
+ }
+ else
+ InTokenWordOffset = WordOffset + 4;
+#else // EIP202_64BIT_DEVICE
+ // Write Control Word
+ DMAResource_Write32(Handle, WordOffset, Descr_p->ControlWord);
+
+ // Write Source Packet Data address
+ DMAResource_Write32(Handle, WordOffset + 1, Descr_p->SrcPacketAddr.Addr);
+
+ if (fATP)
+ {
+#ifndef EIP202_CDR_OPT2
+ // Write Token Data address
+ DMAResource_Write32(Handle, WordOffset + 2, Descr_p->TokenDataAddr.Addr);
+#endif
+ InTokenWordOffset = WordOffset + 3;
+ }
+ else
+ InTokenWordOffset = WordOffset + 2;
+#endif // !EIP202_64BIT_DEVICE
+
+ // Write Input Token (only for the first segment and if token is available)
+ if (Descr_p->ControlWord & BIT_23 && Descr_p->Token_p)
+ {
+ unsigned int i, offset = InTokenWordOffset;
+
+ // Write Application ID
+#ifdef EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
+ IOToken_Mark_Set(Descr_p->Token_p);
+#endif
+
+ for (i = 0; i < IOToken_InWordCount_Get(); i++)
+ DMAResource_Write32(Handle, offset + i, Descr_p->Token_p[i]);
+ }
+
+ return;
+}
+
+
+/* end of file eip202_cd_format.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_dscr.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_dscr.c
new file mode 100644
index 0000000..f7d1527
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_dscr.c
@@ -0,0 +1,363 @@
+/* eip202_cdr_dscr.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * 1) Descriptor I/O Driver Library API implementation
+ * 2) Internal Command Descriptor interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Descriptor I/O Driver Library API implementation
+#include "eip202_cdr.h"
+
+// Internal Command Descriptor interface
+#include "eip202_cdr_dscr.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+#include "eip202_cdr_level0.h" // EIP-202 Level 0 macros
+#include "eip202_cdr_fsm.h" // CDR State machine
+#include "eip202_cd_format.h" // CD Format API
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // IDENTIFIER_NOT_USED, bool, uint32_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h" // types of the DMA resource API
+#include "dmares_rw.h" // read/write of the DMA resource API.
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_CDR_FillLevel_Finalize
+ *
+ */
+static EIP202_Ring_Error_t
+EIP202Lib_CDR_FillLevel_Finalize(
+ const unsigned int CDWordCount,
+ volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p,
+ unsigned int * const FillLevelDscrCount_p)
+{
+#ifdef EIP202_RING_DEBUG_FSM
+ EIP202_Ring_Error_t rv;
+
+ if(CDWordCount == 0)
+ // CD Ring is empty
+ rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+ EIP202_CDR_STATE_INITIALIZED);
+ else if(CDWordCount > 0 &&
+ CDWordCount < (unsigned int)TrueIOArea_p->RingSizeWordCount)
+ // CD Ring is free
+ rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+ EIP202_CDR_STATE_FREE);
+ else if(CDWordCount == (unsigned int)TrueIOArea_p->RingSizeWordCount)
+ // CD Ring is full
+ rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+ EIP202_CDR_STATE_FULL);
+ else
+ rv = EIP202_RING_ILLEGAL_IN_STATE;
+
+ if(rv != EIP202_RING_NO_ERROR)
+ return EIP202_RING_ILLEGAL_IN_STATE;
+#endif
+
+ // Store actual fill level
+ *FillLevelDscrCount_p = CDWordCount /
+ (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+ // Return actual fill level plus one descriptor to distinguish
+ // ring full from ring empty
+ if(CDWordCount < (unsigned int)TrueIOArea_p->RingSizeWordCount)
+ (*FillLevelDscrCount_p)++;
+
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ Internal Command Descriptor interface
+ ---------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_WriteCB
+ */
+int
+EIP202_CDR_WriteCB(
+ void * const CallbackParam1_p,
+ const int CallbackParam2,
+ const unsigned int WriteIndex,
+ const unsigned int WriteCount,
+ const unsigned int TotalWriteLimit,
+ const void * Descriptors_p,
+ const int DescriptorCount,
+ const unsigned int DescriptorSkipCount)
+{
+ Device_Handle_t Device;
+ unsigned int i, DescOffsetWordCount;
+ unsigned int nWritten = 0;
+ volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p =
+ CDRIOAREA(CallbackParam1_p);
+ if(CallbackParam1_p == NULL || Descriptors_p == NULL)
+ return -1;
+
+ IDENTIFIER_NOT_USED(CallbackParam2);
+ IDENTIFIER_NOT_USED(DescriptorCount);
+ IDENTIFIER_NOT_USED(TotalWriteLimit);
+
+ Device = TrueIOArea_p->Device;
+
+ DescOffsetWordCount = (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+ // Write descriptors to CDR
+ for(i = WriteIndex; i < WriteIndex + WriteCount; i++)
+ {
+ EIP202_CD_Write(
+ TrueIOArea_p->RingHandle,
+ i * DescOffsetWordCount,
+ ((const EIP202_ARM_CommandDescriptor_t *)Descriptors_p) +
+ DescriptorSkipCount + nWritten,
+ TrueIOArea_p->fATP);
+
+ nWritten++;
+ }
+
+ if (nWritten > 0)
+ {
+ // Call PreDMA to prepared descriptors in Ring DMA buffer for handover
+ // to the Device (the EIP-202 DMA Master)
+ DMAResource_PreDMA(TrueIOArea_p->RingHandle,
+ WriteIndex * DescOffsetWordCount *
+ (unsigned int)sizeof(uint32_t),
+ nWritten * DescOffsetWordCount *
+ (unsigned int)sizeof(uint32_t));
+
+ // CDS point: hand over written Command Descriptors to the Device
+ EIP202_CDR_COUNT_WR(Device,
+ (uint16_t)(nWritten * DescOffsetWordCount),
+ false);
+ }
+
+ return (int) nWritten;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_ReadCB
+ */
+int
+EIP202_CDR_ReadCB(
+ void * const CallbackParam1_p,
+ const int CallbackParam2,
+ const unsigned int ReadIndex,
+ const unsigned int ReadLimit,
+ void * Descriptors_p,
+ const unsigned int DescriptorSkipCount)
+{
+ IDENTIFIER_NOT_USED(CallbackParam1_p);
+ IDENTIFIER_NOT_USED(CallbackParam2);
+ IDENTIFIER_NOT_USED(ReadIndex);
+ IDENTIFIER_NOT_USED(ReadLimit);
+ IDENTIFIER_NOT_USED(Descriptors_p);
+ IDENTIFIER_NOT_USED(DescriptorSkipCount);
+
+ // Not used for CDR
+
+ return -1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_StatusCB
+ */
+int
+EIP202_CDR_StatusCB(
+ void * const CallbackParam1_p,
+ const int CallbackParam2,
+ int * const DeviceReadPos_p)
+{
+ IDENTIFIER_NOT_USED(CallbackParam1_p);
+ IDENTIFIER_NOT_USED(CallbackParam2);
+
+ *DeviceReadPos_p = -1; // not used
+
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ Descriptor I/O Driver Library API implementation
+ ---------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_FillLevel_Get
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_FillLevel_Get(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ unsigned int * FillLevelDscrCount_p)
+{
+ Device_Handle_t Device;
+ unsigned int CDWordCount;
+ volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p = CDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+ EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
+
+ Device = TrueIOArea_p->Device;
+
+ {
+ uint32_t Value32;
+
+ EIP202_CDR_COUNT_RD(Device, &Value32);
+
+ TrueIOArea_p->CountRD = Value32;
+ TrueIOArea_p->fValidCountRD = true;
+
+ CDWordCount = (unsigned int)Value32;
+ }
+
+ return EIP202Lib_CDR_FillLevel_Finalize(CDWordCount,
+ TrueIOArea_p,
+ FillLevelDscrCount_p);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Write_ControlWord
+ */
+uint32_t
+EIP202_CDR_Write_ControlWord(
+ const EIP202_CDR_Control_t * const CommandCtrl_p)
+{
+ return EIP202_CD_Make_ControlWord(CommandCtrl_p->TokenWordCount,
+ CommandCtrl_p->SegmentByteCount,
+ CommandCtrl_p->fFirstSegment,
+ CommandCtrl_p->fLastSegment,
+ CommandCtrl_p->fForceEngine,
+ CommandCtrl_p->EngineId);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Descriptor_Put
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Descriptor_Put(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ const EIP202_ARM_CommandDescriptor_t * CommandDscr_p,
+ const unsigned int DscrRequestedCount,
+ unsigned int * const DscrDoneCount_p,
+ unsigned int * FillLevelDscrCount_p)
+{
+ Device_Handle_t Device;
+ int res;
+ unsigned int CDWordCount, CDFreeCount, CDNewRequestedCount;
+ volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p = CDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+ EIP202_RING_CHECK_POINTER(CommandDscr_p);
+ EIP202_RING_CHECK_POINTER(DscrDoneCount_p);
+ EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
+
+ Device = TrueIOArea_p->Device;
+
+ // Check how many descriptors can be put
+ {
+ uint32_t Value32;
+
+ if (TrueIOArea_p->fValidCountRD)
+ {
+ Value32 = TrueIOArea_p->CountRD;
+ TrueIOArea_p->fValidCountRD = false;
+ }
+ else
+ {
+ EIP202_CDR_COUNT_RD(Device, &Value32);
+ TrueIOArea_p->CountRD = Value32;
+ }
+
+ CDWordCount = (unsigned int)Value32;
+ }
+
+ // Check if CDR is full
+ if(CDWordCount == (unsigned int)TrueIOArea_p->RingSizeWordCount)
+ {
+ // CD Ring is full
+ *FillLevelDscrCount_p = CDWordCount /
+ (unsigned int)TrueIOArea_p->DescOffsWordCount;
+ *DscrDoneCount_p = 0;
+
+ return EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+ EIP202_CDR_STATE_FULL);
+ }
+
+ CDFreeCount =
+ ((unsigned int)TrueIOArea_p->RingSizeWordCount - CDWordCount) /
+ (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+ CDNewRequestedCount = MIN(CDFreeCount, DscrRequestedCount);
+
+ // Put command descriptors to CDR
+ res = RingHelper_Put((volatile RingHelper_t*)&TrueIOArea_p->RingHelper,
+ CommandDscr_p,
+ (int)CDNewRequestedCount);
+ if(res >= 0)
+ *DscrDoneCount_p = (unsigned int)res;
+ else
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ // Increase the fill level by the number of successfully put descriptors
+ CDWordCount += ((unsigned int)res *
+ (unsigned int)TrueIOArea_p->DescOffsWordCount);
+
+ return EIP202Lib_CDR_FillLevel_Finalize(CDWordCount,
+ TrueIOArea_p,
+ FillLevelDscrCount_p);
+}
+
+
+/* end of file eip202_cdr_dscr.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_event.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_event.c
new file mode 100644
index 0000000..07e8481
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_event.c
@@ -0,0 +1,172 @@
+/* eip202_cdr_event.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * CDR Event Management API implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_cdr.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+#include "eip202_cdr_level0.h" // EIP-202 Level 0 macros
+#include "eip202_cdr_fsm.h" // CDR State machine
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // IDENTIFIER_NOT_USED, bool, uint32_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Status_Get
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Status_Get(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ EIP202_CDR_Status_t * const Status_p)
+{
+ Device_Handle_t Device;
+ EIP202_Ring_Error_t rv;
+ volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p = CDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+ EIP202_RING_CHECK_POINTER(Status_p);
+
+ Device = TrueIOArea_p->Device;
+
+ EIP202_CDR_STAT_RD(Device,
+ &Status_p->fDMAError,
+ &Status_p->fTresholdInt,
+ &Status_p->fError,
+ &Status_p->fOUFlowError,
+ &Status_p->fTimeoutInt,
+ &Status_p->CDFIFOWordCount);
+
+ EIP202_CDR_COUNT_RD(Device, &Status_p->CDPrepWordCount);
+ EIP202_CDR_PROC_COUNT_RD(Device,
+ &Status_p->CDProcWordCount,
+ &Status_p->CDProcPktWordCount);
+
+ // Transit to a new state
+ if(Status_p->fDMAError)
+ rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+ EIP202_CDR_STATE_FATAL_ERROR);
+ else
+ // Remain in the current state
+ rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+ (EIP202_CDR_State_t)TrueIOArea_p->State);
+ if(rv != EIP202_RING_NO_ERROR)
+ return EIP202_RING_ILLEGAL_IN_STATE;
+
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_FillLevel_Low_INT_Enable
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_FillLevel_Low_INT_Enable(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ const unsigned int ThresholdDscrCount,
+ const unsigned int Timeout)
+{
+ Device_Handle_t Device;
+ EIP202_Ring_Error_t rv;
+ volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p = CDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+
+ Device = TrueIOArea_p->Device;
+
+ EIP202_CDR_THRESH_WR(Device,
+ (uint32_t)ThresholdDscrCount *
+ TrueIOArea_p->DescOffsWordCount,
+ (uint8_t)Timeout);
+
+ // Remain in the current state
+ rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+ (EIP202_CDR_State_t)TrueIOArea_p->State);
+ if(rv != EIP202_RING_NO_ERROR)
+ return EIP202_RING_ILLEGAL_IN_STATE;
+
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_FillLevel_Low_INT_ClearAndDisable
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_FillLevel_Low_INT_ClearAndDisable(
+ EIP202_Ring_IOArea_t * const IOArea_p)
+{
+ Device_Handle_t Device;
+ EIP202_Ring_Error_t rv;
+ volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p = CDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+
+ Device = TrueIOArea_p->Device;
+
+ // Disable timeout interrupt and stop timeout counter for
+ // reducing power consumption
+ EIP202_CDR_THRESH_DEFAULT_WR(Device);
+
+ // Clear all CDR interrupts
+ EIP202_CDR_STAT_CLEAR_ALL_IRQ_WR(Device);
+
+ // Remain in the current state
+ rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+ (EIP202_CDR_State_t)TrueIOArea_p->State);
+ if(rv != EIP202_RING_NO_ERROR)
+ return EIP202_RING_ILLEGAL_IN_STATE;
+
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/* end of file eip202_cdr_event.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_fsm.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_fsm.c
new file mode 100644
index 0000000..dda97e8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_fsm.c
@@ -0,0 +1,174 @@
+/* eip202_cdr_fsm.c
+ *
+ * EIP-202 Ring Control Driver Library API
+ * State Machine Internal Interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_cdr_fsm.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // IDENTIFIER_NOT_USED
+
+// EIP-202 Ring Control Driver Library Types API
+#include "eip202_ring_types.h" // EIP202_Ring_* types
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_State_Set
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_State_Set(
+ volatile EIP202_CDR_State_t * const CurrentState,
+ const EIP202_CDR_State_t NewState)
+{
+#ifdef EIP202_RING_DEBUG_FSM
+ switch(*CurrentState)
+ {
+ case EIP202_CDR_STATE_UNKNOWN:
+ switch(NewState)
+ {
+ case EIP202_CDR_STATE_UNINITIALIZED:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP202_RING_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP202_CDR_STATE_UNINITIALIZED:
+ switch(NewState)
+ {
+ case EIP202_CDR_STATE_INITIALIZED:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP202_RING_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP202_CDR_STATE_INITIALIZED:
+ switch(NewState)
+ {
+ case EIP202_CDR_STATE_UNINITIALIZED:
+ *CurrentState = NewState;
+ break;
+ case EIP202_CDR_STATE_FREE:
+ *CurrentState = NewState;
+ break;
+ case EIP202_CDR_STATE_FULL:
+ *CurrentState = NewState;
+ break;
+ case EIP202_CDR_STATE_INITIALIZED:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP202_RING_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP202_CDR_STATE_FREE:
+ switch(NewState)
+ {
+ case EIP202_CDR_STATE_UNINITIALIZED:
+ *CurrentState = NewState;
+ break;
+ case EIP202_CDR_STATE_INITIALIZED:
+ *CurrentState = NewState;
+ break;
+ case EIP202_CDR_STATE_FULL:
+ *CurrentState = NewState;
+ break;
+ case EIP202_CDR_STATE_FATAL_ERROR:
+ *CurrentState = NewState;
+ break;
+ case EIP202_CDR_STATE_FREE:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP202_RING_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP202_CDR_STATE_FULL:
+ switch(NewState)
+ {
+ case EIP202_CDR_STATE_UNINITIALIZED:
+ *CurrentState = NewState;
+ break;
+ case EIP202_CDR_STATE_INITIALIZED:
+ *CurrentState = NewState;
+ break;
+ case EIP202_CDR_STATE_FREE:
+ *CurrentState = NewState;
+ break;
+ case EIP202_CDR_STATE_FATAL_ERROR:
+ *CurrentState = NewState;
+ break;
+ case EIP202_CDR_STATE_FULL:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP202_RING_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP202_CDR_STATE_FATAL_ERROR:
+ switch(NewState)
+ {
+ case EIP202_CDR_STATE_UNINITIALIZED:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP202_RING_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ default:
+ return EIP202_RING_ILLEGAL_IN_STATE;
+ }
+#else
+ IDENTIFIER_NOT_USED(CurrentState);
+ IDENTIFIER_NOT_USED(NewState);
+#endif // EIP202_RING_DEBUG_FSM
+
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/* end of file eip202_cdr_fsm.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_init.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_init.c
new file mode 100644
index 0000000..4b010f9
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_cdr_init.c
@@ -0,0 +1,403 @@
+/* eip202_cdr_init.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * CDR Init/Reset API implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_cdr.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Types API
+#include "eip202_ring_types.h" // EIP202_Ring_* types
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+#include "eip202_cdr_level0.h" // EIP-202 Level 0 macros
+#include "eip202_cdr_fsm.h" // CDR State machine
+#include "eip202_cdr_dscr.h" // RingHelper callbacks
+#include "eip202_cd_format.h" // EIP-202 Command Descriptor
+
+// RingHelper API
+#include "ringhelper.h" // RingHelper_Init
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // IDENTIFIER_NOT_USED, bool, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h" // types of the DMA resource API
+#include "dmares_rw.h" // read/write of the DMA resource API.
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"
+
+// Standard IOToken API
+#include "iotoken.h" // IOToken_InWordCount_Get()
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_Detect
+ *
+ * Checks the presence of EIP-202 HIA hardware. Returns true when found.
+ */
+static bool
+EIP202Lib_CDR_Detect(
+ const Device_Handle_t Device)
+{
+ uint32_t Value;
+
+ // read-write test one of the registers
+
+ // Set MASK_31_BITS bits of the EIP202_CDR_RING_BASE_ADDR_LO register
+ EIP202_CDR_Write32(Device,
+ EIP202_CDR_RING_BASE_ADDR_LO,
+ MASK_31_BITS );
+
+ Value = EIP202_CDR_Read32(Device, EIP202_CDR_RING_BASE_ADDR_LO);
+ if ((Value & MASK_31_BITS) != MASK_31_BITS)
+ return false;
+
+ // Clear MASK_31_BITS bits of the EIP202_CDR_RING_BASE_ADDR_LO register
+ EIP202_CDR_Write32(Device, EIP202_CDR_RING_BASE_ADDR_LO, 0);
+ Value = EIP202_CDR_Read32(Device, EIP202_CDR_RING_BASE_ADDR_LO);
+ if ((Value & MASK_31_BITS) != 0)
+ return false;
+
+ return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_CDR_ClearAllDescriptors
+ *
+ * Clear all descriptors
+ */
+static inline void
+EIP202Lib_CDR_ClearAllDescriptors(
+ DMAResource_Handle_t Handle,
+ const uint32_t DescriptorSpacingWordCount,
+ const uint32_t DescriptorSizeWordCount,
+ const uint32_t NumberOfDescriptors)
+{
+ unsigned int i, j;
+
+ for(i = 0; i < NumberOfDescriptors; i++)
+ for(j = 0; j < DescriptorSizeWordCount; j++)
+ DMAResource_Write32(Handle, i * DescriptorSpacingWordCount + j, 0);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Init
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Init(
+ EIP202_Ring_IOArea_t * IOArea_p,
+ const Device_Handle_t Device,
+ const EIP202_CDR_Settings_t * const CDRSettings_p)
+{
+ uint16_t CDFIFOWordCount;
+ EIP202_Ring_Error_t rv;
+ volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p = CDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+
+ // Initialize the IO Area
+ TrueIOArea_p->fValidCountRD = false;
+ TrueIOArea_p->Device = Device;
+ TrueIOArea_p->State = (unsigned int)EIP202_CDR_STATE_UNINITIALIZED;
+
+ // Check if the CPU integer size is enough to store 32-bit value
+ if(sizeof(unsigned int) < sizeof(uint32_t))
+ return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+
+ // Detect presence of EIP-202 CDR hardware
+ if(!EIP202Lib_CDR_Detect(Device))
+ return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+
+ if(CDRSettings_p->fATPtoToken)
+ return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+
+ // Extension of 32-bit pointers to 64-bit addresses not supported.
+ if(CDRSettings_p->Params.DMA_AddressMode == EIP202_RING_64BIT_DMA_EXT_ADDR)
+ return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+
+ if(CDRSettings_p->Params.DscrOffsWordCount == 0 ||
+ CDRSettings_p->Params.DscrOffsWordCount <
+ CDRSettings_p->Params.DscrSizeWordCount)
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ // Ring size cannot be smaller than one descriptor size or
+ // larger than 4194303 (16MB / 4 - 1), in 32-bit words
+ if(CDRSettings_p->Params.RingSizeWordCount <
+ CDRSettings_p->Params.DscrOffsWordCount ||
+ CDRSettings_p->Params.RingSizeWordCount > 4194303)
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ // Read Command Descriptor FIFO size (in 32-bit words)
+ EIP202_CDR_STAT_FIFO_SIZE_RD(Device, &CDFIFOWordCount);
+
+ if(CDRSettings_p->Params.DscrSizeWordCount >
+ EIP202_CD_CTRL_DATA_MAX_WORD_COUNT + IOToken_InWordCount_Get() ||
+ CDRSettings_p->Params.DscrSizeWordCount > CDFIFOWordCount)
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ if(CDRSettings_p->Params.DscrFetchSizeWordCount > CDFIFOWordCount ||
+ CDRSettings_p->Params.DscrThresholdWordCount > CDFIFOWordCount)
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ if(CDRSettings_p->Params.DscrFetchSizeWordCount %
+ CDRSettings_p->Params.DscrOffsWordCount)
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ if( CDRSettings_p->Params.IntThresholdDscrCount >
+ CDRSettings_p->Params.RingSizeWordCount )
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ // Configure the Ring Helper
+ TrueIOArea_p->RingHelperCallbacks.WriteFunc_p = &EIP202_CDR_WriteCB;
+ TrueIOArea_p->RingHelperCallbacks.ReadFunc_p = &EIP202_CDR_ReadCB;
+ TrueIOArea_p->RingHelperCallbacks.StatusFunc_p = &EIP202_CDR_StatusCB;
+ TrueIOArea_p->RingHelperCallbacks.CallbackParam1_p = IOArea_p;
+ TrueIOArea_p->RingHelperCallbacks.CallbackParam2 = 0;
+ TrueIOArea_p->RingHandle = CDRSettings_p->Params.RingDMA_Handle;
+ TrueIOArea_p->DescOffsWordCount = CDRSettings_p->Params.DscrOffsWordCount;
+ TrueIOArea_p->RingSizeWordCount = CDRSettings_p->Params.RingSizeWordCount;
+ TrueIOArea_p->fATP = CDRSettings_p->fATP;
+
+ // Initialize one RingHelper instance for one CDR instance
+ if( RingHelper_Init(
+ (volatile RingHelper_t*)&TrueIOArea_p->RingHelper,
+ (volatile RingHelper_CallbackInterface_t*)&TrueIOArea_p->RingHelperCallbacks,
+ true, // Separate CDR ring
+ (unsigned int)(CDRSettings_p->Params.RingSizeWordCount /
+ CDRSettings_p->Params.DscrOffsWordCount),
+ (unsigned int)(CDRSettings_p->Params.RingSizeWordCount /
+ CDRSettings_p->Params.DscrOffsWordCount)) < 0)
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ // Transit to a new state
+ rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+ EIP202_CDR_STATE_INITIALIZED);
+ if(rv != EIP202_RING_NO_ERROR)
+ return EIP202_RING_ILLEGAL_IN_STATE;
+
+ // Prepare the CDR DMA buffer
+ // Initialize all descriptors with zero for CDR
+ EIP202Lib_CDR_ClearAllDescriptors(
+ TrueIOArea_p->RingHandle,
+ CDRSettings_p->Params.DscrOffsWordCount,
+ CDRSettings_p->Params.DscrSizeWordCount,
+ CDRSettings_p->Params.RingSizeWordCount /
+ CDRSettings_p->Params.DscrOffsWordCount);
+
+ // Call PreDMA to make sure engine sees it
+ DMAResource_PreDMA(TrueIOArea_p->RingHandle,
+ 0,
+ (unsigned int)(TrueIOArea_p->RingSizeWordCount*4));
+
+ EIP202_CDR_RING_BASE_ADDR_LO_WR(
+ Device,
+ CDRSettings_p->Params.RingDMA_Address.Addr);
+
+ EIP202_CDR_RING_BASE_ADDR_HI_WR(
+ Device,
+ CDRSettings_p->Params.RingDMA_Address.UpperAddr);
+
+ EIP202_CDR_RING_SIZE_WR(
+ Device,
+ CDRSettings_p->Params.RingSizeWordCount);
+
+ EIP202_CDR_DESC_SIZE_WR(
+ Device,
+ CDRSettings_p->Params.DscrSizeWordCount,
+ CDRSettings_p->Params.DscrOffsWordCount,
+ CDRSettings_p->fATPtoToken,
+ CDRSettings_p->fATP,
+ CDRSettings_p->Params.DMA_AddressMode == EIP202_RING_64BIT_DMA_DSCR_PTR);
+
+ EIP202_CDR_CFG_WR(
+ Device,
+ CDRSettings_p->Params.DscrFetchSizeWordCount,
+ CDRSettings_p->Params.DscrThresholdWordCount);
+
+ EIP202_CDR_DMA_CFG_WR(
+ Device,
+ (uint8_t)CDRSettings_p->Params.ByteSwap_Descriptor_Mask,
+ (uint8_t)CDRSettings_p->Params.ByteSwap_Packet_Mask,
+ (uint8_t)CDRSettings_p->Params.ByteSwap_Token_Mask,
+ // Bufferability control
+ true, // Buffer Ownership Word DMA writes
+ EIP202_RING_CD_WR_CACHE_CTRL, // Write cache type control
+ EIP202_RING_CD_RD_CACHE_CTRL, // Read cache type control
+ EIP202_RING_CD_PROT_VALUE,
+ EIP202_RING_DATA_PROT_VALUE,
+ EIP202_RING_ACD_PROT_VALUE);
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Reset
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Reset(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ const Device_Handle_t Device)
+{
+ EIP202_Ring_Error_t rv;
+ volatile EIP202_CDR_True_IOArea_t * const TrueIOArea_p = CDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+
+ // Initialize the IO Area
+ memset((void*)IOArea_p, 0, sizeof(*TrueIOArea_p));
+ TrueIOArea_p->Device = Device;
+ TrueIOArea_p->State = (unsigned int)EIP202_CDR_STATE_UNKNOWN;
+
+ // Transit to a new state
+ rv = EIP202_CDR_State_Set((volatile EIP202_CDR_State_t*)&TrueIOArea_p->State,
+ EIP202_CDR_STATE_UNINITIALIZED);
+ if(rv != EIP202_RING_NO_ERROR)
+ return EIP202_RING_ILLEGAL_IN_STATE;
+
+ // Clear CDR count
+ EIP202_CDR_COUNT_WR(Device, 0, true);
+
+ // Re-init CDR
+ EIP202_CDR_POINTER_DEFAULT_WR(Device);
+
+ // Restore default register values
+ EIP202_CDR_RING_BASE_ADDR_LO_DEFAULT_WR(Device);
+ EIP202_CDR_RING_BASE_ADDR_HI_DEFAULT_WR(Device);
+ EIP202_CDR_RING_SIZE_DEFAULT_WR(Device);
+ EIP202_CDR_DESC_SIZE_DEFAULT_WR(Device);
+ EIP202_CDR_CFG_DEFAULT_WR(Device);
+ EIP202_CDR_DMA_CFG_DEFAULT_WR(Device);
+
+ // Clear and disable all CDR interrupts
+ EIP202_CDR_STAT_CLEAR_ALL_IRQ_WR(Device);
+
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Options_Get
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_CDR_Options_Get(
+ const Device_Handle_t Device,
+ EIP202_Ring_Options_t * const Options_p)
+{
+ uint32_t Rev;
+
+ EIP202_RING_CHECK_POINTER(Options_p);
+
+ // Note: thie register does not exist in all versions of the device.
+ // If it exists, the options register is also available.
+ Rev = EIP202_CDR_Read32(Device, EIP202_CDR_VERSION);
+ if ( !EIP202_CDR_REV_SIGNATURE_MATCH((uint16_t)Rev))
+ {
+ // No local CDR version and options registers available,
+ // function not supported
+ return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+ }
+
+ EIP202_CDR_OPTIONS_RD(Device,
+ &Options_p->NofRings,
+ &Options_p->NofPes,
+ &Options_p->fExpPlf,
+ &Options_p->CF_Size,
+ &Options_p->RF_Size,
+ &Options_p->HostIfc,
+ &Options_p->DMA_Len,
+ &Options_p->HDW,
+ &Options_p->TgtAlign,
+ &Options_p->fAddr64);
+
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_CDR_Dump
+ *
+ */
+void
+EIP202_CDR_Dump(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ EIP202_RingAdmin_t * const RingAdmin_p)
+{
+ EIP202_RDR_True_IOArea_t * const TrueIOArea_p =
+ (EIP202_RDR_True_IOArea_t * const)IOArea_p;
+
+ if(!TrueIOArea_p)
+ return;
+
+ if(!RingAdmin_p)
+ return;
+
+ RingAdmin_p->IN_Size = TrueIOArea_p->RingHelper.IN_Size;
+ RingAdmin_p->IN_Tail = TrueIOArea_p->RingHelper.IN_Tail;
+ RingAdmin_p->OUT_Size = TrueIOArea_p->RingHelper.OUT_Size;
+ RingAdmin_p->OUT_Head = TrueIOArea_p->RingHelper.OUT_Head;
+
+ RingAdmin_p->fSeparate = TrueIOArea_p->RingHelper.fSeparate;
+
+ RingAdmin_p->DescOffsWordCount = TrueIOArea_p->DescOffsWordCount;
+ RingAdmin_p->RingSizeWordCount = TrueIOArea_p->RingSizeWordCount;
+}
+
+
+/* end of file eip202_cdr_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_global_init.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_global_init.c
new file mode 100644
index 0000000..7a0006d
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_global_init.c
@@ -0,0 +1,457 @@
+/* eip202_global_init.c
+ *
+ * EIP-202 Global Control Driver Library
+ * Initialization Module
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_global_init.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip97_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // uint32_t
+
+// Driver Framework C Run-time Library API
+#include "clib.h" // ZEROINIT
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+
+#include "eip202_global_level0.h" // EIP-202 Level 0 macros
+
+// EIP97_Interfaces_Get
+#include "eip97_global_internal.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Detect
+ */
+bool
+EIP202_Global_Detect(
+ const Device_Handle_t Device)
+{
+ uint32_t Value;
+
+ Value = EIP202_Read32(Device, EIP202_G_REG_VERSION);
+ if (!EIP202_REV_SIGNATURE_MATCH( Value ))
+ return false;
+
+ return true;
+}
+
+
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_HWRevision_Get
+ */
+void
+EIP202_Global_HWRevision_Get(
+ const Device_Handle_t Device,
+ EIP202_Capabilities_t * const Capabilities_p)
+{
+ EIP202_EIP_REV_RD(Device,
+ &Capabilities_p->EipNumber,
+ &Capabilities_p->ComplmtEipNumber,
+ &Capabilities_p->HWPatchLevel,
+ &Capabilities_p->MinHWRevision,
+ &Capabilities_p->MajHWRevision);
+
+ EIP202_OPTIONS_RD(Device,
+ &Capabilities_p->NofRings,
+ &Capabilities_p->NofPes,
+ &Capabilities_p->fExpPlf,
+ &Capabilities_p->CF_Size,
+ &Capabilities_p->RF_Size,
+ &Capabilities_p->HostIfc,
+ &Capabilities_p->DMA_Len,
+ &Capabilities_p->HDW,
+ &Capabilities_p->TgtAlign,
+ &Capabilities_p->fAddr64);
+
+ EIP202_OPTIONS2_RD(Device,
+ &Capabilities_p->NofLA_Ifs,
+ &Capabilities_p->NofIN_Ifs,
+ &Capabilities_p->NofAXI_WrChs,
+ &Capabilities_p->NofAXI_RdClusters,
+ &Capabilities_p->NofAXI_RdCPC);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Endianness_Slave_Configure
+ *
+ * Configure Endianness Conversion method
+ * for the EIP-202 slave (MMIO) interface
+ *
+ */
+bool
+EIP202_Global_Endianness_Slave_Configure(
+ const Device_Handle_t Device)
+{
+#ifdef EIP97_GLOBAL_ENABLE_SWAP_REG_DATA
+ uint32_t Value;
+
+ // Read and check the revision register
+ Value = EIP202_Read32(Device, EIP202_G_REG_VERSION);
+ if (!EIP202_REV_SIGNATURE_MATCH( Value ))
+ {
+ // No match, try to enable the Slave interface byte swap
+ // Must be done via EIP-202 HIA GLobal
+ EIP202_MST_CTRL_BYTE_SWAP_UPDATE(Device, true);
+
+ // Read and check the revision register again
+ Value = EIP202_Read32(Device, EIP202_G_REG_VERSION);
+ if (!EIP202_REV_SIGNATURE_MATCH( Value ))
+ // Bail out if still not OK
+ return false;
+ }
+
+ return true;
+#else
+ IDENTIFIER_NOT_USED(Device);
+ return true;
+#endif // EIP97_GLOBAL_ENABLE_SWAP_REG_DATA
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Init
+ */
+void
+EIP202_Global_Init(
+ const Device_Handle_t Device,
+ unsigned int NofPE,
+ unsigned int NofLA,
+ uint8_t ipbuf_min,
+ uint8_t ipbuf_max,
+ uint8_t itbuf_min,
+ uint8_t itbuf_max,
+ uint8_t opbuf_min,
+ uint8_t opbuf_max)
+{
+ unsigned int i;
+ uint8_t BufferCtrl;
+ unsigned int NofPEs,NofRings,NofLAs,NofIN,DFEDSEOffset;
+ EIP97_Interfaces_Get(&NofPEs,&NofRings,&NofLAs,&NofIN);
+ DFEDSEOffset = EIP97_DFEDSE_Offset_Get();
+
+ // Configure EIP-202 HIA Global
+ EIP202_MST_CTRL_BUS_BURST_SIZE_UPDATE(Device,
+ EIP97_GLOBAL_BUS_BURST_SIZE,
+ EIP97_GLOBAL_RX_BUS_BURST_SIZE);
+ EIP202_MST_CTRL_BUS_TIMEOUT_UPDATE(Device,
+ EIP97_GLOBAL_TIMEOUT_VALUE);
+ if (NofLA)
+ // User-configured value
+ BufferCtrl = EIP97_GLOBAL_DSE_BUFFER_CTRL;
+ else
+ // Default register reset value
+ BufferCtrl = (uint8_t)EIP202_DSE_BUFFER_CTRL;
+
+ for (i = 0; i < NofPE; i++)
+ {
+ // Configure EIP-202 HIA DFE Global
+ EIP202_DFE_CFG_WR(Device,
+ DFEDSEOffset,
+ i,
+ ipbuf_min,
+ EIP97_GLOBAL_DFE_DATA_CACHE_CTRL,
+ ipbuf_max,
+ itbuf_min,
+ EIP97_GLOBAL_DFE_CTRL_CACHE_CTRL,
+ itbuf_max,
+ (EIP97_GLOBAL_DFE_ADV_THRESH_MODE_FLAG == 1),
+ (EIP97_GLOBAL_DFE_AGGRESSIVE_DMA_FLAG == 1));
+
+ // Configure EIP-202 HIA DSE Global
+ EIP202_DSE_CFG_WR(Device,
+ DFEDSEOffset,
+ i,
+ opbuf_min,
+ EIP97_GLOBAL_DSE_DATA_CACHE_CTRL,
+ opbuf_max,
+ BufferCtrl,
+ (EIP97_GLOBAL_DSE_ENABLE_SINGLE_WR_FLAG == 1),
+ (EIP97_GLOBAL_DSE_AGGRESSIVE_DMA_FLAG == 1));
+
+ }
+
+ // Configure HIA Look-aside FIFO
+ EIP202_LASIDE_BASE_ADDR_LO_WR(Device,
+ EIP202_LASIDE_DSCR_BYTE_SWAP_METHOD);
+
+ for (i = EIP97_GLOBAL_LAFIFO_RING_ID;
+ i < NofLAs +
+ EIP97_GLOBAL_LAFIFO_RING_ID;
+ i++)
+ {
+ EIP202_LASIDE_SLAVE_CTRL_WR(Device,
+ i,
+ EIP202_LASIDE_IN_PKT_BYTE_SWAP_METHOD,
+ EIP202_LASIDE_IN_PKT_PROTO,
+ EIP202_LASIDE_TOKEN_BYTE_SWAP_METHOD,
+ EIP202_LASIDE_TOKEN_PROTO,
+ true); // Clear cmd descriptor error
+
+ EIP202_LASIDE_MASTER_CTRL_WR(Device,
+ i,
+ EIP202_LASIDE_OUT_PKT_BYTE_SWAP_METHOD,
+ EIP202_LASIDE_OUT_PKT_PROTO,
+ true); // Clear res descriptor error
+ }
+ // Configure HIA Inline FIFO
+ for (i = 0; i < NofIN; i++)
+ EIP202_INLINE_CTRL_WR(Device,
+ i,
+ EIP202_INLINE_IN_PKT_BYTE_SWAP_METHOD,
+ false, // Clear protocol error
+ EIP202_INLINE_OUT_PKT_BYTE_SWAP_METHOD,
+ opbuf_min,
+ opbuf_max,
+ EIP202_INLINE_BURST_SIZE,
+ EIP202_INLINE_FORCE_INORDER);
+
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Reset
+ */
+bool
+EIP202_Global_Reset(
+ const Device_Handle_t Device,
+ const unsigned int NofPE)
+{
+ unsigned int i;
+ unsigned int DFEDSEOffset;
+ DFEDSEOffset = EIP97_DFEDSE_Offset_Get();
+
+ // Restore the EIP-202 default configuration
+ // Resets DFE thread and clears ring assignment
+ for (i = 0; i < NofPE; i++)
+ EIP202_DFE_TRD_CTRL_WR(Device, DFEDSEOffset, i, 0, false, true);
+
+ // HIA DFE defaults
+ for (i = 0; i < NofPE; i++)
+ EIP202_DFE_CFG_DEFAULT_WR(Device, DFEDSEOffset, i);
+
+#ifndef EIP202_RA_DISABLE
+ EIP202_RA_PRIO_0_DEFAULT_WR(Device);
+ EIP202_RA_PRIO_1_DEFAULT_WR(Device);
+ EIP202_RA_PRIO_2_DEFAULT_WR(Device);
+ EIP202_RA_PRIO_3_DEFAULT_WR(Device);
+
+ // Resets ring assignment
+ for (i = 0; i < NofPE; i++)
+ EIP202_RA_PE_CTRL_WR(Device, i, 0, false, true);
+#endif // #ifndef EIP202_RA_DISABLE
+
+ // Resets DSE thread and clears ring assignment
+ for (i = 0; i < NofPE; i++)
+ EIP202_DSE_TRD_CTRL_WR(Device, DFEDSEOffset, i, 0, false, true);
+
+ // HIA DSE defaults
+ for (i = 0; i < NofPE; i++)
+ EIP202_DSE_CFG_DEFAULT_WR(Device, DFEDSEOffset, i);
+
+
+ // HIA LASIDE defaults
+ EIP202_LASIDE_BASE_ADDR_LO_DEFAULT_WR(Device);
+ EIP202_LASIDE_BASE_ADDR_HI_DEFAULT_WR(Device);
+ for (i = EIP97_GLOBAL_LAFIFO_RING_ID;
+ i < EIP97_GLOBAL_MAX_NOF_LAFIFO_TO_USE + EIP97_GLOBAL_LAFIFO_RING_ID;
+ i++)
+ {
+ EIP202_LASIDE_MASTER_CTRL_DEFAULT_WR(Device, i);
+ EIP202_LASIDE_SLAVE_CTRL_DEFAULT_WR(Device, i);
+ }
+
+ // HIA INLINE defaults
+ for (i = 0; i < NofPE; i++)
+ EIP202_INLINE_CTRL_DEFAULT_WR(Device, i);
+ return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Reset_IsDone
+ */
+bool
+EIP202_Global_Reset_IsDone(
+ const Device_Handle_t Device,
+ const unsigned int PEnr)
+{
+ uint8_t RingId;
+ unsigned int DFEDSEOffset;
+ DFEDSEOffset = EIP97_DFEDSE_Offset_Get();
+
+ // Check for completion of all DMA transfers
+ EIP202_DFE_TRD_STAT_RINGID_RD(Device, DFEDSEOffset, PEnr, &RingId);
+ if(RingId == EIP202_DFE_TRD_REG_STAT_IDLE)
+ {
+ EIP202_DSE_TRD_STAT_RINGID_RD(Device, DFEDSEOffset, PEnr, &RingId);
+ if(RingId == EIP202_DFE_TRD_REG_STAT_IDLE)
+ {
+ // Take DFE thread out of reset
+ EIP202_DFE_TRD_CTRL_DEFAULT_WR(Device, DFEDSEOffset, PEnr);
+
+ // Take DSE thread out of reset
+ EIP202_DSE_TRD_CTRL_DEFAULT_WR(Device, DFEDSEOffset, PEnr);
+
+ // Do not restore the EIP-202 Master Control default configuration
+ // so this will not change the endianness conversion configuration
+ // for the Slave interface
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Global_Configure
+ */
+void
+EIP202_Global_Configure(
+ const Device_Handle_t Device,
+ const unsigned int PE_Number,
+ const EIP202_Global_Ring_PE_Map_t * const RingPEMap_p)
+{
+ unsigned int DFEDSEOffset;
+ DFEDSEOffset = EIP97_DFEDSE_Offset_Get();
+ // Disable EIP-202 HIA DFE thread(s)
+ EIP202_DFE_TRD_CTRL_WR(Device,
+ DFEDSEOffset,
+ PE_Number, // Thread Nr
+ 0,
+ false, // Disable thread
+ false); // Do not reset thread
+
+ // Disable EIP-202 HIA DSE thread(s)
+ EIP202_DSE_TRD_CTRL_WR(Device,
+ DFEDSEOffset,
+ PE_Number, // Thread Nr
+ 0,
+ false, // Disable thread
+ false); // Do not reset thread
+
+#ifndef EIP202_RA_DISABLE
+ // Configure the HIA Ring Arbiter
+ EIP202_RA_PRIO_0_WR(
+ Device,
+ (RingPEMap_p->RingPrio_Mask & BIT_0) == 0 ? false : true,
+ (uint8_t)(RingPEMap_p->RingSlots0 & MASK_4_BITS),
+ (RingPEMap_p->RingPrio_Mask & BIT_1) == 0 ? false : true,
+ (uint8_t)((RingPEMap_p->RingSlots0 >> 4) & MASK_4_BITS),
+ (RingPEMap_p->RingPrio_Mask & BIT_2) == 0 ? false : true,
+ (uint8_t)((RingPEMap_p->RingSlots0 >> 8) & MASK_4_BITS),
+ (RingPEMap_p->RingPrio_Mask & BIT_3) == 0 ? false : true,
+ (uint8_t)((RingPEMap_p->RingSlots0 >> 12) & MASK_4_BITS));
+
+ EIP202_RA_PRIO_1_WR(
+ Device,
+ (RingPEMap_p->RingPrio_Mask & BIT_4) == 0 ? false : true,
+ (uint8_t)((RingPEMap_p->RingSlots0 >> 16) & MASK_4_BITS),
+ (RingPEMap_p->RingPrio_Mask & BIT_5) == 0 ? false : true,
+ (uint8_t)((RingPEMap_p->RingSlots0 >> 20) & MASK_4_BITS),
+ (RingPEMap_p->RingPrio_Mask & BIT_6) == 0 ? false : true,
+ (uint8_t)((RingPEMap_p->RingSlots0 >> 24) & MASK_4_BITS),
+ (RingPEMap_p->RingPrio_Mask & BIT_7) == 0 ? false : true,
+ (uint8_t)((RingPEMap_p->RingSlots0 >> 28) & MASK_4_BITS));
+
+ EIP202_RA_PRIO_2_WR(
+ Device,
+ (RingPEMap_p->RingPrio_Mask & BIT_8) == 0 ? false : true,
+ (uint8_t)(RingPEMap_p->RingSlots1 & MASK_4_BITS),
+ (RingPEMap_p->RingPrio_Mask & BIT_9) == 0 ? false : true,
+ (uint8_t)((RingPEMap_p->RingSlots1 >> 4) & MASK_4_BITS),
+ (RingPEMap_p->RingPrio_Mask & BIT_10) == 0 ? false : true,
+ (uint8_t)((RingPEMap_p->RingSlots1 >> 8) & MASK_4_BITS),
+ (RingPEMap_p->RingPrio_Mask & BIT_11) == 0 ? false : true,
+ (uint8_t)((RingPEMap_p->RingSlots1 >> 12) & MASK_4_BITS));
+
+ EIP202_RA_PRIO_3_WR(
+ Device,
+ (RingPEMap_p->RingPrio_Mask & BIT_12) == 0 ? false : true,
+ (uint8_t)((RingPEMap_p->RingSlots1 >> 16) & MASK_4_BITS),
+ (RingPEMap_p->RingPrio_Mask & BIT_13) == 0 ? false : true,
+ (uint8_t)((RingPEMap_p->RingSlots1 >> 20) & MASK_4_BITS),
+ (RingPEMap_p->RingPrio_Mask & BIT_14) == 0 ? false : true,
+ (uint8_t)((RingPEMap_p->RingSlots1 >> 24) & MASK_4_BITS));
+
+ // Ring assignment in the Ring Arbiter
+ EIP202_RA_PE_CTRL_WR(Device,
+ PE_Number,
+ RingPEMap_p->RingPE_Mask,
+ true,
+ false);
+#endif // #ifndef EIP202_RA_DISABLE
+
+ {
+ // Assign Rings to this DFE thread
+ // Enable EIP-202 HIA DFE thread(s)
+ EIP202_DFE_TRD_CTRL_WR(Device,
+ DFEDSEOffset,
+ PE_Number, // Thread Nr
+ RingPEMap_p->RingPE_Mask, // Rings to assign
+ true, // Enable thread
+ false); // Do not reset thread
+
+ // Assign Rings to this DSE thread
+ // Enable EIP-202 HIA DSE thread(s)
+ EIP202_DSE_TRD_CTRL_WR(Device,
+ DFEDSEOffset,
+ PE_Number, // Thread Nr
+ RingPEMap_p->RingPE_Mask, // Rings to assign
+ true, // Enable thread
+ false); // Do not reset thread
+ }
+}
+
+/* end of file eip202_global_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rd_format.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rd_format.c
new file mode 100644
index 0000000..d3ce3c6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rd_format.c
@@ -0,0 +1,313 @@
+/* eip202_rd_format.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * Result Descriptor Internal interface
+ *
+ * This module contains the EIP-202 Result Descriptor specific functionality
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_rd_format.h"
+
+// Descriptor I/O Driver Library API implementation
+#include "eip202_rdr.h" // EIP202_ARM_CommandDescriptor_t
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // bool, uint32_t, uint8_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h" // DMAResource_Handle_t
+#include "dmares_rw.h" // DMAResource_Write/Read
+
+// Standard IOToken API
+#include "iotoken.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RD_Make_ControlWord
+ */
+uint32_t
+EIP202_RD_Make_ControlWord(
+ const uint8_t ExpectedResultWordCount,
+ const uint32_t PrepSegmentByteCount,
+ const bool fFirstSegment,
+ const bool fLastSegment)
+{
+ uint32_t Value = 0;
+
+ if(fFirstSegment)
+ Value |= BIT_23;
+
+ if(fLastSegment)
+ Value |= BIT_22;
+
+ Value |= ((((uint32_t)ExpectedResultWordCount) & MASK_8_BITS) << 24);
+ Value |= ((((uint32_t)PrepSegmentByteCount) & MASK_20_BITS));
+
+ return Value;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_Prepared_Write
+ */
+void
+EIP202_Prepared_Write(
+ DMAResource_Handle_t Handle,
+ const unsigned int WordOffset,
+ const EIP202_ARM_PreparedDescriptor_t * const Descr_p)
+{
+#ifdef EIP202_64BIT_DEVICE
+ // Write Control Word
+ DMAResource_Write32(Handle, WordOffset, Descr_p->PrepControlWord);
+
+ // Do not support lengths greater than 20 bit.
+ DMAResource_Write32(Handle, WordOffset + 1, 0);
+
+ // Write Destination Packet Data address
+ DMAResource_Write32(Handle, WordOffset + 2, Descr_p->DstPacketAddr.Addr);
+ DMAResource_Write32(Handle, WordOffset + 3, Descr_p->DstPacketAddr.UpperAddr);
+
+#else
+ // Write Control Word
+ DMAResource_Write32(Handle, WordOffset, Descr_p->PrepControlWord);
+
+ // Write Destination Packet Data address
+ DMAResource_Write32(Handle, WordOffset + 1, Descr_p->DstPacketAddr.Addr);
+#endif
+
+ return;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_ReadDescriptor
+ */
+void
+EIP202_ReadDescriptor(
+ EIP202_ARM_ResultDescriptor_t * const Descr_p,
+ const DMAResource_Handle_t Handle,
+ const unsigned int WordOffset,
+ const unsigned int DscrOffsWordCount,
+ const unsigned int TokenOffsWordCount,
+ bool * const fLastSegment,
+ bool * const fFirstSegment)
+{
+ unsigned int OutTokenWordOffset;
+
+#ifdef EIP202_64BIT_DEVICE
+ // Word 0 - Control Word
+ Descr_p->ProcControlWord = DMAResource_Read32(Handle, WordOffset);
+
+ // Word 1 - extended length, not read.
+
+ // Word 2 & 3 - Destination Packet Data Buffer Address
+ Descr_p->DstPacketAddr.Addr = DMAResource_Read32(Handle, WordOffset + 2);
+ Descr_p->DstPacketAddr.UpperAddr = DMAResource_Read32(Handle, WordOffset + 3);
+
+ OutTokenWordOffset = WordOffset + TokenOffsWordCount;
+#else // EIP202_64BIT_DEVICE
+ // Word 0 - Control Word
+ Descr_p->ProcControlWord = DMAResource_Read32(Handle, WordOffset);
+
+ // Word 1 - Destination Packet Data Buffer Address
+ Descr_p->DstPacketAddr.Addr = DMAResource_Read32(Handle, WordOffset + 1);
+
+ OutTokenWordOffset = WordOffset + 2;
+#endif // !EIP202_64BIT_DEVICE
+
+ if (Descr_p->Token_p == NULL)
+ {
+ *fLastSegment = false;
+ *fFirstSegment = false;
+ return; // Fatal error
+ }
+
+ // Read token data
+ {
+ unsigned int i;
+
+#ifdef EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
+ for (i = 0; i < IOToken_OutWordCount_Get(); i++)
+ if (i != (unsigned int)IOToken_OutMarkOffset_Get())
+ Descr_p->Token_p[i] = DMAResource_Read32(
+ Handle,
+ OutTokenWordOffset + i);
+#else
+ for (i = 0; i < IOToken_OutWordCount_Get(); i++)
+ Descr_p->Token_p[i] = DMAResource_Read32(
+ Handle,
+ OutTokenWordOffset + i);
+#endif
+ }
+
+ // Check if this descriptor is for the last segment
+ if((Descr_p->ProcControlWord & BIT_22) != 0)
+ *fLastSegment = true; // Processed packet
+ else
+ *fLastSegment = false;
+
+ // Check if this descriptor is for the first segment
+ if((Descr_p->ProcControlWord & BIT_23) != 0)
+ *fFirstSegment = true; // New packet descriptor chain detected
+ else
+ *fFirstSegment = false;
+
+ IDENTIFIER_NOT_USED(DscrOffsWordCount);
+
+ return;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_ClearDescriptor
+ */
+void
+EIP202_ClearDescriptor(
+ EIP202_ARM_ResultDescriptor_t * const Descr_p,
+ const DMAResource_Handle_t Handle,
+ const unsigned int WordOffset,
+ const unsigned int TokenOffsWordCount,
+ const unsigned int DscrWordCount)
+{
+ IDENTIFIER_NOT_USED(Descr_p);
+
+#if defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
+
+ DMAResource_Write32(Handle, WordOffset + DscrWordCount - 1, 0);
+ IDENTIFIER_NOT_USED(TokenOffsWordCount);
+
+#elif defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS)
+
+ IDENTIFIER_NOT_USED(DscrWordCount);
+
+ DMAResource_Write32(Handle,
+ WordOffset + TokenOffsWordCount +
+ IOToken_OutMarkOffset_Get(),
+ 0);
+#else
+ IDENTIFIER_NOT_USED(Handle);
+ IDENTIFIER_NOT_USED(WordOffset);
+ IDENTIFIER_NOT_USED(DscrWordCount);
+ IDENTIFIER_NOT_USED(TokenOffsWordCount);
+#endif // !EIP202_RDR_OWNERSHIP_WORD_ENABLE
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RD_Read_ControlWord
+ */
+void
+EIP202_RD_Read_ControlWord(
+ const uint32_t ControlWord,
+ uint32_t * TokenData_p,
+ EIP202_RDR_Result_Control_t * const RDControl_p,
+ EIP202_RDR_Result_Token_t * const ResToken_p)
+{
+ RDControl_p->ProcSegmentByteCount = (ControlWord & MASK_20_BITS);
+ RDControl_p->ProcResultWordCount = ((ControlWord >> 24) & MASK_8_BITS);
+
+ // Fill in EIP202_RDR_Result_Control_t
+ if((ControlWord & BIT_20) != 0)
+ RDControl_p->fDscrOverflow = true;
+ else
+ RDControl_p->fDscrOverflow = false;
+
+ if((ControlWord & BIT_21) != 0)
+ RDControl_p->fBufferOverflow = true;
+ else
+ RDControl_p->fBufferOverflow = false;
+
+ if((ControlWord & BIT_22) != 0)
+ RDControl_p->fLastSegment = true;
+ else
+ RDControl_p->fLastSegment = false;
+
+ if((ControlWord & BIT_23) != 0)
+ RDControl_p->fFirstSegment = true;
+ else
+ RDControl_p->fFirstSegment = false;
+
+ IDENTIFIER_NOT_USED(TokenData_p);
+ IDENTIFIER_NOT_USED(ResToken_p);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RD_Read_BypassData
+ */
+void
+EIP202_RD_Read_BypassData(
+ const uint32_t * BypassData_p,
+ const uint8_t BypassWordCount,
+ EIP202_RDR_BypassData_t * const BD_p)
+{
+ if (BypassWordCount == 1)
+ {
+ BD_p->Fail.ErrorFlags = BypassData_p[0] & MASK_2_BITS;
+ }
+ else if (BypassWordCount == 2)
+ {
+ BD_p->Pass.TOS_TC = BypassData_p[0] & MASK_8_BITS;
+ BD_p->Pass.fDF = ((BypassData_p[0] & BIT_8) != 0);
+ BD_p->Pass.NextHeaderOffset = (BypassData_p[0] >> 8) & MASK_16_BITS;
+ BD_p->Pass.HdrProcCtxRef = BypassData_p[1];
+ }
+ else
+ {
+ IDENTIFIER_NOT_USED(BypassData_p);
+ IDENTIFIER_NOT_USED(BypassWordCount);
+ IDENTIFIER_NOT_USED(BD_p);
+ }
+}
+
+
+/* end of file eip202_rd_format.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_dscr.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_dscr.c
new file mode 100644
index 0000000..831a486
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_dscr.c
@@ -0,0 +1,735 @@
+/* eip202_rdr_dscr.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * 1) Descriptor I/O Driver Library API implementation
+ * 2) Internal Result Descriptor interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Descriptor I/O Driver Library API implementation
+#include "eip202_rdr.h"
+
+// Internal Result Descriptor interface
+#include "eip202_rdr_dscr.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+#include "eip202_rdr_level0.h" // EIP-202 Level 0 macros
+#include "eip202_rdr_fsm.h" // RDR State machine
+#include "eip202_rd_format.h" // RD Format API
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // IDENTIFIER_NOT_USED, bool, uint32_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h" // types of the DMA resource API
+#include "dmares_rw.h" // read/write of the DMA resource API.
+
+// Standard IOToken API
+#include "iotoken.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// EIP-202 HW limit for the number of packets to acknowledge at once
+#define EIP202_RING_MAX_RD_PACKET_COUNT 127
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_RDR_Prepared_FillLevel_Get
+ */
+static EIP202_Ring_Error_t
+EIP202Lib_RDR_Prepared_FillLevel_Get(
+ const Device_Handle_t Device,
+ volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p,
+ unsigned int * const FillLevelDscrCount_p)
+{
+ unsigned int RDWordCount;
+ EIP202_Ring_Error_t rv;
+
+ EIP202_RDR_PREP_COUNT_RD(Device, (uint32_t*)&RDWordCount);
+
+ // Remain in the current state
+ rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+ (EIP202_RDR_State_t)TrueIOArea_p->State);
+ if(rv != EIP202_RING_NO_ERROR)
+ return EIP202_RING_ILLEGAL_IN_STATE;
+
+ *FillLevelDscrCount_p = RDWordCount /
+ (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+ if(RDWordCount < (unsigned int)TrueIOArea_p->RingSizeWordCount)
+ (*FillLevelDscrCount_p)++;
+
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_RDR_Processed_FillLevel_Finalize
+ */
+static EIP202_Ring_Error_t
+EIP202Lib_RDR_Processed_FillLevel_Finalize(
+ const unsigned int RDWordCount,
+ const unsigned int PktCount,
+ volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p,
+ unsigned int * const FillLevelDscrCount_p,
+ unsigned int * const FillLevelPktCount_p)
+{
+#ifdef EIP202_RING_DEBUG_FSM
+ EIP202_Ring_Error_t rv;
+
+ if(RDWordCount == 0)
+ // CD Ring is empty
+ rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+ EIP202_RDR_STATE_INITIALIZED);
+ else if(RDWordCount > 0 &&
+ RDWordCount < (unsigned int)TrueIOArea_p->RingSizeWordCount)
+ // CD Ring is free
+ rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+ EIP202_RDR_STATE_FREE);
+ else if(RDWordCount == (unsigned int)TrueIOArea_p->RingSizeWordCount)
+ // CD Ring is full
+ rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+ EIP202_RDR_STATE_FULL);
+ else
+ rv = EIP202_RING_ILLEGAL_IN_STATE;
+
+ if(rv != EIP202_RING_NO_ERROR)
+ return EIP202_RING_ILLEGAL_IN_STATE;
+#endif
+
+ *FillLevelDscrCount_p = RDWordCount /
+ (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+ *FillLevelPktCount_p = PktCount;
+
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ Internal Result Descriptor interface
+ ---------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_WriteCB
+ */
+int
+EIP202_RDR_WriteCB(
+ void * const CallbackParam1_p,
+ const int CallbackParam2,
+ const unsigned int WriteIndex,
+ const unsigned int WriteCount,
+ const unsigned int TotalWriteLimit,
+ const void * Descriptors_p,
+ const int DescriptorCount,
+ const unsigned int DescriptorSkipCount)
+{
+ Device_Handle_t Device;
+ unsigned int i, DescOffsetWordCount;
+ unsigned int nWritten = 0;
+ volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p =
+ RDRIOAREA(CallbackParam1_p);
+ if(CallbackParam1_p == NULL || Descriptors_p == NULL)
+ return -1;
+
+ IDENTIFIER_NOT_USED(CallbackParam2);
+ IDENTIFIER_NOT_USED(DescriptorCount);
+ IDENTIFIER_NOT_USED(TotalWriteLimit);
+
+ Device = TrueIOArea_p->Device;
+
+ DescOffsetWordCount = (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+ // Write descriptors to RDR
+ for(i = WriteIndex; i < WriteIndex + WriteCount; i++)
+ {
+ EIP202_Prepared_Write(
+ TrueIOArea_p->RingHandle,
+ i * DescOffsetWordCount,
+ ((const EIP202_ARM_PreparedDescriptor_t *)Descriptors_p) +
+ DescriptorSkipCount + nWritten);
+
+ nWritten++;
+ }
+
+ if (nWritten > 0)
+ {
+ // Call PreDMA to prepared descriptors in Ring DMA buffer for handover
+ // to the Device (the EIP-202 DMA Master)
+ DMAResource_PreDMA(TrueIOArea_p->RingHandle,
+ WriteIndex *
+ DescOffsetWordCount *
+ (unsigned int)sizeof(uint32_t),
+ nWritten *
+ DescOffsetWordCount *
+ (unsigned int)sizeof(uint32_t));
+
+ // CDS point: hand over written Prepared Descriptors to the Device
+ EIP202_RDR_PREP_COUNT_WR(Device,
+ (uint16_t)(nWritten * DescOffsetWordCount),
+ false);
+ }
+
+ return (int)nWritten;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_ReadCB
+ */
+int
+EIP202_RDR_ReadCB(
+ void * const CallbackParam1_p,
+ const int CallbackParam2,
+ const unsigned int ReadIndex,
+ const unsigned int ReadLimit,
+ void * Descriptors_p,
+ const unsigned int DescriptorSkipCount)
+{
+ Device_Handle_t Device;
+ unsigned int i, DescOffsetWordCount;
+ bool fGotDescriptor, fLastSegment = false, fFirstSegment = false;
+ unsigned int GotDscrCount = 0, GotPktCount = 0;
+ volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p =
+ RDRIOAREA(CallbackParam1_p);
+
+ if(CallbackParam1_p == NULL || Descriptors_p == NULL)
+ return -1;
+
+ IDENTIFIER_NOT_USED(CallbackParam2);
+
+ Device = TrueIOArea_p->Device;
+
+ DescOffsetWordCount = (unsigned int )TrueIOArea_p->DescOffsWordCount;
+
+ // Read descriptors from RDR
+ for(i = ReadIndex; i < ReadIndex + ReadLimit; i++)
+ {
+ EIP202_ARM_ResultDescriptor_t * CurrentResultDesc_p =
+ ((EIP202_ARM_ResultDescriptor_t *)Descriptors_p) +
+ DescriptorSkipCount + GotDscrCount;
+
+#define EIP202_RING_RDR_ALL_DESCRIPTORS_TO_GET_DONE \
+ (TrueIOArea_p->AcknowledgedRDCount + GotDscrCount >= \
+ TrueIOArea_p->RDToGetCount)
+
+// This can be true only if the PktRequestedCount parameter in
+// the EIP202_RDR_Descriptor_Get() function is set to a non-zero value
+#define EIP202_RING_RDR_ALL_PACKETS_TO_GET_DONE \
+ (TrueIOArea_p->PktToGetCount > 0 && \
+ TrueIOArea_p->AcknowledgedPktCount + GotPktCount >= \
+ TrueIOArea_p->PktToGetCount)
+
+ // Stop reading the descriptors if all the requested
+ // descriptors and packet chains have been read
+ if(EIP202_RING_RDR_ALL_PACKETS_TO_GET_DONE)
+ {
+ if(EIP202_RING_RDR_ALL_DESCRIPTORS_TO_GET_DONE)
+ break; // for
+ }
+
+ // Call PostDMA before reading descriptors from
+ // the EIP-202 DMA Master
+ DMAResource_PostDMA(TrueIOArea_p->RingHandle,
+ i * DescOffsetWordCount *
+ (unsigned int)sizeof(uint32_t),
+ DescOffsetWordCount *
+ (unsigned int)sizeof(uint32_t));
+
+ // Check if a processed result descriptor is received
+#if defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
+ {
+ uint32_t OwnershipWord =
+ DMAResource_Read32(TrueIOArea_p->RingHandle,
+ i * DescOffsetWordCount +
+ DescOffsetWordCount - 1);
+ fGotDescriptor =
+ (OwnershipWord == EIP202_RDR_OWNERSHIP_WORD_PATTERN);
+#ifdef EIP202_RING_BUS_KEEPALIVE_WORKAROUND
+ // Read from the device to solve a keep-alive problem in some
+ // bus environments.
+ Device_Read32(Device,0);
+#endif
+ }
+#elif defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS)
+ CurrentResultDesc_p->Token_p[IOToken_OutMarkOffset_Get()] =
+ DMAResource_Read32(TrueIOArea_p->RingHandle,
+ i * DescOffsetWordCount +
+ TrueIOArea_p->TokenOffsetWordCount +
+ IOToken_OutMarkOffset_Get());
+ fGotDescriptor = (IOToken_Mark_Check(CurrentResultDesc_p->Token_p) == 0);
+#else
+ fGotDescriptor = true; // according to EIP202_RDR_PROC_COUNT_RD()
+#endif
+
+ if (fGotDescriptor)
+ {
+ // Read Result Descriptor
+ EIP202_ReadDescriptor(CurrentResultDesc_p,
+ TrueIOArea_p->RingHandle,
+ i * DescOffsetWordCount,
+ DescOffsetWordCount,
+ TrueIOArea_p->TokenOffsetWordCount,
+ &fLastSegment,
+ &fFirstSegment);
+
+ // Stop reading the descriptors if all the requested
+ // packet chains have been read and a new processed packet descriptor
+ // chain is detected
+ if(fFirstSegment && EIP202_RING_RDR_ALL_PACKETS_TO_GET_DONE)
+ break; // for
+
+ if (fFirstSegment)
+ TrueIOArea_p->PacketFound = true;
+
+ GotDscrCount++;
+
+ if(TrueIOArea_p->PacketFound && fLastSegment)
+ {
+ GotPktCount++;
+ TrueIOArea_p->PacketFound = false;
+ }
+
+#if defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS) || \
+ defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
+ // Clear this descriptor
+ EIP202_ClearDescriptor(CurrentResultDesc_p,
+ TrueIOArea_p->RingHandle,
+ i * DescOffsetWordCount,
+ TrueIOArea_p->TokenOffsetWordCount,
+ DescOffsetWordCount);
+
+ // Ensure next PostDMA does not undo the clear operation above
+ DMAResource_PreDMA(
+ TrueIOArea_p->RingHandle,
+ i * DescOffsetWordCount * (unsigned int)sizeof(uint32_t),
+ DescOffsetWordCount * (unsigned int)sizeof(uint32_t));
+#endif
+ }
+ else
+ {
+ // The fGotDescriptor is set in EIP202_ReadDescriptor() and
+ // depends on the Application ID field in the result descriptor
+ // when EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS is defined.
+ // In case of a packet descriptor chain the Engine writes the
+ // Application ID field for the last segment descriptor only
+ // but we need to acknowledge all the descriptors of the chain
+ break; // for
+ }
+ } // for
+
+ // Check if there are processed result descriptors and packets
+ // that must be acknowledged
+ if (GotDscrCount > 0)
+ {
+ unsigned int NewGotPktCount;
+
+#if EIP202_RING_RD_INTERRUPTS_PER_PACKET_FLAG != 1
+ GotPktCount = 0;
+#endif
+
+ // EIP-202 HW limits the number of packets to acknowledge at once to
+ // EIP202_RING_MAX_RD_PACKET_COUNT packets
+ NewGotPktCount = MIN(GotPktCount, EIP202_RING_MAX_RD_PACKET_COUNT);
+
+ // CDS point: hand over read Result Descriptors to the Device
+ EIP202_RDR_PROC_COUNT_WR(
+ Device,
+ (uint16_t)(GotDscrCount * DescOffsetWordCount),
+ (uint8_t)NewGotPktCount,
+ false);
+ }
+
+ // Update acknowledged packets counter
+ TrueIOArea_p->AcknowledgedPktCount += GotPktCount;
+
+ // Update acknowledged descriptors counter
+ TrueIOArea_p->AcknowledgedRDCount += GotDscrCount;
+
+ return (int)GotDscrCount;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_StatusCB
+ */
+int
+EIP202_RDR_StatusCB(
+ void * const CallbackParam1_p,
+ const int CallbackParam2,
+ int * const DeviceReadPos_p)
+{
+ IDENTIFIER_NOT_USED(CallbackParam1_p);
+ IDENTIFIER_NOT_USED(CallbackParam2);
+
+ *DeviceReadPos_p = -1; // not used
+
+ return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ Descriptor I/O Driver Library API implementation
+ ---------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_FillLevel_Get
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_FillLevel_Get(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ unsigned int * FillLevelDscrCount_p)
+{
+ int FillLevel;
+ volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+ EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
+
+ FillLevel = RingHelper_FillLevel_Get(
+ (volatile RingHelper_t*)&TrueIOArea_p->RingHelper);
+
+ if(FillLevel < 0)
+ return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+ else
+ {
+ *FillLevelDscrCount_p = (unsigned int)FillLevel;
+ return EIP202_RING_NO_ERROR;
+ }
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Prepared_FillLevel_Get
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Prepared_FillLevel_Get(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ unsigned int * FillLevelDscrCount_p)
+{
+ Device_Handle_t Device;
+ volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+ EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
+
+ Device = TrueIOArea_p->Device;
+
+ return EIP202Lib_RDR_Prepared_FillLevel_Get(Device,
+ TrueIOArea_p,
+ FillLevelDscrCount_p);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Write_Prepared_ControlWord
+ *
+ * This helper function returns the control word that can be written to
+ * the logical prepared descriptor.
+ *
+ * This function is re-entrant.
+ *
+ */
+uint32_t
+EIP202_RDR_Write_Prepared_ControlWord(
+ const EIP202_RDR_Prepared_Control_t * const PreparedCtrl_p)
+{
+ return EIP202_RD_Make_ControlWord(PreparedCtrl_p->ExpectedResultWordCount,
+ PreparedCtrl_p->PrepSegmentByteCount,
+ PreparedCtrl_p->fFirstSegment,
+ PreparedCtrl_p->fLastSegment);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Descriptor_Prepare
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Descriptor_Prepare(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ const EIP202_ARM_PreparedDescriptor_t * PreparedDscr_p,
+ const unsigned int DscrRequestedCount,
+ unsigned int * const DscrPreparedCount_p,
+ unsigned int * FillLevelDscrCount_p)
+{
+ int res, FillLevel;
+ unsigned int RDWordCount, RDFreeCount, DscrNewRequestedCount;
+ volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+ EIP202_RING_CHECK_POINTER(PreparedDscr_p);
+ EIP202_RING_CHECK_POINTER(DscrPreparedCount_p);
+ EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
+
+ // Check how many more descriptors can be added (prepared) to RDR
+ FillLevel = RingHelper_FillLevel_Get(
+ (volatile RingHelper_t*)&TrueIOArea_p->RingHelper);
+ if(FillLevel < 0)
+ return EIP202_RING_ARGUMENT_ERROR; // Error, RDR admin corrupted
+
+ // Check if RDR is full
+ RDWordCount = ((unsigned int)FillLevel *
+ (unsigned int)TrueIOArea_p->DescOffsWordCount);
+ if(RDWordCount == (unsigned int)TrueIOArea_p->RingSizeWordCount)
+ {
+ // RD Ring is full
+ *FillLevelDscrCount_p = (unsigned int)FillLevel;
+ *DscrPreparedCount_p = 0;
+
+ // Remain in the current state
+ return EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+ (EIP202_RDR_State_t)TrueIOArea_p->State);
+ }
+
+ // Calculate the maximum number of descriptors that can be added to RDR
+ RDFreeCount =
+ ((unsigned int)TrueIOArea_p->RingSizeWordCount - RDWordCount) /
+ (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+ DscrNewRequestedCount = MIN(RDFreeCount, DscrRequestedCount);
+
+ res = RingHelper_Put((volatile RingHelper_t*)&TrueIOArea_p->RingHelper,
+ PreparedDscr_p,
+ (int)DscrNewRequestedCount);
+ if(res >= 0)
+ *DscrPreparedCount_p = (unsigned int)res;
+ else
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ // Get the current RDR fill level
+ FillLevel = RingHelper_FillLevel_Get(
+ (volatile RingHelper_t*)&TrueIOArea_p->RingHelper);
+ if(FillLevel < 0)
+ return EIP202_RING_ARGUMENT_ERROR; // Error, RDR admin corrupted
+ else
+ {
+ *FillLevelDscrCount_p = (unsigned int)FillLevel;
+ return EIP202_RING_NO_ERROR;
+ }
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Processed_FillLevel_Get
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Processed_FillLevel_Get(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ unsigned int * FillLevelDscrCount_p,
+ unsigned int * FillLevelPktCount_p)
+{
+// If configured then the driver cannot rely on the register counter
+#if defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS) || \
+ defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
+ IDENTIFIER_NOT_USED(FillLevelDscrCount_p);
+ IDENTIFIER_NOT_USED(FillLevelPktCount_p);
+ IDENTIFIER_NOT_USED(IOArea_p);
+
+ return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+#else
+ Device_Handle_t Device;
+ unsigned int RDWordCount, PktCount;
+ volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+ EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
+ EIP202_RING_CHECK_POINTER(FillLevelPktCount_p);
+
+ Device = TrueIOArea_p->Device;
+
+ {
+ uint8_t Value8;
+ uint32_t Value32;
+
+ EIP202_RDR_PROC_COUNT_RD(Device, &Value32, &Value8);
+
+ RDWordCount = (unsigned int)Value32;
+ PktCount = (unsigned int)Value8;
+ }
+
+ return EIP202Lib_RDR_Processed_FillLevel_Finalize(RDWordCount,
+ PktCount,
+ TrueIOArea_p,
+ FillLevelDscrCount_p,
+ FillLevelPktCount_p);
+#endif // EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Read_Processed_ControlWord
+ */
+void
+EIP202_RDR_Read_Processed_ControlWord(
+ EIP202_ARM_ResultDescriptor_t * const ResDscr_p,
+ EIP202_RDR_Result_Control_t * const RDControl_p,
+ EIP202_RDR_Result_Token_t * const ResToken_p)
+{
+ IDENTIFIER_NOT_USED(ResToken_p);
+
+ EIP202_RD_Read_ControlWord(ResDscr_p->ProcControlWord,
+ NULL,
+ RDControl_p,
+ NULL);
+
+ return;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Read_Processed_BypassData
+ */
+void
+EIP202_RDR_Read_Processed_BypassData(
+ const EIP202_RDR_Result_Token_t * const ResToken_p,
+ EIP202_RDR_BypassData_t * const BD_p)
+{
+ EIP202_RD_Read_BypassData(ResToken_p->BypassData_p,
+ ResToken_p->BypassWordCount,
+ BD_p);
+
+ return;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Descriptor_Get
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Descriptor_Get(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ EIP202_ARM_ResultDescriptor_t * ResultDscr_p,
+ const unsigned int PktRequestedCount,
+ const unsigned int DscrRequestedCount,
+ unsigned int * const DscrDoneCount_p,
+ unsigned int * FillLevelDscrCount_p)
+{
+ Device_Handle_t Device;
+ int res;
+ unsigned int RDWordCount, ProcDsrcCount, ProcPktCount;
+ volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+ EIP202_RING_CHECK_POINTER(ResultDscr_p);
+ EIP202_RING_CHECK_POINTER(DscrDoneCount_p);
+ EIP202_RING_CHECK_POINTER(FillLevelDscrCount_p);
+
+ if(DscrRequestedCount == 0)
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ Device = TrueIOArea_p->Device;
+
+ // Check how many descriptors can be obtained
+ {
+ uint8_t Value8;
+ uint32_t Value32;
+
+#ifdef EIP202_RDR_OWNERSHIP_WORD_ENABLE
+ Value32 = MIN(PktRequestedCount, DscrRequestedCount);
+ Value8 = MIN(EIP202_RING_MAX_RD_PACKET_COUNT, Value32);
+ Value32 = Value8 * TrueIOArea_p->DescOffsWordCount;
+ IDENTIFIER_NOT_USED(Device);
+#else
+ EIP202_RDR_PROC_COUNT_RD(Device, &Value32, &Value8);
+#endif
+ RDWordCount = (unsigned int)Value32;
+ ProcPktCount = (unsigned int)Value8;
+ }
+
+ // Check if RDR is empty or
+ // if RDR has no fully processed packet descriptor chain
+ if(RDWordCount == 0 ||
+ (PktRequestedCount != 0 && ProcPktCount == 0))
+ {
+ // Nothing to do
+ *FillLevelDscrCount_p = 0;
+ *DscrDoneCount_p = 0;
+
+ return EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+ EIP202_RDR_STATE_INITIALIZED);
+ }
+
+ ProcDsrcCount = RDWordCount /
+ (unsigned int)TrueIOArea_p->DescOffsWordCount;
+
+ TrueIOArea_p->AcknowledgedRDCount = 0;
+ TrueIOArea_p->AcknowledgedPktCount = 0;
+ TrueIOArea_p->RDToGetCount = MIN(ProcDsrcCount, DscrRequestedCount);
+ TrueIOArea_p->PktToGetCount = MIN(ProcPktCount, PktRequestedCount);
+
+ // Get processed (result) descriptors
+ res = RingHelper_Get((volatile RingHelper_t*)&TrueIOArea_p->RingHelper,
+// If configured then the driver cannot rely on the register counter
+#if defined(EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS) || \
+ defined(EIP202_RDR_OWNERSHIP_WORD_ENABLE)
+ -1, // Certainly available RD count unknown
+#else
+ (int)TrueIOArea_p->RDToGetCount,
+#endif // EIP202_RING_ANTI_DMA_RACE_CONDITION_CDS
+ ResultDscr_p,
+ (int)DscrRequestedCount);
+ if(res >= 0)
+ *DscrDoneCount_p = (unsigned int)res;
+ else
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ // Increase the fill level by the number of successfully got descriptors
+ RDWordCount -= ((unsigned int)res *
+ (unsigned int)TrueIOArea_p->DescOffsWordCount);
+
+ // Increase the fill level by the number of acknowledged packets
+ ProcPktCount -= TrueIOArea_p->AcknowledgedPktCount;
+
+ return EIP202Lib_RDR_Processed_FillLevel_Finalize(RDWordCount,
+ ProcPktCount,
+ TrueIOArea_p,
+ FillLevelDscrCount_p,
+ &ProcPktCount);
+}
+
+
+/* end of file eip202_rdr_dscr.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_event.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_event.c
new file mode 100644
index 0000000..6f6efc8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_event.c
@@ -0,0 +1,230 @@
+/* eip202_rdr_event.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * CDR Event Management API implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_rdr.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+#include "eip202_rdr_level0.h" // EIP-202 Level 0 macros
+#include "eip202_rdr_fsm.h" // RDR State machine
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // IDENTIFIER_NOT_USED, bool, uint32_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Status_Get
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Status_Get(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ EIP202_RDR_Status_t * const Status_p)
+{
+ Device_Handle_t Device;
+ EIP202_Ring_Error_t rv;
+ volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+ EIP202_RING_CHECK_POINTER(Status_p);
+
+ Device = TrueIOArea_p->Device;
+
+ EIP202_RDR_PREP_COUNT_RD(Device, &Status_p->RDPrepWordCount);
+ EIP202_RDR_PROC_COUNT_RD(Device,
+ &Status_p->RDProcWordCount,
+ &Status_p->RDProcPktWordCount);
+
+ EIP202_RDR_STAT_RD(Device,
+ &Status_p->fDMAError,
+ &Status_p->fTresholdInt,
+ &Status_p->fError,
+ &Status_p->fOUFlowError,
+ &Status_p->fTimeoutInt,
+ &Status_p->fRDBufOverflowInt,
+ &Status_p->fRDOverflowInt,
+ &Status_p->RDFIFOWordCount);
+
+ // Transit to a new state
+ if(Status_p->fDMAError)
+ rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+ EIP202_RDR_STATE_FATAL_ERROR);
+ else
+ // Remain in the current state
+ rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+ (EIP202_RDR_State_t)TrueIOArea_p->State);
+ if(rv != EIP202_RING_NO_ERROR)
+ return EIP202_RING_ILLEGAL_IN_STATE;
+
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Processed_FillLevel_High_INT_Enable
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Processed_FillLevel_High_INT_Enable(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ const unsigned int ThresholdDscrCount,
+ const unsigned int Timeout,
+ const bool fIntPerPacket)
+{
+ Device_Handle_t Device;
+ EIP202_Ring_Error_t rv;
+ volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+
+ if(EIP202_RING_RD_INTERRUPTS_PER_PACKET_FLAG == 0 && fIntPerPacket)
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ Device = TrueIOArea_p->Device;
+
+ if (fIntPerPacket)
+ {
+ EIP202_RDR_THRESH_WR(Device,
+ (uint32_t)ThresholdDscrCount,
+ // Set packet processing mode,
+ // e.g. interrupts per packet i.s.o. descriptor
+ true,
+ (uint8_t)Timeout);
+ }
+ else
+ {
+ EIP202_RDR_THRESH_WR(Device,
+ (uint32_t)ThresholdDscrCount *
+ TrueIOArea_p->DescOffsWordCount,
+ // Set packet processing mode,
+ // e.g. interrupts per packet i.s.o. descriptor
+ false,
+ (uint8_t)Timeout);
+ }
+
+#ifdef EIP202_CLUSTERED_WRITES_DISABLE
+ // Prevent clustered write operations, break them with a read operation
+ // Note: Reading the EIP202_RDR_RING_BASE_ADDR_LO register
+ // has no side effects!
+ EIP202_RDR_Read32(Device, EIP202_RDR_RING_BASE_ADDR_LO);
+#endif
+
+ // Remain in the current state
+ rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+ (EIP202_RDR_State_t)TrueIOArea_p->State);
+ if(rv != EIP202_RING_NO_ERROR)
+ return EIP202_RING_ILLEGAL_IN_STATE;
+
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Processed_FillLevel_High_INT_ClearAndDisable
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Processed_FillLevel_High_INT_ClearAndDisable(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ const bool fOvflIntOnly)
+{
+ Device_Handle_t Device;
+ EIP202_Ring_Error_t rv;
+ volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+
+ Device = TrueIOArea_p->Device;
+
+ if(fOvflIntOnly)
+ {
+ // Clear Descriptor and Buffer overflow interrupts
+ EIP202_RDR_STAT_CLEAR_DSCR_BUF_OFLO_IRQ_WR(Device);
+ }
+ else
+ {
+ // Disable Processed Descriptor threshold interrupt,
+ // Disable Timeout interrupt and stop timeout counter for
+ // reducing power consumption
+ EIP202_RDR_THRESH_WR(
+ Device,
+ TrueIOArea_p->RingSizeWordCount,
+ 0, // Set descriptor processing mode
+ 0); // Disable timeout
+
+#ifdef EIP202_CLUSTERED_WRITES_DISABLE
+ // Prevent clustered write operations, break them with a read operation
+ // Note: Reading the EIP202_RDR_RING_BASE_ADDR_LO register
+ // has no side effects!
+ EIP202_RDR_Read32(Device, EIP202_RDR_RING_BASE_ADDR_LO);
+#endif
+
+ // Clear all RDR interrupts
+ EIP202_RDR_STAT_CLEAR_ALL_IRQ_WR(Device);
+
+#ifdef EIP202_CLUSTERED_WRITES_DISABLE
+ // Prevent clustered write operations, break them with a read operation
+ // Note: Reading the EIP202_RDR_RING_BASE_ADDR_LO register
+ // has no side effects!
+ EIP202_RDR_Read32(Device, EIP202_RDR_RING_BASE_ADDR_LO);
+#endif
+ }
+
+ // Remain in the current state
+ rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+ (EIP202_RDR_State_t)TrueIOArea_p->State);
+ if(rv != EIP202_RING_NO_ERROR)
+ return EIP202_RING_ILLEGAL_IN_STATE;
+
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/* end of file eip202_rdr_event.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_fsm.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_fsm.c
new file mode 100644
index 0000000..a3fa0e5
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_fsm.c
@@ -0,0 +1,174 @@
+/* eip202_rdr_fsm.c
+ *
+ * EIP-202 Ring Control Driver Library API
+ * State Machine Internal Interface implementation for RDR
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_rdr_fsm.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // IDENTIFIER_NOT_USED
+
+// EIP-202 Ring Control Driver Library Types API
+#include "eip202_ring_types.h" // EIP202_Ring_* types
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_State_Set
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_State_Set(
+ volatile EIP202_RDR_State_t * const CurrentState,
+ const EIP202_RDR_State_t NewState)
+{
+#ifdef EIP202_RING_DEBUG_FSM
+ switch(*CurrentState)
+ {
+ case EIP202_RDR_STATE_UNKNOWN:
+ switch(NewState)
+ {
+ case EIP202_RDR_STATE_UNINITIALIZED:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP202_RING_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP202_RDR_STATE_UNINITIALIZED:
+ switch(NewState)
+ {
+ case EIP202_RDR_STATE_INITIALIZED:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP202_RING_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP202_RDR_STATE_INITIALIZED:
+ switch(NewState)
+ {
+ case EIP202_RDR_STATE_UNINITIALIZED:
+ *CurrentState = NewState;
+ break;
+ case EIP202_RDR_STATE_FREE:
+ *CurrentState = NewState;
+ break;
+ case EIP202_RDR_STATE_FULL:
+ *CurrentState = NewState;
+ break;
+ case EIP202_RDR_STATE_INITIALIZED:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP202_RING_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP202_RDR_STATE_FREE:
+ switch(NewState)
+ {
+ case EIP202_RDR_STATE_UNINITIALIZED:
+ *CurrentState = NewState;
+ break;
+ case EIP202_RDR_STATE_INITIALIZED:
+ *CurrentState = NewState;
+ break;
+ case EIP202_RDR_STATE_FULL:
+ *CurrentState = NewState;
+ break;
+ case EIP202_RDR_STATE_FATAL_ERROR:
+ *CurrentState = NewState;
+ break;
+ case EIP202_RDR_STATE_FREE:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP202_RING_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP202_RDR_STATE_FULL:
+ switch(NewState)
+ {
+ case EIP202_RDR_STATE_UNINITIALIZED:
+ *CurrentState = NewState;
+ break;
+ case EIP202_RDR_STATE_INITIALIZED:
+ *CurrentState = NewState;
+ break;
+ case EIP202_RDR_STATE_FREE:
+ *CurrentState = NewState;
+ break;
+ case EIP202_RDR_STATE_FATAL_ERROR:
+ *CurrentState = NewState;
+ break;
+ case EIP202_RDR_STATE_FULL:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP202_RING_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP202_RDR_STATE_FATAL_ERROR:
+ switch(NewState)
+ {
+ case EIP202_RDR_STATE_UNINITIALIZED:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP202_RING_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ default:
+ return EIP202_RING_ILLEGAL_IN_STATE;
+ }
+#else
+ IDENTIFIER_NOT_USED(CurrentState);
+ IDENTIFIER_NOT_USED(NewState);
+#endif // EIP202_RING_DEBUG_FSM
+
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/* end of file eip202_rdr_fsm.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_init.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_init.c
new file mode 100644
index 0000000..6fd658c
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip202_rdr_init.c
@@ -0,0 +1,372 @@
+/* eip202_rdr_init.c
+ *
+ * EIP-202 Ring Control Driver Library
+ * RDR Init/Reset API implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip202_rdr.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip202_ring.h"
+
+// EIP-202 Ring Control Driver Library Types API
+#include "eip202_ring_types.h" // EIP202_Ring_* types
+
+// EIP-202 Ring Control Driver Library Internal interfaces
+#include "eip202_ring_internal.h"
+#include "eip202_rdr_level0.h" // EIP-202 Level 0 macros
+#include "eip202_rdr_fsm.h" // RDR State machine
+#include "eip202_rdr_dscr.h" // RingHelper callbacks
+#include "eip202_rd_format.h" // EIP-202 Result Descriptor
+
+// RingHelper API
+#include "ringhelper.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // IDENTIFIER_NOT_USED, bool, uint32_t
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h" // types of the DMA resource API
+#include "dmares_rw.h" // read/write of the DMA resource API.
+
+// Driver Framework C Run-Time Library API
+#include "clib.h"
+
+// Standard IOToken API
+#include "iotoken.h" // IOToken_InWordCount_Get()
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_Detect
+ *
+ * Checks the presence of EIP-202 HIA hardware. Returns true when found.
+ */
+static bool
+EIP202Lib_RDR_Detect(
+ const Device_Handle_t Device)
+{
+ uint32_t Value;
+
+ // read-write test one of the registers
+
+ // Set MASK_31_BITS bits of the EIP202_RDR_RING_BASE_ADDR_LO register
+ EIP202_RDR_Write32(Device,
+ EIP202_RDR_RING_BASE_ADDR_LO,
+ MASK_31_BITS );
+
+ Value = EIP202_RDR_Read32(Device, EIP202_RDR_RING_BASE_ADDR_LO);
+ if ((Value & MASK_31_BITS) != MASK_31_BITS)
+ return false;
+
+ // Clear MASK_31_BITS bits of the EIP202_RDR_RING_BASE_ADDR_LO register
+ EIP202_RDR_Write32(Device, EIP202_RDR_RING_BASE_ADDR_LO, 0);
+ Value = EIP202_RDR_Read32(Device, EIP202_RDR_RING_BASE_ADDR_LO);
+ if ((Value & MASK_31_BITS) != 0)
+ return false;
+
+ return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_RDR_ClearAllDescriptors
+ *
+ * Clear all descriptors
+ */
+static inline void
+EIP202Lib_RDR_ClearAllDescriptors(
+ DMAResource_Handle_t Handle,
+ const uint32_t DescriptorSpacingWordCount,
+ const uint32_t DescriptorSizeWordCount,
+ const uint32_t NumberOfDescriptors)
+{
+ unsigned int i, j;
+
+ for(i = 0; i < NumberOfDescriptors; i++)
+ for(j = 0; j < DescriptorSizeWordCount; j++)
+ DMAResource_Write32(Handle, i * DescriptorSpacingWordCount + j, 0);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Init
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Init(
+ EIP202_Ring_IOArea_t * IOArea_p,
+ const Device_Handle_t Device,
+ const EIP202_RDR_Settings_t * const RDRSettings_p)
+{
+ EIP202_Ring_Error_t rv;
+ volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+
+ // Initialize the IO Area
+ TrueIOArea_p->Device = Device;
+ TrueIOArea_p->State = (unsigned int)EIP202_RDR_STATE_UNINITIALIZED;
+
+ // Check if the CPU integer size is enough to store 32-bit value
+ if(sizeof(unsigned int) < sizeof(uint32_t))
+ return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+
+ // Detect presence of EIP-202 CDR hardware
+ if(!EIP202Lib_RDR_Detect(Device))
+ return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+
+ // Extension of 32-bit pointers to 64-bit addresses not supported.
+ if(RDRSettings_p->Params.DMA_AddressMode == EIP202_RING_64BIT_DMA_EXT_ADDR)
+ return EIP202_RING_UNSUPPORTED_FEATURE_ERROR;
+
+ if(RDRSettings_p->Params.DscrOffsWordCount == 0 ||
+ RDRSettings_p->Params.DscrOffsWordCount <
+ RDRSettings_p->Params.DscrSizeWordCount)
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ // Ring size cannot be smaller than one descriptor size or
+ // larger than 4194303 (16MB / 4 - 1), in 32-bit words
+ if(RDRSettings_p->Params.RingSizeWordCount <
+ RDRSettings_p->Params.DscrOffsWordCount ||
+ RDRSettings_p->Params.RingSizeWordCount > 4194303)
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ if(RDRSettings_p->Params.DscrSizeWordCount >
+ RDRSettings_p->Params.TokenOffsetWordCount + IOToken_OutWordCount_Get())
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ if(RDRSettings_p->Params.DscrFetchSizeWordCount %
+ RDRSettings_p->Params.DscrOffsWordCount)
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ if( RDRSettings_p->Params.IntThresholdDscrCount *
+ RDRSettings_p->Params.DscrOffsWordCount >
+ RDRSettings_p->Params.RingSizeWordCount )
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ // Configure the Ring Helper
+ TrueIOArea_p->RingHelperCallbacks.WriteFunc_p = &EIP202_RDR_WriteCB;
+ TrueIOArea_p->RingHelperCallbacks.ReadFunc_p = &EIP202_RDR_ReadCB;
+ TrueIOArea_p->RingHelperCallbacks.StatusFunc_p = &EIP202_RDR_StatusCB;
+ TrueIOArea_p->RingHelperCallbacks.CallbackParam1_p = IOArea_p;
+ TrueIOArea_p->RingHelperCallbacks.CallbackParam2 = 0;
+ TrueIOArea_p->RingHandle = RDRSettings_p->Params.RingDMA_Handle;
+ TrueIOArea_p->DescOffsWordCount = RDRSettings_p->Params.DscrOffsWordCount;
+ TrueIOArea_p->RingSizeWordCount = RDRSettings_p->Params.RingSizeWordCount;
+ TrueIOArea_p->TokenOffsetWordCount = RDRSettings_p->Params.TokenOffsetWordCount;
+ TrueIOArea_p->PacketFound = false;
+
+ // Initialize one RingHelper instance for one RDR instance
+ if( RingHelper_Init(
+ (volatile RingHelper_t*)&TrueIOArea_p->RingHelper,
+ (volatile RingHelper_CallbackInterface_t*)&TrueIOArea_p->RingHelperCallbacks,
+ false, // One RDR as combined rings
+ (unsigned int)(RDRSettings_p->Params.RingSizeWordCount /
+ RDRSettings_p->Params.DscrOffsWordCount),
+ (unsigned int)(RDRSettings_p->Params.RingSizeWordCount /
+ RDRSettings_p->Params.DscrOffsWordCount)) < 0)
+ return EIP202_RING_ARGUMENT_ERROR;
+
+ // Transit to a new state
+ rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+ EIP202_RDR_STATE_INITIALIZED);
+ if(rv != EIP202_RING_NO_ERROR)
+ return EIP202_RING_ILLEGAL_IN_STATE;
+
+ // Prepare the RDR DMA buffer
+ // Initialize all descriptors with zero for RDR
+ EIP202Lib_RDR_ClearAllDescriptors(
+ TrueIOArea_p->RingHandle,
+ RDRSettings_p->Params.DscrOffsWordCount,
+ RDRSettings_p->Params.DscrSizeWordCount,
+ RDRSettings_p->Params.RingSizeWordCount /
+ RDRSettings_p->Params.DscrOffsWordCount);
+
+ // Call PreDMA to make sure engine sees it
+ DMAResource_PreDMA(TrueIOArea_p->RingHandle,
+ 0,
+ (unsigned int)(TrueIOArea_p->RingSizeWordCount*4));
+
+ EIP202_RDR_RING_BASE_ADDR_LO_WR(
+ Device,
+ RDRSettings_p->Params.RingDMA_Address.Addr);
+
+ EIP202_RDR_RING_BASE_ADDR_HI_WR(
+ Device,
+ RDRSettings_p->Params.RingDMA_Address.UpperAddr);
+
+ EIP202_RDR_RING_SIZE_WR(
+ Device,
+ RDRSettings_p->Params.RingSizeWordCount);
+
+ EIP202_RDR_DESC_SIZE_WR(
+ Device,
+ RDRSettings_p->Params.DscrSizeWordCount,
+ RDRSettings_p->Params.DscrOffsWordCount,
+ RDRSettings_p->Params.DMA_AddressMode == EIP202_RING_64BIT_DMA_DSCR_PTR);
+
+ EIP202_RDR_CFG_WR(Device,
+ RDRSettings_p->Params.DscrFetchSizeWordCount,
+ RDRSettings_p->Params.DscrThresholdWordCount,
+#ifdef EIP202_RDR_OWNERSHIP_WORD_ENABLE
+ true); // Ownership write mode
+#else
+ RDRSettings_p->fContinuousScatter); // Normal mode, no ownership words are used.
+/* Always enable ownership words for continuous scatter */
+#endif
+
+ // Disable Processed Descriptor threshold interrupt,
+ // Disable Timeout interrupt and stop timeout counter for
+ // reducing power consumption
+ EIP202_RDR_THRESH_WR(
+ Device,
+ TrueIOArea_p->RingSizeWordCount,
+ 0, // Set descriptor processing mode
+ 0); // Disable timeout
+
+ EIP202_RDR_DMA_CFG_WR(
+ Device,
+ (uint8_t)RDRSettings_p->Params.ByteSwap_Descriptor_Mask,
+ (uint8_t)RDRSettings_p->Params.ByteSwap_Packet_Mask,
+
+ // Bufferability control for DMA writes of
+ EIP202_RING_RD_RES_BUF, // result token
+ EIP202_RING_RD_CTRL_BUF, // descriptor control words
+ EIP202_RING_RD_OWN_BUF, // ownership words
+
+ EIP202_RING_RD_WR_CACHE_CTRL, // Write cache type control
+ EIP202_RING_RD_RD_CACHE_CTRL, // Read cache type control
+ EIP202_RING_RD_PROT_VALUE,
+ EIP202_RING_DATA_PROT_VALUE,
+ RDRSettings_p->fContinuousScatter|EIP202_RDR_PAD_TO_OFFSET); // Result descriptor padding
+/* Note: for continuous scatter: always set RDR_PAD_TO_OFFSET. */
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Reset
+ *
+ */
+EIP202_Ring_Error_t
+EIP202_RDR_Reset(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ const Device_Handle_t Device)
+{
+ EIP202_Ring_Error_t rv;
+ volatile EIP202_RDR_True_IOArea_t * const TrueIOArea_p = RDRIOAREA(IOArea_p);
+
+ EIP202_RING_CHECK_POINTER(IOArea_p);
+
+ // Initialize the IO Area
+ memset((void*)IOArea_p, 0, sizeof(*TrueIOArea_p));
+ TrueIOArea_p->Device = Device;
+ TrueIOArea_p->State = (unsigned int)EIP202_RDR_STATE_UNKNOWN;
+
+ // Transit to a new state
+ rv = EIP202_RDR_State_Set((volatile EIP202_RDR_State_t*)&TrueIOArea_p->State,
+ EIP202_RDR_STATE_UNINITIALIZED);
+ if(rv != EIP202_RING_NO_ERROR)
+ return EIP202_RING_ILLEGAL_IN_STATE;
+
+ // Clear RDR count
+ EIP202_RDR_PREP_COUNT_WR(Device, 0, true);
+ EIP202_RDR_PROC_COUNT_WR(Device, 0, 0, true);
+
+ // Re-init RDR
+ EIP202_RDR_PREP_PNTR_DEFAULT_WR(Device);
+ EIP202_RDR_PROC_PNTR_DEFAULT_WR(Device);
+
+ // Restore default register values
+ EIP202_RDR_RING_BASE_ADDR_LO_DEFAULT_WR(Device);
+ EIP202_RDR_RING_BASE_ADDR_HI_DEFAULT_WR(Device);
+ EIP202_RDR_RING_SIZE_DEFAULT_WR(Device);
+ EIP202_RDR_DESC_SIZE_DEFAULT_WR(Device);
+ EIP202_RDR_CFG_DEFAULT_WR(Device);
+ EIP202_RDR_DMA_CFG_DEFAULT_WR(Device);
+ EIP202_RDR_THRESH_DEFAULT_WR(Device);
+
+ // Clear and disable all RDR interrupts
+ EIP202_RDR_STAT_CLEAR_ALL_IRQ_WR(Device);
+
+ return EIP202_RING_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202_RDR_Dump
+ *
+ */
+void
+EIP202_RDR_Dump(
+ EIP202_Ring_IOArea_t * const IOArea_p,
+ EIP202_RingAdmin_t * const RingAdmin_p)
+{
+ EIP202_RDR_True_IOArea_t * const TrueIOArea_p =
+ (EIP202_RDR_True_IOArea_t * const)IOArea_p;
+
+ if(!TrueIOArea_p)
+ return;
+
+ if(!RingAdmin_p)
+ return;
+
+ RingAdmin_p->IN_Size = TrueIOArea_p->RingHelper.IN_Size;
+ RingAdmin_p->IN_Tail = TrueIOArea_p->RingHelper.IN_Tail;
+ RingAdmin_p->OUT_Size = TrueIOArea_p->RingHelper.OUT_Size;
+ RingAdmin_p->OUT_Head = TrueIOArea_p->RingHelper.OUT_Head;
+
+ RingAdmin_p->fSeparate = TrueIOArea_p->RingHelper.fSeparate;
+
+ RingAdmin_p->DescOffsWordCount = TrueIOArea_p->DescOffsWordCount;
+ RingAdmin_p->RingSizeWordCount = TrueIOArea_p->RingSizeWordCount;
+}
+
+
+/* end of file eip202_rdr_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_dtl.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_dtl.c
new file mode 100644
index 0000000..6cbdba3
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_dtl.c
@@ -0,0 +1,1837 @@
+/* eip207_flow_dtl.c
+ *
+ * Partial EIP-207 Flow Control Generic API implementation and
+ * full EIP-207 Flow Control DTL API implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207 Driver Library Flow Control Generic API
+#include "eip207_flow_dtl.h"
+
+// EIP-207 Driver Library Flow Control Generic API
+#include "eip207_flow_generic.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_flow.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // uint32_t
+
+// Driver Framework C Run-time Library API
+#include "clib.h" // ZEROINIT, memset, memcpy
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"
+#include "dmares_rw.h"
+
+// EIP-207 Flow Control Driver Library Internal interfaces
+#include "eip207_flow_level0.h" // EIP-207 Level 0 macros
+#include "eip207_flow_hte_dscr_dtl.h" // HTE descriptor DTL
+#include "eip207_flow_internal.h"
+
+#ifndef EIP207_FLUE_RC_HP
+// EIP-207 (Global Control) Record Cache (RC) interface
+#include "eip207_rc.h"
+
+// EIP-207s (Global Control) Flow Look-Up Engine Cache (FLUEC) interface
+#include "eip207_fluec.h"
+#endif // !EIP207_FLUE_RC_HP
+
+// EIP-207 Firmware API
+#include "firmware_eip207_api_flow_cs.h" // Classification API: Flow Control
+#include "firmware_eip207_api_cs.h" // Classification API: General
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define EIP207_FLOW_MAX_RECORDS_PER_BUCKET 3
+
+
+// Flow record input data required for the flow record creation
+typedef struct
+{
+ // Bitwise of zero or more EIP207_FLOW_FLAG_* flags, see above
+ uint32_t Flags;
+
+ // Physical (DMA/bus) address of the transform record
+ EIP207_Flow_Address_t Xform_DMA_Addr;
+
+ // Software flow record reference
+ uint32_t SW_FR_Reference;
+
+ // Transform record type, true - large, false - small
+ bool fLarge;
+} EIP207_Flow_FR_Data_t;
+
+// Transform record input data required for the transform record creation
+typedef struct
+{
+ // Transform record type, true - large, false - small
+ bool fLarge;
+
+} EIP207_Flow_TR_Data_t;
+
+// Transform record input data required for the Transform record creation
+typedef struct
+{
+ // Record hash ID
+ const EIP207_Flow_ID_t * HashID_p;
+
+ // Flow record input data, fill with NULL if not used
+ const EIP207_Flow_FR_Data_t * FR_Data_p;
+
+ // Transform record input data, fill with NULL if not used
+ const EIP207_Flow_TR_Data_t * TR_Data_p;
+
+ // Note: FR_Data_p and TR_Data_p cannot be both NULL!
+
+} EIP207_Flow_Record_InputData_t;
+
+// Full record descriptor
+typedef struct
+{
+ EIP207_Flow_Dscr_t RecDscr;
+
+ EIP207_Flow_HTE_Dscr_RecData_t RecData;
+
+ void * Reserved_p;
+} EIP207_Flow_Rec_Dscr_t;
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_Entry_Lookup
+ */
+static void
+EIP207Lib_Flow_Entry_Lookup(
+ const uint32_t HashID_Word0,
+ const uint32_t TableSize,
+ unsigned int * const HT_Entry_ByteOffset,
+ unsigned int * const DT_Entry_Index)
+{
+ uint32_t HashID_W0, Mask;
+
+ // From the EIP-197 Programmer Manual:
+ // The hash engine completes the hash ID calculation and
+ // adds bits [(table_size+10):6] (with table_size coming from
+ // the FLUE_SIZE(_VM)_f register) of the hash ID, multiplied by 64,
+ // to the table base address given in the FLUE_HASHBASE(_VM)_f_* registers.
+
+ // Calculate the entry byte offset in the HT for this record
+ HashID_W0 = (HashID_Word0 & (~MASK_6_BITS));
+
+ Mask = (1 << (TableSize + 10 + 1)) - 1;
+
+ // Calculate the HT entry byte offset
+ *HT_Entry_ByteOffset = (unsigned int)(HashID_W0 & Mask);
+
+ // Translate the HT entry byte offset to the index in the HT
+ // HT entry size is one hash bucket (16 words = 64 bytes)
+ *DT_Entry_Index = (*HT_Entry_ByteOffset) >> 6; // divide by 64
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_TableSize_To_EntryCount
+ *
+ * Convert EIP207_Flow_HashTable_Entry_Count_t to a number
+ */
+static inline unsigned int
+EIP207Lib_Flow_TableSize_To_EntryCount(
+ const unsigned int TableSize)
+{
+ return (1 << (TableSize + 5));
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_HTE_Dscr_ByteCount_Get
+ */
+static inline unsigned int
+EIP207Lib_Flow_HTE_Dscr_ByteCount_Get(void)
+{
+ return sizeof(EIP207_Flow_HTE_Dscr_t);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_HB_Record_Add
+ *
+ * Updates Hash ID and record offset in the hash bucket,
+ * first Hash ID then record byte offset
+ */
+static inline void
+EIP207Lib_Flow_HB_Record_Add(
+ const DMAResource_Handle_t HT_DMA_Handle,
+ const unsigned int HB_ByteOffset,
+ const unsigned int slot,
+ const uint32_t Rec_ByteOffset,
+ const uint32_t RecType,
+ const EIP207_Flow_ID_t * const HashID_p)
+{
+ unsigned int i;
+ unsigned int HB_WordOffset = HB_ByteOffset >> 2;
+
+ // Write record Hash ID words
+ for (i = 0; i < EIP207_FLOW_HASH_ID_WORD_COUNT; i++)
+ DMAResource_Write32(HT_DMA_Handle,
+ HB_WordOffset +
+ EIP207_FLOW_HB_HASH_ID_1_WORD_OFFSET + i +
+ EIP207_FLOW_HASH_ID_WORD_COUNT * (slot - 1),
+ HashID_p->Word32[i]);
+
+ // Write record offset
+ DMAResource_Write32(HT_DMA_Handle,
+ HB_WordOffset +
+ EIP207_FLOW_HB_REC_1_WORD_OFFSET + (slot - 1),
+ Rec_ByteOffset | RecType);
+
+ // Perform pre-DMA for this hash bucket
+ DMAResource_PreDMA(HT_DMA_Handle,
+ HB_ByteOffset,
+ EIP207_FLOW_HT_ENTRY_WORD_COUNT *
+ sizeof(uint32_t));
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_HB_Record_Remove
+ *
+ * Updates Hash ID and record offset in the hash bucket,
+ * first record byte offset then Hash ID
+ */
+static inline void
+EIP207Lib_Flow_HB_Record_Remove(
+ const DMAResource_Handle_t HT_DMA_Handle,
+ const unsigned int HB_ByteOffset,
+ const unsigned int slot,
+ EIP207_Flow_ID_t * HashID_p)
+{
+ unsigned int i;
+ unsigned int HB_WordOffset = HB_ByteOffset >> 2;
+ EIP207_Flow_ID_t HashID;
+
+ // Write record offset
+ DMAResource_Write32(HT_DMA_Handle,
+ HB_WordOffset +
+ EIP207_FLOW_HB_REC_1_WORD_OFFSET + (slot - 1),
+ EIP207_FLOW_RECORD_DUMMY_ADDRESS);
+
+ // Read old record Hash ID words
+ for (i = 0; i < EIP207_FLOW_HASH_ID_WORD_COUNT; i++)
+ HashID.Word32[i] = DMAResource_Read32(
+ HT_DMA_Handle,
+ HB_WordOffset +
+ EIP207_FLOW_HB_HASH_ID_1_WORD_OFFSET + i +
+ EIP207_FLOW_HASH_ID_WORD_COUNT * (slot - 1));
+
+ // Write new record Hash ID words
+ for (i = 0; i < EIP207_FLOW_HASH_ID_WORD_COUNT; i++)
+ {
+ DMAResource_Write32(HT_DMA_Handle,
+ HB_WordOffset +
+ EIP207_FLOW_HB_HASH_ID_1_WORD_OFFSET + i +
+ EIP207_FLOW_HASH_ID_WORD_COUNT * (slot - 1),
+ HashID_p->Word32[i]);
+
+ // Store old record Hash ID words
+ HashID_p->Word32[i] = HashID.Word32[i];
+ }
+
+ // Perform pre-DMA for this hash bucket
+ DMAResource_PreDMA(HT_DMA_Handle,
+ HB_ByteOffset,
+ EIP207_FLOW_HT_ENTRY_WORD_COUNT *
+ sizeof(uint32_t));
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_HB_BuckOffs_Update
+ *
+ * Update bucket offset in the hash bucket (identified by HB_ByteOffset)
+ * by writing the Update_Value in there
+ */
+static inline void
+EIP207Lib_Flow_HB_BuckOffs_Update(
+ const DMAResource_Handle_t HT_DMA_Handle,
+ const unsigned int HB_ByteOffset,
+ const uint32_t Update_Value)
+{
+ unsigned int HB_WordOffset = HB_ByteOffset >> 2;
+
+ // Write record offset
+ DMAResource_Write32(HT_DMA_Handle,
+ HB_WordOffset +
+ EIP207_FLOW_HB_OVFL_BUCKET_WORD_OFFSET,
+ Update_Value);
+
+ // Perform pre-DMA for this hash bucket
+ DMAResource_PreDMA(HT_DMA_Handle,
+ HB_ByteOffset,
+ EIP207_FLOW_HT_ENTRY_WORD_COUNT *
+ sizeof(uint32_t));
+}
+
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_HB_HashID_Match
+ *
+ * Checks if the hash bucket already contains this Hash ID
+ */
+static bool
+EIP207Lib_Flow_HB_HashID_Match(
+ const DMAResource_Handle_t HT_DMA_Handle,
+ const unsigned int HB_ByteOffset,
+ const uint32_t RecType,
+ const EIP207_Flow_ID_t * const HashID_p)
+{
+ uint32_t Word32;
+ bool fMatch;
+ unsigned int i, j;
+ unsigned int HB_WordOffset = HB_ByteOffset >> 2;
+
+ // Read Hash ID's from the bucket
+ // (this DMA resource is read-only for the FLUE device)
+ for (i = 0; i < EIP207_FLOW_HTE_BKT_NOF_REC_MAX; i++)
+ {
+ for (j = 0; j < EIP207_FLOW_HASH_ID_WORD_COUNT; j++)
+ {
+ fMatch = true;
+
+ Word32 = DMAResource_Read32(
+ HT_DMA_Handle,
+ HB_WordOffset +
+ EIP207_FLOW_HB_HASH_ID_1_WORD_OFFSET +
+ i * EIP207_FLOW_HASH_ID_WORD_COUNT + j);
+
+ if (Word32 != HashID_p->Word32[j])
+ {
+ fMatch = false;
+ break; // No match, skip this hash ID
+ }
+ } // for
+
+ if (fMatch)
+ break; // Matching Hash ID found, stop searching
+ } // for
+
+ if (fMatch)
+ {
+ uint32_t Match_RecType;
+
+ // Check the record type in the record offset for Hash ID with index i
+ // to confirm the match
+ Word32 = DMAResource_Read32(
+ HT_DMA_Handle,
+ HB_WordOffset +
+ EIP207_FLOW_HB_REC_1_WORD_OFFSET + i);
+
+ // Note: small transform record and large transform record
+ // fall under the same record type for this check!
+ Match_RecType = Word32 & RecType;
+
+ if ((Match_RecType == EIP207_FLOW_RECORD_FR_ADDRESS &&
+ (RecType == EIP207_FLOW_RECORD_TR_ADDRESS ||
+ RecType == EIP207_FLOW_RECORD_TR_LARGE_ADDRESS)) ||
+
+ (RecType == EIP207_FLOW_RECORD_FR_ADDRESS &&
+ (Match_RecType == EIP207_FLOW_RECORD_TR_ADDRESS ||
+ Match_RecType == EIP207_FLOW_RECORD_TR_LARGE_ADDRESS)))
+ {
+ // Match not confirmed, a different record type is used
+ fMatch = false;
+ }
+ }
+
+ return fMatch;
+}
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_HB_Slot_Get
+ *
+ * Determine the free offset slot number (1,2 or 3) and claim it
+ */
+static inline EIP207_Flow_Error_t
+EIP207Lib_Flow_HB_Slot_Get(
+ uint32_t * const RecOffsMask_p,
+ unsigned int * FreeSlot_p)
+{
+ if ((*RecOffsMask_p & EIP207_FLOW_HTE_REC_OFFSET_1) == 0)
+ {
+ *FreeSlot_p = 1;
+ *RecOffsMask_p |= EIP207_FLOW_HTE_REC_OFFSET_1;
+ }
+ else if((*RecOffsMask_p & EIP207_FLOW_HTE_REC_OFFSET_2) == 0)
+ {
+ *FreeSlot_p = 2;
+ *RecOffsMask_p |= EIP207_FLOW_HTE_REC_OFFSET_2;
+ }
+ else if((*RecOffsMask_p & EIP207_FLOW_HTE_REC_OFFSET_3) == 0)
+ {
+ *FreeSlot_p = 3;
+ *RecOffsMask_p |= EIP207_FLOW_HTE_REC_OFFSET_3;
+ }
+ else
+ // Consistency checks for the found HTE descriptor
+ return EIP207_FLOW_INTERNAL_ERROR;
+
+ return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_HB_Slot_Put
+ *
+ * Determine the used offset slot number (1,2 or 3) and release it
+ */
+static inline EIP207_Flow_Error_t
+EIP207Lib_Flow_HB_Slot_Put(
+ uint32_t * const RecOffsMask_p,
+ const unsigned int Slot)
+{
+ switch (Slot)
+ {
+ case 1:
+ *RecOffsMask_p &= ~EIP207_FLOW_HTE_REC_OFFSET_1;
+ break;
+
+ case 2:
+ *RecOffsMask_p &= ~EIP207_FLOW_HTE_REC_OFFSET_2;
+ break;
+
+ case 3:
+ *RecOffsMask_p &= ~EIP207_FLOW_HTE_REC_OFFSET_3;
+ break;
+
+ default:
+ // Consistency checks for the slot to release
+ return EIP207_FLOW_INTERNAL_ERROR;
+ }
+
+ return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_Dscr_InternalData_Set
+ */
+static inline void
+EIP207Lib_Flow_Dscr_InternalData_Set(
+ EIP207_Flow_Dscr_t * const Dscr_p)
+{
+ EIP207_Flow_Rec_Dscr_t * p = (EIP207_Flow_Rec_Dscr_t*)Dscr_p;
+
+ Dscr_p->InternalData_p = &p->RecData;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_FR_Write
+ */
+static void
+EIP207Lib_Flow_FR_Write(
+ const DMAResource_Handle_t DMA_Handle,
+ const EIP207_Flow_FR_Data_t * const FR_Data_p,
+ const uint32_t Xform_ByteOffset,
+ const uint32_t Xform_Addr,
+ const uint32_t Xform_UpperAddr)
+{
+ unsigned int i;
+ uint32_t Record_Type;
+
+ // Write flow record with 0's
+ for (i = 0; i < FIRMWARE_EIP207_CS_FRC_RECORD_WORD_COUNT; i++)
+ DMAResource_Write32(DMA_Handle, i, 0);
+
+#ifdef EIP207_FLOW_NO_TYPE_BITS_IN_FLOW_RECORD
+ Record_Type = 0;
+#else
+ Record_Type = FR_Data_p->fLarge ?
+ EIP207_FLOW_RECORD_TR_LARGE_ADDRESS :
+ EIP207_FLOW_RECORD_TR_ADDRESS;
+#endif
+
+ // Write Transform Record 32-bit offset
+ DMAResource_Write32(DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_FR_XFORM_OFFS_WORD_OFFSET,
+ Xform_ByteOffset + Record_Type);
+
+ // Write Transform Record low half of 64-bit address
+ DMAResource_Write32(DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_FR_XFORM_ADDR_WORD_OFFSET,
+ Xform_Addr + Record_Type);
+
+ // Write Transform Record high half of 64-bit address
+ DMAResource_Write32(DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_FR_XFORM_ADDR_HI_WORD_OFFSET,
+ Xform_UpperAddr);
+
+ // Not supported yet
+ // Write ARC4 State Record physical address
+ //DMAResource_Write32(FR_Dscr_p->Data.DMA_Handle,
+ // FIRMWARE_EIP207_CS_FLOW_FR_ARC4_ADDR_WORD_OFFSET,
+ // EIP207_FLOW_RECORD_DUMMY_ADDRESS);
+
+ // Write Software Flow Record Reference
+ // NOTE: this is a 32-bit value!
+ DMAResource_Write32(DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_FR_SW_ADDR_WORD_OFFSET,
+ FR_Data_p->SW_FR_Reference);
+
+ // Write the Flags field
+ DMAResource_Write32(DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_FR_FLAGS_WORD_OFFSET,
+ FR_Data_p->Flags);
+
+ // Perform pre-DMA for the entire flow record
+ DMAResource_PreDMA(DMA_Handle, 0, 0);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_DTL_Record_Add
+ */
+static EIP207_Flow_Error_t
+EIP207Lib_Flow_DTL_Record_Add(
+ volatile EIP207_Flow_HT_Params_t * const HT_Params_p,
+ EIP207_Flow_Dscr_t * const Rec_Dscr_p,
+ const EIP207_Flow_Record_InputData_t * const RecData_p)
+{
+ uint32_t Rec_ByteOffset;
+ unsigned int slot = 0;
+ EIP207_Flow_HTE_Dscr_t * HTE_Dscr_Updated_p = NULL;
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+ // Consistency check for the provided record descriptor
+ if (Rec_Dscr_p->DMA_Addr.Addr == EIP207_FLOW_RECORD_DUMMY_ADDRESS)
+ return EIP207_FLOW_INTERNAL_ERROR;
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+ // Add the record to the Hash Table
+ {
+ EIP207_Flow_HTE_Dscr_t * HTE_Dscr_p;
+ unsigned int Entry_Index, HTE_ByteOffset, HT_TableSize;
+ uint32_t Record_Type = EIP207_FLOW_RECORD_DUMMY_ADDRESS;
+ DMAResource_Handle_t HT_DMA_Handle = HT_Params_p->HT_DMA_Handle;
+
+ // Transform record
+ if (RecData_p->TR_Data_p != NULL)
+ Record_Type = RecData_p->TR_Data_p->fLarge ?
+ EIP207_FLOW_RECORD_TR_LARGE_ADDRESS :
+ EIP207_FLOW_RECORD_TR_ADDRESS;
+ // Flow record
+ else if (RecData_p->FR_Data_p != NULL)
+ Record_Type = EIP207_FLOW_RECORD_FR_ADDRESS;
+ else
+ return EIP207_FLOW_INTERNAL_ERROR; // Unknown record, error
+
+ HT_TableSize = HT_Params_p->HT_TableSize;
+
+ HTE_ByteOffset = 0;
+ Entry_Index = 0;
+
+ EIP207Lib_Flow_Entry_Lookup(
+ RecData_p->HashID_p->Word32[0], // Word 0 is used for lookup
+ HT_TableSize,
+ &HTE_ByteOffset,
+ &Entry_Index);
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+ {
+ unsigned int HT_EntryCount =
+ EIP207Lib_Flow_TableSize_To_EntryCount(HT_TableSize);
+
+ if (Entry_Index >= HT_EntryCount)
+ return EIP207_FLOW_INTERNAL_ERROR;
+ }
+#endif
+
+ // Calculate the record byte offset,
+ // HT_Params_p->BaseAddr.Addr is the base
+ // address of the DMA bank where the record
+ // must have been allocated
+ Rec_ByteOffset = Rec_Dscr_p->DMA_Addr.Addr - HT_Params_p->BaseAddr.Addr;
+
+ // Convert the DT entry index to the HTE descriptor pointer
+ {
+ void * p;
+ unsigned char * DT_p = (unsigned char*)HT_Params_p->DT_p;
+
+ // Read the entry value at the calculated offset from the DT
+ p = DT_p + Entry_Index * EIP207Lib_Flow_HTE_Dscr_ByteCount_Get();
+
+ HTE_Dscr_p = (EIP207_Flow_HTE_Dscr_t*)p;
+ }
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+ // Consistency checks for the found HTE descriptor
+ if (HTE_Dscr_p->Bucket_ByteOffset != (uint32_t)HTE_ByteOffset)
+ return EIP207_FLOW_INTERNAL_ERROR;
+
+ // Check that this HTE is not an overflow one
+ if (HTE_Dscr_p->fOverflowBucket)
+ return EIP207_FLOW_INTERNAL_ERROR;
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+ do // Walk the bucket chain, look for bucket where record can be added
+ {
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+ if (HTE_Dscr_p->RecordCount > EIP207_FLOW_MAX_RECORDS_PER_BUCKET)
+ return EIP207_FLOW_INTERNAL_ERROR;
+
+ // Check if the hash bucket does not contain this Hash ID already
+ if (HTE_Dscr_Updated_p == NULL && EIP207Lib_Flow_HB_HashID_Match(
+ HT_DMA_Handle,
+ HTE_Dscr_p->Bucket_ByteOffset,
+ Record_Type,
+ RecData_p->HashID_p))
+ return EIP207_FLOW_INTERNAL_ERROR;
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+ // Check if the found hash bucket can be used to add
+ // the record or a next bucket in the chain must be used
+ if (HTE_Dscr_p->RecordCount < EIP207_FLOW_MAX_RECORDS_PER_BUCKET)
+ {
+ uint32_t TempMask = HTE_Dscr_p->UsedRecOffsMask;
+ uint32_t TempSlot = slot;
+
+ // Use the found bucket to add the record
+
+ // Determine the offset slot (1,2 or 3) where the record offset
+ // and Hash ID can be stored
+ {
+ EIP207_Flow_Error_t Flow_Rc =
+ EIP207Lib_Flow_HB_Slot_Get(
+ &TempMask,
+ &TempSlot);
+
+ if(Flow_Rc != EIP207_FLOW_NO_ERROR)
+ return Flow_Rc;
+ }
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+ // Check if the record offset in the HTE slot is a dummy pointer
+ {
+ // Read record offset
+ // (this DMA resource is read-only for the FLUE device)
+ uint32_t Record_ByteOffset =
+ DMAResource_Read32(
+ HT_DMA_Handle,
+ (HTE_Dscr_p->Bucket_ByteOffset >> 2) +
+ EIP207_FLOW_HB_REC_1_WORD_OFFSET +
+ (TempSlot - 1));
+
+ if ((Record_ByteOffset &
+ EIP207_FLOW_RECORD_ADDRESS_TYPE_BITS) !=
+ EIP207_FLOW_RECORD_DUMMY_ADDRESS)
+ return EIP207_FLOW_INTERNAL_ERROR;
+ }
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+ // Add the record only if it has not been done already
+ if (HTE_Dscr_Updated_p == NULL)
+ {
+ HTE_Dscr_p->UsedRecOffsMask = TempMask;
+ slot = TempSlot;
+
+ // If flow record is added then write it
+ if (RecData_p->FR_Data_p != NULL)
+ EIP207Lib_Flow_FR_Write(
+ Rec_Dscr_p->DMA_Handle,
+ RecData_p->FR_Data_p,
+ RecData_p->FR_Data_p->Xform_DMA_Addr.Addr -
+ HT_Params_p->BaseAddr.Addr,
+ RecData_p->FR_Data_p->Xform_DMA_Addr.Addr,
+ RecData_p->FR_Data_p->Xform_DMA_Addr.UpperAddr);
+
+ // Update the found hash bucket with the
+ // record Hash ID and offset
+
+ // CDS point: after this operation is done the FLUE
+ // hardware can find the transform record!
+ EIP207Lib_Flow_HB_Record_Add(HT_DMA_Handle,
+ HTE_Dscr_p->Bucket_ByteOffset,
+ slot,
+ Rec_ByteOffset,
+ Record_Type,
+ RecData_p->HashID_p);
+
+ // Increase the HTE descriptor record count
+ // for the added record
+ HTE_Dscr_p->RecordCount++;
+ }
+
+ // The found HTE is updated, record is added
+ if (HTE_Dscr_Updated_p == NULL)
+ HTE_Dscr_Updated_p = HTE_Dscr_p;
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+ // Get the next HTE descriptor in the chain
+ HTE_Dscr_p = EIP207_Flow_HTE_Dscr_List_Next_Get(HTE_Dscr_p);
+ continue; // Validate the entire chain
+#else
+ break;
+#endif
+ }
+ else // Found bucket record count is max possible
+ {
+ EIP207_Flow_HTE_Dscr_t * HTE_Dscr_Next_p;
+
+ // Use a next overflow bucket to add the record, find a bucket
+ // in the chain with a free slot for the new record
+
+ // Get the next HTE descriptor in the chain
+ HTE_Dscr_Next_p =
+ EIP207_Flow_HTE_Dscr_List_Next_Get(HTE_Dscr_p);
+
+ // Check if we have one and
+ // that the record has not been added already
+ if (HTE_Dscr_Next_p == NULL && HTE_Dscr_Updated_p == NULL)
+ {
+ // No chain is present for HTE_Dscr_p.
+ // Link a new HTE descriptor from the free list to
+ // the found HTE descriptor
+
+ EIP207_Flow_HTE_Dscr_t * FreeList_Head_p;
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+ // Check if the overflow bucket offset is a dummy pointer
+ {
+ // Read the overflow bucket offset
+ // (this DMA resource is read-only for the FLUE device)
+ uint32_t Bucket_ByteOffset =
+ DMAResource_Read32(
+ HT_DMA_Handle,
+ (HTE_Dscr_p->Bucket_ByteOffset >> 2) +
+ EIP207_FLOW_HB_OVFL_BUCKET_WORD_OFFSET);
+
+ if (Bucket_ByteOffset !=
+ EIP207_FLOW_RECORD_DUMMY_ADDRESS)
+ return EIP207_FLOW_INTERNAL_ERROR;
+ }
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+ FreeList_Head_p =
+ (EIP207_Flow_HTE_Dscr_t*)HT_Params_p->FreeList_Head_p;
+
+ // Check if the record can be added
+ if (FreeList_Head_p == NULL)
+ // Out of descriptors for overflow buckets
+ return EIP207_FLOW_OUT_OF_MEMORY_ERROR;
+
+ slot = 1; // start with slot 1 in the new bucket
+
+ // Get a free HTE descriptor from the free list head
+ HTE_Dscr_Next_p =
+ EIP207_Flow_HTE_Dscr_List_Next_Get(FreeList_Head_p);
+
+ // Check if the last descriptor is present in the free list
+ if (HTE_Dscr_Next_p == NULL)
+ {
+ HTE_Dscr_Next_p = FreeList_Head_p;
+ HT_Params_p->FreeList_Head_p = NULL; // List is empty
+ }
+ else
+ {
+ // Remove the got HTE descriptor from the free list
+ EIP207_Flow_HTE_Dscr_List_Remove(HTE_Dscr_Next_p);
+ }
+
+ // Add the got HTE descriptor to the overflow chain,
+ // we know that HTE_Dscr_p is the last descriptor
+ // in the chain
+ EIP207_Flow_HTE_Dscr_List_Next_Set(HTE_Dscr_p,
+ HTE_Dscr_Next_p);
+ EIP207_Flow_HTE_Dscr_List_Prev_Set(HTE_Dscr_Next_p,
+ HTE_Dscr_p);
+
+ // We add first record to the bucket which HTE descriptor
+ // just fresh-taken from the free list
+ HTE_Dscr_Next_p->UsedRecOffsMask =
+ EIP207_FLOW_HTE_REC_OFFSET_1;
+
+ // If flow record is added then write it
+ if (RecData_p->FR_Data_p != NULL)
+ EIP207Lib_Flow_FR_Write(
+ Rec_Dscr_p->DMA_Handle,
+ RecData_p->FR_Data_p,
+ RecData_p->FR_Data_p->Xform_DMA_Addr.Addr -
+ HT_Params_p->BaseAddr.Addr,
+ RecData_p->FR_Data_p->Xform_DMA_Addr.Addr,
+ RecData_p->FR_Data_p->Xform_DMA_Addr.UpperAddr);
+
+ // Update the overflow bucket with hash ID and record offset
+ EIP207Lib_Flow_HB_Record_Add(HT_DMA_Handle,
+ HTE_Dscr_Next_p->Bucket_ByteOffset,
+ slot,
+ Rec_ByteOffset,
+ Record_Type,
+ RecData_p->HashID_p);
+
+ // CDS point: after the next write32() operation is done
+ // the FLUE HW can find the overflow bucket!
+
+ // Update bucket offset to the found bucket
+ // Note: bucket offset can use any address (pointer) type
+ // but not NULL!
+ EIP207Lib_Flow_HB_BuckOffs_Update(
+ HT_DMA_Handle,
+ HTE_Dscr_p->Bucket_ByteOffset,
+ HTE_Dscr_Next_p->Bucket_ByteOffset |
+ EIP207_FLOW_RECORD_TR_ADDRESS);
+
+ // Increment record count for the added record
+ HTE_Dscr_Next_p->RecordCount++;
+
+ // Bucket is updated, record is added
+ if (HTE_Dscr_Updated_p == NULL)
+ HTE_Dscr_Updated_p = HTE_Dscr_Next_p;
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+ HTE_Dscr_p = HTE_Dscr_Next_p;
+ continue; // Validate the entire chain
+#else
+ break;
+#endif
+ }
+ else // Overflow chain is present for the found HTE_Dscr_p
+ {
+ // HTE_Dscr_p - last found HTE descriptor in the chain
+ // HTE_Dscr_Next_p - next HTE descriptor for HTE_Dscr_p
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+ if (HTE_Dscr_Next_p != NULL)
+ {
+ // Consistency checks: next HTE descriptor must be on
+ // the overflow chain
+ if (!HTE_Dscr_Next_p->fOverflowBucket)
+ return EIP207_FLOW_INTERNAL_ERROR;
+
+ // Check if the overflow bucket offset is
+ // a dummy pointer
+ {
+ // Read the overflow bucket offset
+ // from the previous bucket
+ uint32_t Bucket_ByteOffset =
+ DMAResource_Read32(
+ HT_DMA_Handle,
+ (HTE_Dscr_p->Bucket_ByteOffset >> 2) +
+ EIP207_FLOW_HB_OVFL_BUCKET_WORD_OFFSET);
+
+ if (Bucket_ByteOffset !=
+ (HTE_Dscr_Next_p->Bucket_ByteOffset|
+ EIP207_FLOW_RECORD_TR_ADDRESS))
+ return EIP207_FLOW_INTERNAL_ERROR;
+ }
+ }
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+ HTE_Dscr_p = HTE_Dscr_Next_p;
+ continue;
+
+ } // overflow bucket is found
+
+ } // "bucket full" handling is done
+
+ } while(HTE_Dscr_p != NULL);
+
+ } // Record is added to the Hash Table
+
+ // Fill in record descriptor internal data
+ {
+ EIP207_Flow_HTE_Dscr_RecData_t * Rec_DscrData_p;
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+ // Check if the free slot number was found and
+ // the HTE descriptor to update was found
+ if (slot == 0 || HTE_Dscr_Updated_p == NULL)
+ return EIP207_FLOW_INTERNAL_ERROR;
+#endif
+
+ EIP207Lib_Flow_Dscr_InternalData_Set(Rec_Dscr_p);
+ Rec_DscrData_p =
+ (EIP207_Flow_HTE_Dscr_RecData_t*)Rec_Dscr_p->InternalData_p;
+
+ Rec_DscrData_p->Slot = slot;
+ Rec_DscrData_p->HTE_Dscr_p = HTE_Dscr_Updated_p;
+
+ if (RecData_p->TR_Data_p != NULL)
+ {
+ if (RecData_p->TR_Data_p->fLarge)
+ Rec_DscrData_p->Type = EIP207_FLOW_REC_TRANSFORM_LARGE;
+ else
+ Rec_DscrData_p->Type = EIP207_FLOW_REC_TRANSFORM_SMALL;
+ }
+ else if (RecData_p->FR_Data_p != NULL)
+ Rec_DscrData_p->Type = EIP207_FLOW_REC_FLOW;
+ else
+ return EIP207_FLOW_INTERNAL_ERROR;
+ }
+
+ return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_DTL_Record_Remove
+ */
+static EIP207_Flow_Error_t
+EIP207Lib_Flow_DTL_Record_Remove(
+ const Device_Handle_t Device,
+ const unsigned int HashTableId,
+ volatile EIP207_Flow_HT_Params_t * const HT_Params_p,
+ EIP207_Flow_Dscr_t * const Rec_Dscr_p)
+{
+ EIP207_Flow_ID_t HashID;
+ DMAResource_Handle_t HT_DMA_Handle;
+ EIP207_Flow_HTE_Dscr_t * HTE_Dscr_p;
+ EIP207_Flow_HTE_Dscr_RecData_t * Rec_DscrData_p =
+ (EIP207_Flow_HTE_Dscr_RecData_t*)Rec_Dscr_p->InternalData_p;
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+ // Consistency check for the provided TR descriptor
+ if (Rec_Dscr_p->DMA_Addr.Addr == EIP207_FLOW_RECORD_DUMMY_ADDRESS)
+ return EIP207_FLOW_INTERNAL_ERROR;
+
+ if (Rec_DscrData_p == NULL)
+ return EIP207_FLOW_INTERNAL_ERROR;
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+ // get the HTE descriptor for the record to remove
+ HTE_Dscr_p = Rec_DscrData_p->HTE_Dscr_p;
+
+ HT_DMA_Handle = HT_Params_p->HT_DMA_Handle;
+
+ ZEROINIT(HashID);
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+ // Check record count is sane
+ if (HTE_Dscr_p->RecordCount > EIP207_FLOW_MAX_RECORDS_PER_BUCKET ||
+ HTE_Dscr_p->RecordCount == 0)
+ return EIP207_FLOW_INTERNAL_ERROR;
+
+ // Check the record descriptor slot number
+ if (Rec_DscrData_p->Slot < 1 || Rec_DscrData_p->Slot > 3)
+ return EIP207_FLOW_INTERNAL_ERROR; // Incorrect record slot number
+
+ // Check the record offset calculated from the record descriptor
+ // matches the one on the bucket
+ {
+ uint32_t Rec_ByteOffset2;
+ uint32_t Rec_ByteOffset1 =
+ DMAResource_Read32(HT_DMA_Handle,
+ (HTE_Dscr_p->Bucket_ByteOffset >> 2) +
+ EIP207_FLOW_HB_REC_1_WORD_OFFSET +
+ (Rec_DscrData_p->Slot - 1));
+
+ // Clear the bits that specify the record type
+ Rec_ByteOffset1 &= (~EIP207_FLOW_RECORD_ADDRESS_TYPE_BITS);
+
+ // Calculate the record byte offset,
+ // HT_Params_p->BaseAddr.Addr is the base
+ // address of the DMA bank where the record
+ // must have been allocated
+ Rec_ByteOffset2 = Rec_Dscr_p->DMA_Addr.Addr -
+ HT_Params_p->BaseAddr.Addr;
+
+ if (Rec_ByteOffset1 != Rec_ByteOffset2)
+ return EIP207_FLOW_INTERNAL_ERROR; // Incorrect record offset
+ }
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+ if (HTE_Dscr_p->RecordCount > 1)
+ {
+ // Remove the non-last record from the bucket
+
+ EIP207_Flow_Error_t Flow_Rc;
+
+ // CDS point: record is removed when the next function returns!
+
+ // Update the record offset in the bucket.
+ // Update the Hash ID (optional)
+ EIP207Lib_Flow_HB_Record_Remove(HT_DMA_Handle,
+ HTE_Dscr_p->Bucket_ByteOffset,
+ Rec_DscrData_p->Slot,
+ &HashID);
+
+ // Mark this record slot as free in the HTE descriptor
+ Flow_Rc = EIP207Lib_Flow_HB_Slot_Put(&HTE_Dscr_p->UsedRecOffsMask,
+ Rec_DscrData_p->Slot);
+ if (Flow_Rc != EIP207_FLOW_NO_ERROR)
+ return Flow_Rc;
+
+ // Decrease record count in the HTE descriptor
+ HTE_Dscr_p->RecordCount--;
+ }
+ else // record count = 1, so when removing the record also remove the bucket
+ {
+ // Remove the last record from the removed bucket.
+ // Also remove the bucket from the chain first.
+
+ if (HTE_Dscr_p->fOverflowBucket)
+ {
+ // Remove the last record from the overflow bucket
+
+ EIP207_Flow_HTE_Dscr_t * FreeList_Head_p;
+
+ // Get the neighboring HTE descriptors in the chain
+ EIP207_Flow_HTE_Dscr_t * HTE_Dscr_Prev_p =
+ EIP207_Flow_HTE_Dscr_List_Prev_Get(HTE_Dscr_p);
+ EIP207_Flow_HTE_Dscr_t * HTE_Dscr_Next_p =
+ EIP207_Flow_HTE_Dscr_List_Next_Get(HTE_Dscr_p);
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+ // Check if the previous HTE descriptor is not NULL,
+ // it may not be NULL for the overflow bucket
+ if (HTE_Dscr_Prev_p == NULL)
+ return EIP207_FLOW_INTERNAL_ERROR;
+#endif
+
+ // CDS point: bucket (and record) is removed when
+ // the next function returns and the wait loop is done!
+
+ // Remove HTE_Dscr_p bucket from the chain,
+ // make the HTE_Dscr_Prev_p bucket refer to HTE_Dscr_Next_p bucket
+ // Note: bucket offset can use any address (pointer) type
+ // but not NULL!
+ EIP207Lib_Flow_HB_BuckOffs_Update(
+ HT_DMA_Handle,
+ HTE_Dscr_Prev_p->Bucket_ByteOffset,
+ HTE_Dscr_Next_p ? // the last in chain?
+ (HTE_Dscr_Next_p->Bucket_ByteOffset |
+ EIP207_FLOW_RECORD_TR_ADDRESS) :
+ EIP207_FLOW_RECORD_DUMMY_ADDRESS);
+
+ // Wait loop: this is to wait for the EIP-207 packet classification
+ // engine to complete processing using this bucket
+ // before it can be re-used for another record lookup
+ {
+ unsigned int LoopCount, Value = 1;
+
+ for (LoopCount = 0;
+ LoopCount < EIP207_FLOW_RECORD_REMOVE_WAIT_COUNT;
+ LoopCount++)
+ {
+ // Do some work in the loop
+ if (LoopCount & BIT_0)
+ Value <<= 1;
+ else
+ Value >>= 1;
+ }
+ } // HB remove wait loop is done!
+
+ // Remove record from the HTE_Dscr_p bucket
+ // which is not in the chain anymore
+ EIP207Lib_Flow_HB_Record_Remove(HT_DMA_Handle,
+ HTE_Dscr_p->Bucket_ByteOffset,
+ Rec_DscrData_p->Slot,
+ &HashID);
+
+ // Update the bucket offset in the removed from the chain
+ // HTE_Dscr_p bucket
+ EIP207Lib_Flow_HB_BuckOffs_Update(
+ HT_DMA_Handle,
+ HTE_Dscr_p->Bucket_ByteOffset,
+ EIP207_FLOW_RECORD_DUMMY_ADDRESS);
+
+ // Remove HTE descriptor from the chain
+ EIP207_Flow_HTE_Dscr_List_Remove(HTE_Dscr_p);
+
+ // Add the HTE descriptor to the free list
+ FreeList_Head_p =
+ (EIP207_Flow_HTE_Dscr_t*)HT_Params_p->FreeList_Head_p;
+
+ // Insert the HTE descriptor at the free list head
+ if (FreeList_Head_p != NULL)
+ EIP207_Flow_HTE_Dscr_List_Insert(FreeList_Head_p, HTE_Dscr_p);
+ }
+ else
+ {
+ // Remove the last record from the HT bucket
+ // Note: the chain may still be present for this HTE_Dscr_p bucket
+
+ // CDS point: record is removed when the next function returns!
+
+ // Update the record offset in the bucket.
+ // Update the Hash ID (optional)
+ EIP207Lib_Flow_HB_Record_Remove(HT_DMA_Handle,
+ HTE_Dscr_p->Bucket_ByteOffset,
+ Rec_DscrData_p->Slot,
+ &HashID);
+
+ // Wait loop: this is to wait for the EIP-207 packet classification
+ // engine to complete processing using this bucket
+ // before it can be re-used for another record lookup
+ {
+ unsigned int LoopCount, Value = 1;
+
+ for (LoopCount = 0;
+ LoopCount < EIP207_FLOW_RECORD_REMOVE_WAIT_COUNT;
+ LoopCount++)
+ {
+ // Do some work in the loop
+ if (LoopCount & BIT_0)
+ Value <<= 1;
+ else
+ Value >>= 1;
+ }
+ } // HB remove wait loop is done!
+
+ // Mark this record slot as free in the HTE descriptor
+ EIP207Lib_Flow_HB_Slot_Put(&HTE_Dscr_p->UsedRecOffsMask,
+ Rec_DscrData_p->Slot);
+ }
+
+ // Update the HTE_Dscr_p record offset mask and record count
+ HTE_Dscr_p->UsedRecOffsMask = 0;
+ HTE_Dscr_p->RecordCount = 0;
+ }
+
+#ifndef EIP207_FLUE_RC_HP
+ // Invalidate lookup result in the FLUEC
+ EIP207_FLUEC_Invalidate(Device,
+ (uint8_t)HashTableId,
+ HashID.Word32[0],
+ HashID.Word32[1],
+ HashID.Word32[2],
+ HashID.Word32[3]);
+#else
+ IDENTIFIER_NOT_USED(Device);
+ IDENTIFIER_NOT_USED(HashTableId);
+#endif
+
+ // Invalidate the internal data of the DTL transform record descriptor
+ Rec_DscrData_p->Slot = 0;
+ Rec_DscrData_p->HTE_Dscr_p = NULL;
+ Rec_DscrData_p->Type = EIP207_FLOW_REC_INVALID;
+
+ return EIP207_FLOW_NO_ERROR;
+}
+
+#ifdef EIP207_FLOW_STRICT_ARGS
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_Is32bitAddressable
+ */
+static bool
+EIP207Lib_Flow_Is32bitAddressable(
+ const uint32_t BaseAddrLo,
+ const uint32_t BaseAddrHi,
+ const uint32_t AddrLo,
+ const uint32_t AddrHi)
+{
+ if(BaseAddrHi == AddrHi)
+ {
+ if(BaseAddrLo > AddrLo)
+ return false;
+ }
+ else if (BaseAddrHi < AddrHi && (BaseAddrHi == AddrHi + 1))
+ {
+ if(BaseAddrLo <= AddrLo)
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+#endif // EIP207_FLOW_STRICT_ARGS
+
+
+/*****************************************************************************
+ * Generic API functions implemented in DTL-specific way
+ */
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HTE_Dscr_ByteCount_Get
+ */
+unsigned int
+EIP207_Flow_HTE_Dscr_ByteCount_Get(void)
+{
+ return EIP207Lib_Flow_HTE_Dscr_ByteCount_Get();
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_FR_Dscr_ByteCount_Get
+ */
+unsigned int
+EIP207_Flow_FR_Dscr_ByteCount_Get(void)
+{
+ return sizeof(EIP207_Flow_Rec_Dscr_t);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_TR_Dscr_ByteCount_Get
+ */
+unsigned int
+EIP207_Flow_TR_Dscr_ByteCount_Get(void)
+{
+ return sizeof(EIP207_Flow_Rec_Dscr_t);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_Record_Dummy_Addr_Get
+ */
+unsigned int
+EIP207_Flow_Record_Dummy_Addr_Get(void)
+{
+ return EIP207_FLOW_RECORD_DUMMY_ADDRESS;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HashTable_Install
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_HashTable_Install(
+ EIP207_Flow_IOArea_t * const IOArea_p,
+ const unsigned int HashTableId,
+ const EIP207_Flow_HT_t * HT_p,
+ bool fLookupCached,
+ bool fReset)
+{
+ unsigned int i, EntryCount;
+ Device_Handle_t Device;
+ volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP207_FLOW_CHECK_POINTER(IOArea_p);
+ EIP207_FLOW_CHECK_POINTER(HT_p->HT_DMA_Address_p);
+ EIP207_FLOW_CHECK_POINTER(HT_p->DT_p);
+ EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+ EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+
+ EntryCount = (unsigned int)HT_p->HT_TableSize;
+ EIP207_FLOW_CHECK_INT_ATMOST(EntryCount,
+ EIP207_FLOW_HASH_TABLE_ENTRIES_MAX);
+
+ // Convert EIP207_Flow_HashTable_Entry_Count_t to a number
+ EntryCount = EIP207Lib_Flow_TableSize_To_EntryCount(EntryCount);
+ EIP207_FLOW_CHECK_INT_ATMOST(EntryCount, HT_p->DT_EntryCount);
+
+ // Check Flow Hash Table address alignment
+ if (HT_p->HT_DMA_Address_p->Addr == EIP207_FLOW_RECORD_DUMMY_ADDRESS)
+ return EIP207_FLOW_ARGUMENT_ERROR;
+
+ // Save the flag that indicates whether the FLUEC must be used
+ // Note: FLUEC is enabled and configured via the Global Control interface
+ TrueIOArea_p->HT_Params[HashTableId].fLookupCached = fLookupCached;
+
+ // Save the host address of the Flow Descriptor Table and its size
+ TrueIOArea_p->HT_Params[HashTableId].DT_p = HT_p->DT_p;
+ TrueIOArea_p->HT_Params[HashTableId].HT_TableSize =
+ (unsigned int)HT_p->HT_TableSize;
+
+ // Save the DMA resource handle of the Flow Hash Table
+ TrueIOArea_p->HT_Params[HashTableId].HT_DMA_Handle =
+ HT_p->HT_DMA_Handle;
+
+ Device = TrueIOArea_p->Device;
+
+ // Initialize the HT and the DT free list with initial values
+ if (fReset)
+ {
+ EIP207_Flow_HTE_Dscr_t * HTE_Dscr_p =
+ (EIP207_Flow_HTE_Dscr_t*)HT_p->DT_p;
+
+ // Initialize the Descriptor Table with initial values
+ memset(HT_p->DT_p,
+ 0,
+ HT_p->DT_EntryCount * sizeof(EIP207_Flow_HTE_Dscr_t));
+
+ // Number of HTE descriptors is equal to the number of hash buckets
+ // in the HT plus the number of overflow hash buckets.
+
+ for (i = 0; i < HT_p->DT_EntryCount; i++)
+ {
+ unsigned int j;
+
+ // Initialize with dummy address all the words (j)
+ // in HTE descriptor i
+ for (j = 0; j < EIP207_FLOW_HT_ENTRY_WORD_COUNT; j++)
+ DMAResource_Write32(HT_p->HT_DMA_Handle,
+ i * EIP207_FLOW_HT_ENTRY_WORD_COUNT + j,
+ EIP207_FLOW_RECORD_DUMMY_ADDRESS);
+
+ // Add only the HTE descriptors for the overflow hash buckets
+ // to the free list.
+ if (i >= EntryCount)
+ {
+ // Descriptor Table free list initialization,
+ // all the HTE descriptors are added to the free list
+
+ // First overflow HTE descriptor in DT?
+ if (i == EntryCount)
+ {
+ EIP207_Flow_HTE_Dscr_List_Prev_Set(HTE_Dscr_p, NULL);
+ EIP207_Flow_HTE_Dscr_List_Next_Set(HTE_Dscr_p,
+ HTE_Dscr_p + 1);
+
+ // Set the free list head
+ TrueIOArea_p->HT_Params[HashTableId].FreeList_Head_p =
+ HTE_Dscr_p;
+ }
+
+ // Last overflow HTE descriptor in DT?
+ if (i == HT_p->DT_EntryCount - 1)
+ {
+ // First and last overflow HTE descriptor in DT?
+ if (i != EntryCount)
+ EIP207_Flow_HTE_Dscr_List_Prev_Set(HTE_Dscr_p,
+ HTE_Dscr_p - 1);
+ EIP207_Flow_HTE_Dscr_List_Next_Set(HTE_Dscr_p, NULL);
+ }
+
+ // Non-first and non-last overflow HTE descriptor in DT?
+ if (i != EntryCount && i != (HT_p->DT_EntryCount - 1))
+ {
+ EIP207_Flow_HTE_Dscr_List_Prev_Set(HTE_Dscr_p,
+ HTE_Dscr_p - 1);
+ EIP207_Flow_HTE_Dscr_List_Next_Set(HTE_Dscr_p,
+ HTE_Dscr_p + 1);
+ }
+
+ // Mark overflow hash buckets
+ HTE_Dscr_p->fOverflowBucket = true;
+ }
+ else
+ // Mark non-overflow hash buckets
+ HTE_Dscr_p->fOverflowBucket = false;
+
+ // Set hash bucket byte offset
+ HTE_Dscr_p->Bucket_ByteOffset = i *
+ EIP207_FLOW_HT_ENTRY_WORD_COUNT *
+ sizeof(uint32_t);
+
+ HTE_Dscr_p++; // Next HTE descriptor in the DT
+ } // for
+
+ // Perform pre-DMA for the entire HT including the overflow buckets,
+ // both are expected to be in one linear contiguous DMA-safe buffer
+ DMAResource_PreDMA(HT_p->HT_DMA_Handle, 0, 0);
+ }
+
+ // Install the FHT
+ EIP207_FLUE_HASHBASE_LO_WR(Device,
+ HashTableId,
+ HT_p->HT_DMA_Address_p->Addr);
+ EIP207_FLUE_HASHBASE_HI_WR(Device,
+ HashTableId,
+ HT_p->HT_DMA_Address_p->UpperAddr);
+ EIP207_FLUE_SIZE_UPDATE(Device,
+ HashTableId,
+ (uint8_t)HT_p->HT_TableSize);
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+ if (fReset)
+ {
+ EIP207_Flow_Error_t rv;
+ uint32_t State = TrueIOArea_p->State;
+
+ // Transit to a new state
+ rv = EIP207_Flow_State_Set(
+ (EIP207_Flow_State_t* const)&State,
+ EIP207_FLOW_STATE_ENABLED);
+
+ TrueIOArea_p->State = State;
+
+ if (rv != EIP207_FLOW_NO_ERROR)
+ return EIP207_FLOW_ILLEGAL_IN_STATE;
+ }
+#endif // EIP207_FLOW_DEBUG_FSM
+
+ return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_FR_Add
+
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_FR_Add(
+ EIP207_Flow_IOArea_t * const IOArea_p,
+ const unsigned int HashTableId,
+ EIP207_Flow_FR_Dscr_t * const FR_Dscr_p,
+ const EIP207_Flow_FR_InputData_t * const FlowInData_p)
+{
+ volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+ EIP207_Flow_Record_InputData_t Rec_Data;
+ EIP207_Flow_FR_Data_t FR_Data;
+ EIP207_Flow_Error_t Flow_Rc;
+
+ EIP207_FLOW_CHECK_POINTER(IOArea_p);
+ EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+ EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+ EIP207_FLOW_CHECK_POINTER(FR_Dscr_p);
+ EIP207_FLOW_CHECK_POINTER(FlowInData_p);
+
+#ifdef EIP207_FLOW_STRICT_ARGS
+ // Provided flow record physical DMA address must be addressable by
+ // a 32-bit offset to the Base Address installed via
+ // the EIP207_Flow_RC_BaseAddr_Set() function
+ if(!EIP207Lib_Flow_Is32bitAddressable(
+ TrueIOArea_p->HT_Params[HashTableId].BaseAddr.Addr,
+ TrueIOArea_p->HT_Params[HashTableId].BaseAddr.UpperAddr,
+ FR_Dscr_p->DMA_Addr.Addr,
+ FR_Dscr_p->DMA_Addr.UpperAddr))
+ return EIP207_FLOW_ARGUMENT_ERROR;
+
+ // Provided transform record physical DMA address must be addressable by
+ // a 32-bit offset to the Base Address installed via
+ // the EIP207_Flow_RC_BaseAddr_Set() function
+ if(FlowInData_p->Xform_DMA_Addr.Addr != EIP207_FLOW_RECORD_DUMMY_ADDRESS &&
+ !EIP207Lib_Flow_Is32bitAddressable(
+ TrueIOArea_p->HT_Params[HashTableId].BaseAddr.Addr,
+ TrueIOArea_p->HT_Params[HashTableId].BaseAddr.UpperAddr,
+ FlowInData_p->Xform_DMA_Addr.Addr,
+ FlowInData_p->Xform_DMA_Addr.UpperAddr))
+ return EIP207_FLOW_ARGUMENT_ERROR;
+#endif // EIP207_FLOW_STRICT_ARGS
+
+ ZEROINIT(Rec_Data);
+ ZEROINIT(FR_Data);
+
+ FR_Data.Flags = FlowInData_p->Flags;
+ FR_Data.SW_FR_Reference = FlowInData_p->SW_FR_Reference;
+ FR_Data.Xform_DMA_Addr = FlowInData_p->Xform_DMA_Addr;
+ FR_Data.fLarge = FlowInData_p->fLarge;
+
+ Rec_Data.HashID_p = &FlowInData_p->HashID;
+ Rec_Data.FR_Data_p = &FR_Data;
+
+ Flow_Rc = EIP207Lib_Flow_DTL_Record_Add(
+ &TrueIOArea_p->HT_Params[HashTableId],
+ (EIP207_Flow_Dscr_t*)FR_Dscr_p,
+ &Rec_Data);
+ if (Flow_Rc != EIP207_FLOW_NO_ERROR)
+ return Flow_Rc;
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+ {
+ EIP207_Flow_Error_t rv;
+ uint32_t State = TrueIOArea_p->State;
+
+ TrueIOArea_p->Rec_InstalledCounter++;
+
+ // Transit to a new state
+ rv = EIP207_Flow_State_Set((EIP207_Flow_State_t* const)&State,
+ EIP207_FLOW_STATE_INSTALLED);
+
+ TrueIOArea_p->State = State;
+
+ if (rv != EIP207_FLOW_NO_ERROR)
+ return EIP207_FLOW_ILLEGAL_IN_STATE;
+ }
+#endif // EIP207_FLOW_DEBUG_FSM
+
+ return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_RC_BaseAddr_Set
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_RC_BaseAddr_Set(
+ EIP207_Flow_IOArea_t * const IOArea_p,
+ const unsigned int HashTableId,
+ const EIP207_Flow_Address_t * const FlowBaseAddr_p,
+ const EIP207_Flow_Address_t * const TransformBaseAddr_p)
+{
+ Device_Handle_t Device;
+ volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP207_FLOW_CHECK_POINTER(IOArea_p);
+ EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+ EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+
+ IDENTIFIER_NOT_USED(TransformBaseAddr_p);
+
+ Device = TrueIOArea_p->Device;
+
+ // Set the common base address for all the records which can be looked up
+ // Note: Standard (legacy) record cache should have
+ // EIP207_RC_SET_NR_DEFAULT set (which is 0, just one Hash Table);
+ // High-performance (HP) record cache should have
+ // HashTableId set
+#ifndef EIP207_FLUE_RC_HP
+ EIP207_RC_BaseAddr_Set(Device,
+ EIP207_FRC_REG_BASE,
+ HashTableId, // EIP207_RC_SET_NR_DEFAULT
+ FlowBaseAddr_p->Addr,
+ FlowBaseAddr_p->UpperAddr);
+#else
+ EIP207_FLUE_CACHEBASE_LO_WR(Device, HashTableId, FlowBaseAddr_p->Addr);
+ EIP207_FLUE_CACHEBASE_HI_WR(Device, HashTableId, FlowBaseAddr_p->UpperAddr);
+#endif
+
+ TrueIOArea_p->HT_Params[HashTableId].BaseAddr.Addr = FlowBaseAddr_p->Addr;
+ TrueIOArea_p->HT_Params[HashTableId].BaseAddr.UpperAddr =
+ FlowBaseAddr_p->UpperAddr;
+
+ return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*****************************************************************************
+ * DTL-specific API functions
+ */
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_FR_Remove
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_DTL_FR_Remove(
+ EIP207_Flow_IOArea_t * const IOArea_p,
+ const unsigned int HashTableId,
+ EIP207_Flow_FR_Dscr_t * const FR_Dscr_p)
+{
+ volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+ EIP207_Flow_HTE_Dscr_RecData_t * FR_Data_p;
+ EIP207_Flow_Error_t Flow_Rc;
+
+ EIP207_FLOW_CHECK_POINTER(IOArea_p);
+ EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+ EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+ EIP207_FLOW_CHECK_POINTER(FR_Dscr_p);
+
+ FR_Data_p = (EIP207_Flow_HTE_Dscr_RecData_t*)FR_Dscr_p->InternalData_p;
+
+ EIP207_FLOW_CHECK_POINTER(FR_Data_p);
+ EIP207_FLOW_CHECK_POINTER(FR_Data_p->HTE_Dscr_p);
+
+#ifdef EIP207_FLOW_STRICT_ARGS
+ // Provided flow record physical DMA address must be addressable by
+ // a 32-bit offset to the Based Address installed via
+ // the EIP207_Flow_RC_BaseAddr_Set() function
+ if(!EIP207Lib_Flow_Is32bitAddressable(
+ TrueIOArea_p->HT_Params[HashTableId].BaseAddr.Addr,
+ TrueIOArea_p->HT_Params[HashTableId].BaseAddr.UpperAddr,
+ FR_Dscr_p->DMA_Addr.Addr,
+ FR_Dscr_p->DMA_Addr.UpperAddr))
+ return EIP207_FLOW_ARGUMENT_ERROR;
+
+ if (FR_Data_p->Type != EIP207_FLOW_REC_FLOW)
+ return EIP207_FLOW_INTERNAL_ERROR;
+#endif // EIP207_FLOW_STRICT_ARGS
+
+ Flow_Rc = EIP207Lib_Flow_DTL_Record_Remove(
+ TrueIOArea_p->Device,
+ HashTableId,
+ &TrueIOArea_p->HT_Params[HashTableId],
+ (EIP207_Flow_Dscr_t*)FR_Dscr_p);
+ if (Flow_Rc != EIP207_FLOW_NO_ERROR)
+ return Flow_Rc;
+
+ IDENTIFIER_NOT_USED(FR_Data_p);
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+ {
+ EIP207_Flow_Error_t rv;
+ uint32_t State = TrueIOArea_p->State;
+
+ TrueIOArea_p->Rec_InstalledCounter--;
+
+ // Transit to a new state
+ if (TrueIOArea_p->Rec_InstalledCounter == 0)
+ // Last record is removed
+ rv = EIP207_Flow_State_Set(
+ (EIP207_Flow_State_t* const)&State,
+ EIP207_FLOW_STATE_ENABLED);
+ else
+ // Non-last record is removed
+ rv = EIP207_Flow_State_Set(
+ (EIP207_Flow_State_t* const)&State,
+ EIP207_FLOW_STATE_INSTALLED);
+
+ TrueIOArea_p->State = State;
+
+ if (rv != EIP207_FLOW_NO_ERROR)
+ return EIP207_FLOW_ILLEGAL_IN_STATE;
+ }
+#endif // EIP207_FLOW_DEBUG_FSM
+
+ return EIP207_FLOW_NO_ERROR;
+}
+
+
+#ifndef EIP207_FLOW_REMOVE_TR_LARGE_SUPPORT
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_TR_Large_WordCount_Get
+ */
+unsigned int
+EIP207_Flow_DTL_TR_Large_WordCount_Get(void)
+{
+ return FIRMWARE_EIP207_CS_FLOW_TRC_RECORD_WORD_COUNT_LARGE;
+}
+#endif // !EIP207_FLOW_REMOVE_TR_LARGE_SUPPORT
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_TR_Add
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_DTL_TR_Add(
+ EIP207_Flow_IOArea_t * const IOArea_p,
+ const unsigned int HashTableId,
+ EIP207_Flow_TR_Dscr_t * const TR_Dscr_p,
+ const EIP207_Flow_TR_InputData_t * const XformInData_p)
+{
+ volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+ EIP207_Flow_Record_InputData_t Rec_Data;
+ EIP207_Flow_TR_Data_t TR_Data;
+ EIP207_Flow_Error_t Flow_Rc;
+
+ EIP207_FLOW_CHECK_POINTER(IOArea_p);
+ EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+ EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+ EIP207_FLOW_CHECK_POINTER(TR_Dscr_p);
+ EIP207_FLOW_CHECK_POINTER(XformInData_p);
+
+#ifdef EIP207_FLOW_STRICT_ARGS
+ // Provided transform record physical DMA address must be addressable by
+ // a 32-bit offset to the Transform Based Address installed via
+ // the EIP207_Flow_RC_BaseAddr_Set() function
+ if(!EIP207Lib_Flow_Is32bitAddressable(
+ TrueIOArea_p->HT_Params[HashTableId].BaseAddr.Addr,
+ TrueIOArea_p->HT_Params[HashTableId].BaseAddr.UpperAddr,
+ TR_Dscr_p->DMA_Addr.Addr,
+ TR_Dscr_p->DMA_Addr.UpperAddr))
+ return EIP207_FLOW_ARGUMENT_ERROR;
+#endif // EIP207_FLOW_STRICT_ARGS
+
+ ZEROINIT(Rec_Data);
+ ZEROINIT(TR_Data);
+
+ TR_Data.fLarge = XformInData_p->fLarge;
+
+ Rec_Data.HashID_p = &XformInData_p->HashID;
+ Rec_Data.TR_Data_p = &TR_Data;
+
+ Flow_Rc = EIP207Lib_Flow_DTL_Record_Add(
+ &TrueIOArea_p->HT_Params[HashTableId],
+ (EIP207_Flow_Dscr_t*)TR_Dscr_p,
+ &Rec_Data);
+ if (Flow_Rc != EIP207_FLOW_NO_ERROR)
+ return Flow_Rc;
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+ {
+ EIP207_Flow_Error_t rv;
+ uint32_t State = TrueIOArea_p->State;
+
+ TrueIOArea_p->Rec_InstalledCounter++;
+
+ // Transit to a new state
+ rv = EIP207_Flow_State_Set((EIP207_Flow_State_t* const)&State,
+ EIP207_FLOW_STATE_INSTALLED);
+
+ TrueIOArea_p->State = State;
+
+ if (rv != EIP207_FLOW_NO_ERROR)
+ return EIP207_FLOW_ILLEGAL_IN_STATE;
+ }
+#endif // EIP207_FLOW_DEBUG_FSM
+
+ return EIP207_FLOW_NO_ERROR;
+}
+
+
+#ifndef EIP207_FLOW_REMOVE_TR_LARGE_SUPPORT
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_TR_Large_Read
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_DTL_TR_Large_Read(
+ EIP207_Flow_IOArea_t * const IOArea_p,
+ const unsigned int HashTableId,
+ const EIP207_Flow_TR_Dscr_t * const TR_Dscr_p,
+ EIP207_Flow_TR_OutputData_t * const XformData_p)
+{
+ EIP207_Flow_Error_t rv;
+ uint32_t Value32, SeqNrWordOffset;
+
+ EIP207_FLOW_CHECK_POINTER(IOArea_p);
+ EIP207_FLOW_CHECK_POINTER(TR_Dscr_p);
+ EIP207_FLOW_CHECK_POINTER(XformData_p);
+ EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+ EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+
+ IDENTIFIER_NOT_USED(IOArea_p);
+ IDENTIFIER_NOT_USED(HashTableId);
+
+ // Prepare the transform record for reading
+ DMAResource_PostDMA(TR_Dscr_p->DMA_Handle, 0, 0);
+
+ // Read the transform record data
+
+ // Recent record Packets Counter
+ XformData_p->PacketsCounter =
+ DMAResource_Read32(
+ TR_Dscr_p->DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET_LARGE);
+
+ // Read Token Context Instruction word
+ Value32 =
+ DMAResource_Read32(TR_Dscr_p->DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET_LARGE);
+
+ // Extract the Sequence Number word offset from the read value
+ FIRMWARE_EIP207_CS_Flow_SeqNum_Offset_Read(Value32, &SeqNrWordOffset);
+
+ // Read the sequence number
+ XformData_p->SequenceNumber =
+ DMAResource_Read32(TR_Dscr_p->DMA_Handle, SeqNrWordOffset);
+
+ // Recent record time stamp
+ rv = EIP207_Flow_Internal_Read64(
+ TR_Dscr_p->DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET_LARGE,
+ FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET_LARGE,
+ &XformData_p->LastTimeLo,
+ &XformData_p->LastTimeHi);
+ if (rv != EIP207_FLOW_NO_ERROR)
+ return rv;
+
+ // Recent record Octets Counter
+ rv = EIP207_Flow_Internal_Read64(
+ TR_Dscr_p->DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET_LARGE,
+ FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET_LARGE,
+ &XformData_p->OctetsCounterLo,
+ &XformData_p->OctetsCounterHi);
+ if (rv != EIP207_FLOW_NO_ERROR)
+ return rv;
+
+ return EIP207_FLOW_NO_ERROR;
+}
+#endif // !EIP207_FLOW_REMOVE_TR_LARGE_SUPPORT
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_DTL_TR_Remove
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_DTL_TR_Remove(
+ EIP207_Flow_IOArea_t * const IOArea_p,
+ const unsigned int HashTableId,
+ EIP207_Flow_TR_Dscr_t * const TR_Dscr_p)
+{
+ volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+ EIP207_Flow_HTE_Dscr_RecData_t * TR_Data_p;
+ EIP207_Flow_Error_t Flow_Rc;
+
+ EIP207_FLOW_CHECK_POINTER(IOArea_p);
+ EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+ EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+ EIP207_FLOW_CHECK_POINTER(TR_Dscr_p);
+
+ TR_Data_p = (EIP207_Flow_HTE_Dscr_RecData_t*)TR_Dscr_p->InternalData_p;
+
+ EIP207_FLOW_CHECK_POINTER(TR_Data_p);
+ EIP207_FLOW_CHECK_POINTER(TR_Data_p->HTE_Dscr_p);
+
+#ifdef EIP207_FLOW_STRICT_ARGS
+ // Provided transform record physical DMA address must be addressable by
+ // a 32-bit offset to the Transform Based Address installed via
+ // the EIP207_Flow_RC_BaseAddr_Set() function
+ if(!EIP207Lib_Flow_Is32bitAddressable(
+ TrueIOArea_p->HT_Params[HashTableId].BaseAddr.Addr,
+ TrueIOArea_p->HT_Params[HashTableId].BaseAddr.UpperAddr,
+ TR_Dscr_p->DMA_Addr.Addr,
+ TR_Dscr_p->DMA_Addr.UpperAddr))
+ return EIP207_FLOW_ARGUMENT_ERROR;
+
+ if (TR_Data_p->Type != EIP207_FLOW_REC_TRANSFORM_SMALL &&
+ TR_Data_p->Type != EIP207_FLOW_REC_TRANSFORM_LARGE)
+ return EIP207_FLOW_INTERNAL_ERROR;
+#endif // EIP207_FLOW_STRICT_ARGS
+
+ Flow_Rc = EIP207Lib_Flow_DTL_Record_Remove(
+ TrueIOArea_p->Device,
+ HashTableId,
+ &TrueIOArea_p->HT_Params[HashTableId],
+ (EIP207_Flow_Dscr_t*)TR_Dscr_p);
+ if (Flow_Rc != EIP207_FLOW_NO_ERROR)
+ return Flow_Rc;
+
+ IDENTIFIER_NOT_USED(TR_Data_p);
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+ {
+ EIP207_Flow_Error_t rv;
+ uint32_t State = TrueIOArea_p->State;
+
+ TrueIOArea_p->Rec_InstalledCounter--;
+
+ // Transit to a new state
+ if (TrueIOArea_p->Rec_InstalledCounter == 0)
+ // Last record is removed
+ rv = EIP207_Flow_State_Set(
+ (EIP207_Flow_State_t* const)&State,
+ EIP207_FLOW_STATE_ENABLED);
+ else
+ // Non-last record is removed
+ rv = EIP207_Flow_State_Set(
+ (EIP207_Flow_State_t* const)&State,
+ EIP207_FLOW_STATE_INSTALLED);
+
+ TrueIOArea_p->State = State;
+
+ if (rv != EIP207_FLOW_NO_ERROR)
+ return EIP207_FLOW_ILLEGAL_IN_STATE;
+ }
+#endif // EIP207_FLOW_DEBUG_FSM
+
+ return EIP207_FLOW_NO_ERROR;
+}
+
+
+/* end of file eip207_flow_dtl.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_generic.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_generic.c
new file mode 100644
index 0000000..cd3ecbd
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_generic.c
@@ -0,0 +1,512 @@
+/* eip207_flow_generic.c
+ *
+ * Partial EIP-207 Flow Control Generic API implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207 Driver Library Flow Control Generic API
+#include "eip207_flow_generic.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_flow.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // uint32_t
+
+// Driver Framework C Run-time Library API
+#include "clib.h" // ZEROINIT, memset, memcpy
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h"
+#include "dmares_rw.h"
+
+// EIP-207 Flow Control Driver Library Internal interfaces
+#include "eip207_flow_level0.h" // EIP-207 Level 0 macros
+#include "eip207_flow_internal.h"
+
+// EIP-207 Firmware API
+#include "firmware_eip207_api_flow_cs.h" // Classification API: Flow Control
+#include "firmware_eip207_api_cs.h" // Classification API: General
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_Detect
+ *
+ * Checks the presence of EIP-207c hardware. Returns true when found.
+ */
+static bool
+EIP207Lib_Flow_Detect(
+ const Device_Handle_t Device)
+{
+ uint32_t Value;
+
+ Value = EIP207_Flow_Read32(Device, EIP207_FLUE_FHT_REG_VERSION);
+ if (!EIP207_FLUE_SIGNATURE_MATCH( Value ))
+ return false;
+
+ // read-write test one of the registers
+
+ // Set MASK_31_BITS bits of the EIP207_FLUE_REG_HASHBASE_LO register
+ EIP207_Flow_Write32( Device,
+ EIP207_FLUE_FHT_REG_HASHBASE_LO(0),
+ ~MASK_2_BITS);
+ Value = EIP207_Flow_Read32(Device, EIP207_FLUE_FHT_REG_HASHBASE_LO(0));
+ if ((Value) != ~MASK_2_BITS)
+ return false;
+
+ // Clear MASK_31_BITS bits of the EIP207_FLUE_REG_HASHBASE_LO register
+ EIP207_Flow_Write32(Device, EIP207_FLUE_FHT_REG_HASHBASE_LO(0), 0);
+ Value = EIP207_Flow_Read32(Device, EIP207_FLUE_FHT_REG_HASHBASE_LO(0));
+ if (Value != 0)
+ return false;
+
+ return true;
+}
+
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Flow_State_Set
+ *
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_State_Set(
+ EIP207_Flow_State_t * const CurrentState,
+ const EIP207_Flow_State_t NewState)
+{
+ switch(*CurrentState)
+ {
+ case EIP207_FLOW_STATE_INITIALIZED:
+ switch(NewState)
+ {
+ case EIP207_FLOW_STATE_ENABLED:
+ *CurrentState = NewState;
+ break;
+ case EIP207_FLOW_STATE_FATAL_ERROR:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP207_FLOW_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP207_FLOW_STATE_ENABLED:
+ switch(NewState)
+ {
+ case EIP207_FLOW_STATE_INSTALLED:
+ *CurrentState = NewState;
+ break;
+ case EIP207_FLOW_STATE_FATAL_ERROR:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP207_FLOW_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP207_FLOW_STATE_INSTALLED:
+ switch(NewState)
+ {
+ case EIP207_FLOW_STATE_INSTALLED:
+ *CurrentState = NewState;
+ break;
+ case EIP207_FLOW_STATE_ENABLED:
+ *CurrentState = NewState;
+ break;
+ case EIP207_FLOW_STATE_FATAL_ERROR:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP207_FLOW_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ default:
+ return EIP207_FLOW_ILLEGAL_IN_STATE;
+ }
+
+ return EIP207_FLOW_NO_ERROR;
+}
+#endif // EIP207_FLOW_DEBUG_FSM
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_IOArea_ByteCount_Get
+ */
+unsigned int
+EIP207_Flow_IOArea_ByteCount_Get(void)
+{
+ return sizeof(EIP207_Flow_True_IOArea_t);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_HT_Entry_WordCount_Get
+ */
+unsigned int
+EIP207_Flow_HT_Entry_WordCount_Get(void)
+{
+ return EIP207_FLOW_HT_ENTRY_WORD_COUNT;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_Init
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_Init(
+ EIP207_Flow_IOArea_t * const IOArea_p,
+ const Device_Handle_t Device)
+{
+ volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP207_FLOW_CHECK_POINTER(IOArea_p);
+
+ // Detect presence of EIP-207c HW hardware
+ if (!EIP207Lib_Flow_Detect(Device))
+ return EIP207_FLOW_UNSUPPORTED_FEATURE_ERROR;
+
+ // Initialize the IO Area
+ TrueIOArea_p->Device = Device;
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+ {
+ TrueIOArea_p->Rec_InstalledCounter = 0;
+
+ TrueIOArea_p->State = (uint32_t)EIP207_FLOW_STATE_INITIALIZED;
+ }
+#endif // EIP207_FLOW_DEBUG_FSM
+
+ return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_ID_Compute
+ *
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_ID_Compute(
+ EIP207_Flow_IOArea_t * const IOArea_p,
+ const unsigned int HashTableId,
+ const EIP207_Flow_SelectorParams_t * const SelectorParams_p,
+ EIP207_Flow_ID_t * const FlowID)
+{
+ uint32_t h1, h2, h3, h4;
+ uint32_t w;
+ const uint32_t * p;
+ uint32_t count, data [FIRMWARE_EIP207_CS_FLOW_HASH_ID_INPUT_WORD_COUNT];
+ Device_Handle_t Device;
+ FIRMWARE_EIP207_CS_Flow_SelectorParams_t Selectors;
+ volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP207_FLOW_CHECK_POINTER(IOArea_p);
+ EIP207_FLOW_CHECK_POINTER(SelectorParams_p);
+ EIP207_FLOW_CHECK_POINTER(FlowID);
+
+ Device = TrueIOArea_p->Device;
+
+ // Read the IV from the flow hash engine in the classification engine
+ // The IV must have been already installed in the flow hash engine
+ // via the Global Classification Control API
+ EIP207_FHASH_IV_RD(Device, HashTableId, &h1, &h2, &h3, &h4);
+
+ // Install the selectors for the flow hash ID calculation
+ ZEROINIT(Selectors);
+ Selectors.Flags = SelectorParams_p->Flags;
+ Selectors.DstIp_p = SelectorParams_p->DstIp_p;
+ Selectors.DstPort = SelectorParams_p->DstPort;
+ Selectors.IpProto = SelectorParams_p->IpProto;
+ Selectors.SPI = SelectorParams_p->SPI;
+#ifdef FIRMWARE_EIP207_CS_FLOW_DTLS_SUPPORTED
+ Selectors.Epoch = SelectorParams_p->Epoch;
+#endif
+ Selectors.SrcIp_p = SelectorParams_p->SrcIp_p;
+ Selectors.SrcPort = SelectorParams_p->SrcPort;
+ FIRMWARE_EIP207_CS_Flow_Selectors_Reorder(&Selectors, data, &count);
+
+ p = data;
+
+ while (p < &data[count - 3])
+ {
+ w = *p++;
+ h2 ^= w;
+ h1 += w;
+ h1 += h1 << 10;
+ h1 ^= h1 >> 6;
+
+ w = *p++;
+ h3 ^= w;
+ h1 += w;
+ h1 += h1 << 10;
+ h1 ^= h1 >> 6;
+
+ w = *p++;
+ h4 ^= w;
+ h1 += w;
+ h1 += h1 << 10;
+ h1 ^= h1 >> 6;
+
+ /* Mixing step for the 96 bits in h2-h4. The code comes from a
+ hash table lookup function by Robert J. Jenkins, and has been
+ presented on numerous web pages and in a Dr. Dobbs Journal
+ sometimes in late 90's.
+
+ h1 is computed according to the one-at-a-time hash function,
+ presented in the same article. */
+ h2 -= h3; h2 -= h4; h2 ^= h4 >> 13;
+ h3 -= h4; h3 -= h2; h3 ^= h2 << 8;
+ h4 -= h2; h4 -= h3; h4 ^= h3 >> 13;
+ h2 -= h3; h2 -= h4; h2 ^= h4 >> 12;
+ h3 -= h4; h3 -= h2; h3 ^= h2 << 16;
+ h4 -= h2; h4 -= h3; h4 ^= h3 >> 5;
+ h2 -= h3; h2 -= h4; h2 ^= h4 >> 3;
+ h3 -= h4; h3 -= h2; h3 ^= h2 << 10;
+ h4 -= h2; h4 -= h3; h4 ^= h3 >> 15;
+ } // while
+
+ w = *p++;
+ h1 += w;
+ h1 += h1 << 10;
+ h1 ^= h1 >> 6;
+ h2 ^= w;
+
+ if (p < data + count)
+ {
+ w = *p++;
+ h1 += w;
+ h1 += h1 << 10;
+ h1 ^= h1 >> 6;
+ h3 ^= w;
+
+ if (p < data + count)
+ {
+ w = *p++;
+ h1 += w;
+ h1 += h1 << 10;
+ h1 ^= h1 >> 6;
+ h4 ^= w;
+ }
+ }
+
+ FlowID->Word32[0] = h1;
+ FlowID->Word32[1] = h2;
+ FlowID->Word32[2] = h3;
+ FlowID->Word32[3] = h4;
+
+ return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_FR_WordCount_Get
+ */
+unsigned int
+EIP207_Flow_FR_WordCount_Get(void)
+{
+ return FIRMWARE_EIP207_CS_FRC_RECORD_WORD_COUNT;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_FR_Read
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_FR_Read(
+ EIP207_Flow_IOArea_t * const IOArea_p,
+ const unsigned int HashTableId,
+ EIP207_Flow_FR_Dscr_t * const FR_Dscr_p,
+ EIP207_Flow_FR_OutputData_t * const FlowData_p)
+{
+ EIP207_Flow_Error_t rv;
+
+ EIP207_FLOW_CHECK_POINTER(IOArea_p);
+ EIP207_FLOW_CHECK_POINTER(FR_Dscr_p);
+ EIP207_FLOW_CHECK_POINTER(FlowData_p);
+ EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+ EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+
+ IDENTIFIER_NOT_USED(HashTableId);
+
+#ifdef EIP207_FLOW_CONSISTENCY_CHECK
+ // Consistency check for the provided flow descriptor
+ if (FR_Dscr_p->DMA_Addr.Addr == EIP207_FLOW_RECORD_DUMMY_ADDRESS)
+ return EIP207_FLOW_INTERNAL_ERROR;
+#endif // EIP207_FLOW_CONSISTENCY_CHECK
+
+ // Prepare the flow record for reading
+ DMAResource_PostDMA(FR_Dscr_p->DMA_Handle, 0, 0);
+
+ // Read the flow record data
+
+ // Recent record Packets Counter
+ FlowData_p->PacketsCounter =
+ DMAResource_Read32(FR_Dscr_p->DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_FR_STAT_PKT_WORD_OFFSET);
+
+ // Recent record time stamp
+ rv = EIP207_Flow_Internal_Read64(
+ FR_Dscr_p->DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_FR_TIME_STAMP_LO_WORD_OFFSET,
+ FIRMWARE_EIP207_CS_FLOW_FR_TIME_STAMP_HI_WORD_OFFSET,
+ &FlowData_p->LastTimeLo,
+ &FlowData_p->LastTimeHi);
+ if (rv != EIP207_FLOW_NO_ERROR)
+ return rv;
+
+ // Recent record Octets Counter
+ rv = EIP207_Flow_Internal_Read64(
+ FR_Dscr_p->DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_FR_STAT_OCT_LO_WORD_OFFSET,
+ FIRMWARE_EIP207_CS_FLOW_FR_STAT_OCT_HI_WORD_OFFSET,
+ &FlowData_p->OctetsCounterLo,
+ &FlowData_p->OctetsCounterHi);
+ if (rv != EIP207_FLOW_NO_ERROR)
+ return rv;
+
+#ifdef EIP207_FLOW_DEBUG_FSM
+ {
+ volatile EIP207_Flow_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+ uint32_t State = TrueIOArea_p->State;
+
+ // Remain in the current state
+ rv = EIP207_Flow_State_Set(
+ (EIP207_Flow_State_t* const)&State,
+ (EIP207_Flow_State_t)TrueIOArea_p->State);
+
+ TrueIOArea_p->State = State;
+
+ if (rv != EIP207_FLOW_NO_ERROR)
+ return EIP207_FLOW_ILLEGAL_IN_STATE;
+ }
+#else
+ IDENTIFIER_NOT_USED(IOArea_p);
+#endif // EIP207_FLOW_DEBUG_FSM
+
+ return EIP207_FLOW_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_TR_WordCount_Get
+ */
+unsigned int
+EIP207_Flow_TR_WordCount_Get(void)
+{
+ return FIRMWARE_EIP207_CS_TRC_RECORD_WORD_COUNT;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_TR_Read
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_TR_Read(
+ EIP207_Flow_IOArea_t * const IOArea_p,
+ const unsigned int HashTableId,
+ const EIP207_Flow_TR_Dscr_t * const TR_Dscr_p,
+ EIP207_Flow_TR_OutputData_t * const XformData_p)
+{
+ EIP207_Flow_Error_t rv;
+ uint32_t Value32, SeqNrWordOffset;
+
+ EIP207_FLOW_CHECK_POINTER(IOArea_p);
+ EIP207_FLOW_CHECK_POINTER(TR_Dscr_p);
+ EIP207_FLOW_CHECK_POINTER(XformData_p);
+ EIP207_FLOW_CHECK_INT_ATMOST(HashTableId + 1,
+ EIP207_FLOW_MAX_NOF_FLOW_HASH_TABLES_TO_USE);
+
+ IDENTIFIER_NOT_USED(IOArea_p);
+ IDENTIFIER_NOT_USED(HashTableId);
+
+ // Prepare the transform record for reading
+ DMAResource_PostDMA(TR_Dscr_p->DMA_Handle, 0, 0);
+
+ // Read the transform record data
+
+ // Recent record Packets Counter
+ XformData_p->PacketsCounter =
+ DMAResource_Read32(TR_Dscr_p->DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_TR_STAT_PKT_WORD_OFFSET);
+
+ // Read Token Context Instruction word
+ Value32 =
+ DMAResource_Read32(TR_Dscr_p->DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_TR_TK_CTX_INST_WORD_OFFSET);
+
+ // Extract the Sequence Number word offset from the read value
+ FIRMWARE_EIP207_CS_Flow_SeqNum_Offset_Read(Value32, &SeqNrWordOffset);
+
+ // Read the sequence number
+ XformData_p->SequenceNumber =
+ DMAResource_Read32(TR_Dscr_p->DMA_Handle, SeqNrWordOffset);
+
+ // Recent record time stamp
+ rv = EIP207_Flow_Internal_Read64(
+ TR_Dscr_p->DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_LO_WORD_OFFSET,
+ FIRMWARE_EIP207_CS_FLOW_TR_TIME_STAMP_HI_WORD_OFFSET,
+ &XformData_p->LastTimeLo,
+ &XformData_p->LastTimeHi);
+ if (rv != EIP207_FLOW_NO_ERROR)
+ return rv;
+
+ // Recent record Octets Counter
+ rv = EIP207_Flow_Internal_Read64(
+ TR_Dscr_p->DMA_Handle,
+ FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_LO_WORD_OFFSET,
+ FIRMWARE_EIP207_CS_FLOW_TR_STAT_OCT_HI_WORD_OFFSET,
+ &XformData_p->OctetsCounterLo,
+ &XformData_p->OctetsCounterHi);
+ if (rv != EIP207_FLOW_NO_ERROR)
+ return rv;
+
+ return EIP207_FLOW_NO_ERROR;
+}
+
+
+/* end of file eip207_flow_generic.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_internal.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_internal.c
new file mode 100644
index 0000000..1b61461
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flow_internal.c
@@ -0,0 +1,95 @@
+/* eip207_flow_internal.c
+ *
+ * EIP-207 Flow Control Internal interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207 Flow Control Driver Library Internal interfaces
+#include "eip207_flow_internal.h"
+#include "eip207_flow_generic.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+#include "eip207_flow_level0.h" // EIP-207 Level 0 macros
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // BIT definitions, bool, uint32_t
+
+// Driver Framework DMA Resource API
+#include "dmares_types.h" // DMAResource_Handle_t
+#include "dmares_rw.h" // DMAResource_Write32()/_Read32()/_PreDMA()
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Flow_Internal_Read64
+ */
+EIP207_Flow_Error_t
+EIP207_Flow_Internal_Read64(
+ const DMAResource_Handle_t Handle,
+ const unsigned int Value64_WordOffsetLo,
+ const unsigned int Value64_WordOffsetHi,
+ uint32_t * const Value64_Lo,
+ uint32_t * const Value64_Hi)
+{
+ uint32_t Value32;
+ unsigned int i;
+
+ for (i = 0; i < EIP207_FLOW_VALUE_64BIT_MAX_NOF_READ_ATTEMPTS; i++)
+ {
+ Value32 = DMAResource_Read32(Handle, Value64_WordOffsetHi);
+ *Value64_Lo = DMAResource_Read32(Handle, Value64_WordOffsetLo);
+
+ // Prepare the flow record for reading
+ DMAResource_PostDMA(Handle, 0, 0);
+
+ *Value64_Hi = DMAResource_Read32(Handle, Value64_WordOffsetHi);
+
+ if (Value32 == (*Value64_Hi))
+ return EIP207_FLOW_NO_ERROR;
+ }
+
+ return EIP207_FLOW_INTERNAL_ERROR;
+}
+
+
+/* end of file eip207_flow_hte_dscr_dtl.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flue.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flue.c
new file mode 100644
index 0000000..1074b7a
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_flue.c
@@ -0,0 +1,177 @@
+/* eip207_ice.c
+ *
+ * EIP-207s Flow Look-Up Engine (FLUE) interface implementation
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207s Flow Look-Up Engine (FLUE) interface
+#include "eip207_flue.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // uint32_t, bool
+
+// EIP-207 Global Control Driver Library Internal interfaces
+#include "eip207_level0.h" // EIP-207 Level 0 macros
+
+// EIP-207 HW interface
+#include "eip207_hw_interface.h"
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+
+// EIP-207 Firmware Classification API
+#include "firmware_eip207_api_cs.h" // Classification API: General
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define EIP207_FLUE_3ENTRY_LOOKUP_MODE 1
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_FLUE_Init
+ */
+void
+EIP207_FLUE_Init(
+ const Device_Handle_t Device,
+ const unsigned int HashTableId,
+ const EIP207_Global_FLUEConfig_t * const FLUEConf_p,
+ const bool fARC4Present,
+ const bool fLookupCachePresent)
+{
+ // Configure hash tables
+ EIP207_FLUE_CONFIG_WR(Device,
+ HashTableId, // Hash Table ID
+ HashTableId, // Function,
+ // set it equal to hash table id
+ 0, // Generation
+ true, // Table enable
+ true); // Access enable
+
+ // Use Hash table 0 parameters, they must be the same for all the tables!
+ // Initialize FLUE with EIP-207 Firmware Classification API parameters
+ EIP207_FLUE_OFFSET_WR(Device,
+ FLUEConf_p->HashTable[HashTableId].fPrefetchXform,
+ fLookupCachePresent ?
+ FLUEConf_p->HashTable[HashTableId].fLookupCached :
+ false,
+ FIRMWARE_EIP207_CS_XFORM_RECORD_WORD_OFFSET);
+
+ // Use Hash table 0 parameters, they must be the same for all the tables!
+ // Check if ARC4 Record Cache is available
+ if ( fARC4Present )
+ {
+ EIP207_FLUE_ARC4_OFFSET_WR(
+ Device,
+ FLUEConf_p->HashTable[HashTableId].fPrefetchARC4State,
+ EIP207_GLOBAL_FLUE_LOOKUP_MODE,
+ FIRMWARE_EIP207_CS_ARC4_RECORD_WORD_OFFSET);
+ }
+#if EIP207_GLOBAL_FLUE_LOOKUP_MODE == EIP207_FLUE_3ENTRY_LOOKUP_MODE
+ else
+ {
+ EIP207_FLUE_ARC4_OFFSET_WR(Device,
+ HashTableId,
+ EIP207_GLOBAL_FLUE_LOOKUP_MODE,
+ 0);
+ }
+#endif // EIP207_GLOBAL_FLUE_LOOKUP_MODE == EIP207_FLUE_1ENTRY_LOOKUP_MODE
+
+#ifdef EIP207_FLUE_HAVE_VIRTUALIZATION
+ // Virtualisation support present, initialize the lookup table.
+ // All interfaces refer to Table # 0.
+ {
+ unsigned int i;
+ unsigned int c;
+ unsigned int idx0,idx1,idx2,idx3;
+
+ c = FLUEConf_p->InterfacesCount;
+ if (c > EIP207_FLUE_MAX_NOF_INTERFACES_TO_USE)
+ c = EIP207_FLUE_MAX_NOF_INTERFACES_TO_USE;
+
+ for (i = 0; i < c; i += 4)
+ {
+ idx0 = FLUEConf_p->InterfaceIndex[i];
+
+ if (i + 1 < c)
+ idx1 = FLUEConf_p->InterfaceIndex[i + 1];
+ else
+ idx1 = 0;
+
+ if (i + 2 < c)
+ idx2 = FLUEConf_p->InterfaceIndex[i + 2];
+ else
+ idx2 = 0;
+
+ if (i + 3 < c)
+ idx3 = FLUEConf_p->InterfaceIndex[i + 3];
+ else
+ idx3 = 0;
+
+ EIP207_FLUE_IFC_LUT_WR(Device,
+ i / 4,
+ idx0, idx1, idx2, idx3);
+ }
+ }
+#endif
+
+ return;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_FLUE_Status_Get
+ */
+void
+EIP207_FLUE_Status_Get(
+ const Device_Handle_t Device,
+ EIP207_Global_FLUE_Status_t * const FLUE_Status_p)
+{
+ IDENTIFIER_NOT_USED(Device);
+
+ FLUE_Status_p->Error1 = 0;
+ FLUE_Status_p->Error2 = 0;
+
+ return;
+}
+
+
+/* end of file eip207_flue.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_fluec.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_fluec.c
new file mode 100644
index 0000000..82f04ac
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_fluec.c
@@ -0,0 +1,77 @@
+/* eip207_fluec.c
+ *
+ * EIP-207 Flow Look-Up Engine Cache (FLUEC) interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207s Flow Look-Up Engine Cache (FLUEC) interface
+#include "eip207_fluec.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // uint8_t, uint32_t,
+ // IDENTIFIER_NOT_USED
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_FLUEC_Invalidate
+ */
+void
+EIP207_FLUEC_Invalidate(
+ const Device_Handle_t Device,
+ const uint8_t InvTable,
+ const uint32_t FlowID_W0,
+ const uint32_t FlowID_W1,
+ const uint32_t FlowID_W2,
+ const uint32_t FlowID_W3)
+{
+ // Not implemented
+ IDENTIFIER_NOT_USED(Device);
+ IDENTIFIER_NOT_USED(InvTable);
+ IDENTIFIER_NOT_USED(FlowID_W0);
+ IDENTIFIER_NOT_USED(FlowID_W1);
+ IDENTIFIER_NOT_USED(FlowID_W2);
+ IDENTIFIER_NOT_USED(FlowID_W3);
+}
+
+
+/* end of file eip207_fluec.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_global_init.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_global_init.c
new file mode 100644
index 0000000..41586a8
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_global_init.c
@@ -0,0 +1,690 @@
+/* eip207_global_init.c
+ *
+ * EIP-207 Global Control Driver Library
+ * Initialization and status retrieval Module
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207 Global Control API
+#include "eip207_global_init.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // uint32_t
+
+// Driver Framework C Run-time Library API
+#include "clib.h" // ZEROINIT
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+
+// EIP-207s Record Cache (RC) internal interface
+#include "eip207_rc_internal.h"
+
+// EIP-207c Input Classification Engine (ICE) interface
+#include "eip207_ice.h"
+
+// EIP-207c Output Classification Engine (OCE) interface
+#include "eip207_oce.h"
+
+// EIP-207s Flow Look-Up Engine (FLUE) interface
+#include "eip207_flue.h"
+
+// EIP-207 Global Control Driver Library Internal interfaces
+#include "eip207_level0.h" // EIP-207 Level 0 macros
+
+// EIP-207s Flow Look-Up Engine Cache (FLUEC) Level0 interface
+#include "eip207_fluec_level0.h"
+
+// EIP-207c Firmware Classification API
+#include "firmware_eip207_api_cs.h" // Classification API: General
+
+// EIP-207c Firmware Download API
+#include "firmware_eip207_api_dwld.h" // Classification API: FW download
+
+// EIP97 Global init API
+#include "eip97_global_init.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Maximum number of EIP-207c Classification Engines that should be used
+// Should not exceed the number of engines physically available
+#ifndef EIP207_GLOBAL_MAX_NOF_CE_TO_USE
+#error "EIP207_GLOBAL_MAX_NOF_CE_TO_USE is not defined"
+#endif
+
+// Maximum number of flow hash tables that should be used
+#ifndef EIP207_MAX_NOF_FLOW_HASH_TABLES_TO_USE
+#error "EIP207_MAX_NOF_FLOW_HASH_TABLES_TO_USE is not defined"
+#endif
+
+// Default Classification Engine number
+#define CE_DEFAULT_NR 0
+
+#if (CE_DEFAULT_NR >= EIP207_GLOBAL_MAX_NOF_CE_TO_USE)
+#error "Error: CE_DEFAULT_NR must be less than EIP207_GLOBAL_MAX_NOF_CE_TO_USE"
+#endif
+
+// Size of the ARC4 State Record in 32-bit words
+#define EIP207_CS_ARC4RC_RECORD_WORD_COUNT 64
+
+#ifndef FIRMWARE_EIP207_CS_ARC4RC_RECORD_WORD_COUNT
+#define FIRMWARE_EIP207_CS_ARC4RC_RECORD_WORD_COUNT 64
+#endif
+
+// I/O Area, used internally
+typedef struct
+{
+ Device_Handle_t Device;
+ uint32_t State;
+} EIP207_True_IOArea_t;
+
+#define IOAREA(_p) ((volatile EIP207_True_IOArea_t *)_p)
+
+#ifdef EIP207_GLOBAL_STRICT_ARGS
+#define EIP207_GLOBAL_CHECK_POINTER(_p) \
+ if (NULL == (_p)) \
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+#define EIP207_GLOBAL_CHECK_INT_INRANGE(_i, _min, _max) \
+ if ((_i) < (_min) || (_i) > (_max)) \
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+#define EIP207_GLOBAL_CHECK_INT_ATLEAST(_i, _min) \
+ if ((_i) < (_min)) \
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+#define EIP207_GLOBAL_CHECK_INT_ATMOST(_i, _max) \
+ if ((_i) > (_max)) \
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+#else
+/* EIP207_GLOBAL_STRICT_ARGS undefined */
+#define EIP207_GLOBAL_CHECK_POINTER(_p)
+#define EIP207_GLOBAL_CHECK_INT_INRANGE(_i, _min, _max)
+#define EIP207_GLOBAL_CHECK_INT_ATLEAST(_i, _min)
+#define EIP207_GLOBAL_CHECK_INT_ATMOST(_i, _max)
+#endif /*end of EIP207_GLOBAL_STRICT_ARGS */
+
+#define TEST_SIZEOF(type, size) \
+ extern int size##_must_bigger[1 - 2*((int)(sizeof(type) > size))]
+
+// validate the size of the fake and real IOArea structures
+TEST_SIZEOF(EIP207_True_IOArea_t, EIP207_GLOBAL_IOAREA_REQUIRED_SIZE);
+
+#ifdef EIP207_GLOBAL_DEBUG_FSM
+// EIP-207 Global Control API States
+typedef enum
+{
+ EIP207_GLOBAL_STATE_INITIALIZED = 5,
+ EIP207_GLOBAL_STATE_FATAL_ERROR = 7,
+ EIP207_GLOBAL_STATE_RC_ENABLED = 8,
+ EIP207_GLOBAL_STATE_FW_LOADED = 9
+} EIP207_Global_State_t;
+#endif // EIP207_GLOBAL_DEBUG_FSM
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Detect
+ *
+ * Checks the presence of EIP-207 hardware. Returns true when found.
+ */
+static bool
+EIP207Lib_Detect(
+ const Device_Handle_t Device,
+ const unsigned int CEnr)
+{
+ uint32_t Value;
+
+ IDENTIFIER_NOT_USED(CEnr);
+
+ Value = EIP207_Read32(Device, EIP207_CS_REG_VERSION);
+ if (!EIP207_CS_SIGNATURE_MATCH( Value ))
+ return false;
+
+ return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_HWRevision_Get
+ */
+static void
+EIP207Lib_HWRevision_Get(
+ const Device_Handle_t Device,
+ EIP207_Options_t * const Options_p,
+ EIP207_Version_t * const Version_p)
+{
+ EIP207_CS_VERSION_RD(
+ Device,
+ &Version_p->EipNumber,
+ &Version_p->ComplmtEipNumber,
+ &Version_p->HWPatchLevel,
+ &Version_p->MinHWRevision,
+ &Version_p->MajHWRevision);
+
+ EIP207_CS_OPTIONS_RD(Device,
+ &Options_p->NofLookupTables,
+ &Options_p->fLookupCached,
+ &Options_p->NofLookupClients,
+ &Options_p->fCombinedTRC_ARC4,
+ &Options_p->fCombinedFRC_ARC4,
+ &Options_p->fARC4Present,
+ &Options_p->NofARC4_Clients,
+ &Options_p->fCombinedFRC_TRC,
+ &Options_p->NofTRC_Clients,
+ &Options_p->NofFRC_Clients,
+ &Options_p->NofCacheSets);
+}
+
+
+#ifdef EIP207_GLOBAL_DEBUG_FSM
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Global_State_Set
+ *
+ */
+static EIP207_Global_Error_t
+EIP207Lib_Global_State_Set(
+ EIP207_Global_State_t * const CurrentState,
+ const EIP207_Global_State_t NewState)
+{
+ switch(*CurrentState)
+ {
+ case EIP207_GLOBAL_STATE_INITIALIZED:
+ switch(NewState)
+ {
+ case EIP207_GLOBAL_STATE_RC_ENABLED:
+ *CurrentState = NewState;
+ break;
+ case EIP207_GLOBAL_STATE_FATAL_ERROR:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP207_GLOBAL_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP207_GLOBAL_STATE_RC_ENABLED:
+ switch(NewState)
+ {
+ case EIP207_GLOBAL_STATE_FW_LOADED:
+ *CurrentState = NewState;
+ break;
+ case EIP207_GLOBAL_STATE_FATAL_ERROR:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP207_GLOBAL_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ default:
+ return EIP207_GLOBAL_ILLEGAL_IN_STATE;
+ }
+
+ return EIP207_GLOBAL_NO_ERROR;
+}
+#endif // EIP207_GLOBAL_DEBUG_FSM
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_Init
+ */
+EIP207_Global_Error_t
+EIP207_Global_Init(
+ EIP207_Global_IOArea_t * const IOArea_p,
+ const Device_Handle_t Device,
+ EIP207_Global_CacheConfig_t * const CacheConf_p,
+ const EIP207_Global_FLUEConfig_t * const FLUEConf_p)
+{
+ unsigned int FLUE_NofLookupTables;
+ EIP207_Global_Capabilities_t Capabilities;
+ volatile EIP207_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+ unsigned int i;
+
+ EIP207_GLOBAL_CHECK_POINTER(IOArea_p);
+ EIP207_GLOBAL_CHECK_POINTER(CacheConf_p);
+ EIP207_GLOBAL_CHECK_POINTER(FLUEConf_p);
+
+ // Detect presence of EIP-207 HW hardware
+ if (!EIP207Lib_Detect(Device, CE_DEFAULT_NR))
+ return EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR;
+
+ // Initialize the IO Area
+ TrueIOArea_p->Device = Device;
+
+#ifdef EIP207_GLOBAL_DEBUG_FSM
+ TrueIOArea_p->State = (uint32_t)EIP207_GLOBAL_STATE_INITIALIZED;
+#endif // EIP207_GLOBAL_DEBUG_FSM
+
+ ZEROINIT(Capabilities);
+
+ EIP207Lib_HWRevision_Get(Device,
+ &Capabilities.EIP207_Options,
+ &Capabilities.EIP207_Version);
+
+ FLUE_NofLookupTables = Capabilities.EIP207_Options.NofLookupTables;
+
+ // 0 hash tables has a special meaning for the EIP-207 FLUE HW
+ if (FLUE_NofLookupTables == 0)
+ FLUE_NofLookupTables = EIP207_GLOBAL_MAX_HW_NOF_FLOW_HASH_TABLES;
+
+ // Check actual configuration HW against capabilities
+ // Number of configured cache sets and hash tables
+ if ((Capabilities.EIP207_Options.NofCacheSets <
+ EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE) ||
+ (FLUE_NofLookupTables <
+ EIP207_MAX_NOF_FLOW_HASH_TABLES_TO_USE) ||
+ (FLUEConf_p->HashTablesCount >
+ EIP207_MAX_NOF_FLOW_HASH_TABLES_TO_USE))
+ return EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR;
+
+ // Configure EIP-207 Classification Engine
+
+ // Initialize Record Caches
+ {
+ EIP207_Global_Error_t rv;
+
+ // Initialize Flow Record Cache
+#ifndef EIP207_GLOBAL_FRC_DISABLE
+ if ((EIP97_SupportedFuncs_Get() & BIT_3) != 0)
+ {
+ for (i=0; i < EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE; i++)
+ {
+ CacheConf_p->FRC[i].DataWordCount = EIP207_FRC_RAM_WORD_COUNT;
+ CacheConf_p->FRC[i].AdminWordCount =
+ EIP207_FRC_ADMIN_RAM_WORD_COUNT;
+ }
+
+ rv = EIP207_RC_Internal_Init(
+ Device,
+ EIP207_RC_INTERNAL_NOT_COMBINED,
+ EIP207_FRC_REG_BASE,
+ CacheConf_p->FRC,
+ FIRMWARE_EIP207_CS_FRC_RECORD_WORD_COUNT);
+ if (rv != EIP207_GLOBAL_NO_ERROR)
+ return rv;
+ }
+#endif // EIP207_GLOBAL_FRC_DISABLE
+ for (i=0; i < EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE; i++)
+ {
+ CacheConf_p->TRC[i].DataWordCount = EIP207_TRC_RAM_WORD_COUNT;
+ CacheConf_p->TRC[i].AdminWordCount =
+ EIP207_TRC_ADMIN_RAM_WORD_COUNT;
+ }
+
+ // Initialize Transform Record Cache
+ rv = EIP207_RC_Internal_Init(
+ Device,
+ Capabilities.EIP207_Options.fCombinedFRC_TRC ?
+ EIP207_RC_INTERNAL_FRC_TRC_COMBINED :
+ EIP207_RC_INTERNAL_NOT_COMBINED,
+ EIP207_TRC_REG_BASE,
+ CacheConf_p->TRC,
+ FIRMWARE_EIP207_CS_TRC_RECORD_WORD_COUNT);
+ if (rv != EIP207_GLOBAL_NO_ERROR)
+ return rv;
+
+ // Check if ARC4 Record Cache is available
+ if ( Capabilities.EIP207_Options.fARC4Present )
+ {
+ for (i=0; i < EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE; i++)
+ {
+ CacheConf_p->ARC4[i].DataWordCount =
+ EIP207_ARC4RC_RAM_WORD_COUNT;
+ CacheConf_p->ARC4[i].AdminWordCount =
+ EIP207_ARC4RC_ADMIN_RAM_WORD_COUNT;
+ }
+ // Initialize ARC4 Record Cache
+ rv = EIP207_RC_Internal_Init(
+ Device,
+ Capabilities.EIP207_Options.fCombinedFRC_ARC4 ?
+ EIP207_RC_INTERNAL_FRC_ARC4_COMBINED :
+ (Capabilities.EIP207_Options.fCombinedTRC_ARC4 ?
+ EIP207_RC_INTERNAL_TRC_ARC4_COMBINED :
+ EIP207_RC_INTERNAL_NOT_COMBINED),
+ EIP207_ARC4RC_REG_BASE,
+ CacheConf_p->ARC4,
+ FIRMWARE_EIP207_CS_ARC4RC_RECORD_WORD_COUNT);
+ if (rv != EIP207_GLOBAL_NO_ERROR)
+ return rv;
+ }
+ }
+
+ // Initialize Flow Hash Engine, set IV values
+ EIP207_FHASH_IV_WR(Device,
+ FLUEConf_p->IV.IV_Word32[0],
+ FLUEConf_p->IV.IV_Word32[1],
+ FLUEConf_p->IV.IV_Word32[2],
+ FLUEConf_p->IV.IV_Word32[3]);
+
+ // Initialize FLUE Hash Tables
+ {
+ unsigned int i;
+
+ for (i = 0; i < FLUEConf_p->HashTablesCount; i++)
+ EIP207_FLUE_Init(Device,
+ i,
+ FLUEConf_p,
+ Capabilities.EIP207_Options.fARC4Present,
+ Capabilities.EIP207_Options.fLookupCached);
+ }
+
+ // Initialize optional FLUE Cache
+ if (Capabilities.EIP207_Options.fLookupCached)
+ {
+ EIP207_FLUEC_CTRL_WR(Device,
+ false, // Disable cache RAM access
+ FLUEConf_p->fDelayMemXS,
+ EIP207_FLUEC_TABLE_SIZE,
+ EIP207_FLUEC_GROUP_SIZE,
+ FLUEConf_p->CacheChain); // Cache chain
+ }
+
+#ifdef EIP207_GLOBAL_DEBUG_FSM
+ {
+ EIP207_Global_Error_t rv;
+ uint32_t State = TrueIOArea_p->State;
+
+ // Transit to a new state
+ rv = EIP207Lib_Global_State_Set(
+ (EIP207_Global_State_t* const)&State,
+ EIP207_GLOBAL_STATE_RC_ENABLED);
+
+ TrueIOArea_p->State = State;
+
+ if (rv != EIP207_GLOBAL_NO_ERROR)
+ return EIP207_GLOBAL_ILLEGAL_IN_STATE;
+ }
+#endif // EIP207_GLOBAL_DEBUG_FSM
+
+ return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_Firmware_Load
+ */
+EIP207_Global_Error_t
+EIP207_Global_Firmware_Load(
+ EIP207_Global_IOArea_t * const IOArea_p,
+ const unsigned int TimerPrescaler,
+ EIP207_Firmware_t * const IPUE_Firmware_p,
+ EIP207_Firmware_t * const IFPP_Firmware_p,
+ EIP207_Firmware_t * const OPUE_Firmware_p,
+ EIP207_Firmware_t * const OFPP_Firmware_p)
+{
+ EIP207_Global_Error_t EIP207_Rc;
+ Device_Handle_t Device;
+ volatile EIP207_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP207_GLOBAL_CHECK_POINTER(IOArea_p);
+
+ Device = TrueIOArea_p->Device;
+
+ // Download EIP-207c Input Classification Engine (ICE) firmware,
+ // use the same images for all the instances of the engine
+ EIP207_Rc = EIP207_ICE_Firmware_Load(Device,
+ TimerPrescaler,
+ IPUE_Firmware_p,
+ IFPP_Firmware_p);
+ if (EIP207_Rc != EIP207_GLOBAL_NO_ERROR)
+ return EIP207_Rc;
+
+ // Download EIP-207c Output Classification Engine (OCE) firmware,
+ // use the same images for all the instances of the engine
+ // Download Input Classification Engine (OCE) firmware
+ EIP207_Rc = EIP207_OCE_Firmware_Load(Device,
+ TimerPrescaler,
+ OPUE_Firmware_p,
+ OFPP_Firmware_p);
+ // OCE is not supported by this EIP-207 HW version
+ if (EIP207_Rc != EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR &&
+ EIP207_Rc != EIP207_GLOBAL_NO_ERROR) // OCE is supported
+ return EIP207_Rc; // OCE FW download error, abort!
+
+#ifdef EIP207_GLOBAL_DEBUG_FSM
+ {
+ EIP207_Global_Error_t rv;
+ uint32_t State = TrueIOArea_p->State;
+
+ // Transit to a new state
+ rv = EIP207Lib_Global_State_Set(
+ (EIP207_Global_State_t* const)&State,
+ EIP207_GLOBAL_STATE_FW_LOADED);
+
+ TrueIOArea_p->State = State;
+
+ if (rv != EIP207_GLOBAL_NO_ERROR)
+ return EIP207_GLOBAL_ILLEGAL_IN_STATE;
+ }
+#endif // EIP207_GLOBAL_DEBUG_FSM
+
+ return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_HWRevision_Get
+ */
+EIP207_Global_Error_t
+EIP207_Global_HWRevision_Get(
+ EIP207_Global_IOArea_t * const IOArea_p,
+ EIP207_Global_Capabilities_t * const Capabilities_p)
+{
+ Device_Handle_t Device;
+ volatile EIP207_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP207_GLOBAL_CHECK_POINTER(IOArea_p);
+ EIP207_GLOBAL_CHECK_POINTER(Capabilities_p);
+
+ Device = TrueIOArea_p->Device;
+
+ EIP207Lib_HWRevision_Get(Device,
+ &Capabilities_p->EIP207_Options,
+ &Capabilities_p->EIP207_Version);
+
+ return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_GlobalStats_Get
+ */
+EIP207_Global_Error_t
+EIP207_Global_GlobalStats_Get(
+ EIP207_Global_IOArea_t * const IOArea_p,
+ const unsigned int CE_Number,
+ EIP207_Global_GlobalStats_t * const GlobalStats_p)
+{
+ Device_Handle_t Device;
+ EIP207_Global_Error_t rv;
+ volatile EIP207_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP207_GLOBAL_CHECK_POINTER(IOArea_p);
+ EIP207_GLOBAL_CHECK_POINTER(GlobalStats_p);
+
+ if(CE_Number >= EIP207_GLOBAL_MAX_NOF_CE_TO_USE)
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+ Device = TrueIOArea_p->Device;
+
+ rv = EIP207_ICE_GlobalStats_Get(Device, CE_Number, &GlobalStats_p->ICE);
+ if (rv != EIP207_GLOBAL_NO_ERROR)
+ return rv;
+
+ rv = EIP207_OCE_GlobalStats_Get(Device, CE_Number, &GlobalStats_p->OCE);
+ if (rv == EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR)
+ return EIP207_GLOBAL_NO_ERROR; // OCE is not supported
+ else // by this EIP-207 HW version
+ return rv;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_ClockCount_Get
+ */
+EIP207_Global_Error_t
+EIP207_Global_ClockCount_Get(
+ EIP207_Global_IOArea_t * const IOArea_p,
+ const unsigned int CE_Number,
+ EIP207_Global_Clock_t * const Clock_p)
+{
+ Device_Handle_t Device;
+ EIP207_Global_Error_t rv;
+ volatile EIP207_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP207_GLOBAL_CHECK_POINTER(IOArea_p);
+ EIP207_GLOBAL_CHECK_POINTER(Clock_p);
+
+ if(CE_Number >= EIP207_GLOBAL_MAX_NOF_CE_TO_USE)
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+ Device = TrueIOArea_p->Device;
+
+ rv = EIP207_ICE_ClockCount_Get(Device, CE_Number, &Clock_p->ICE);
+ if (rv != EIP207_GLOBAL_NO_ERROR)
+ return rv;
+
+ rv = EIP207_OCE_ClockCount_Get(Device, CE_Number, &Clock_p->OCE);
+ if (rv == EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR)
+ return EIP207_GLOBAL_NO_ERROR; // OCE is not supported
+ else // by this EIP-207 HW version
+ return rv;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * EIP207_Global_Status_Get
+ */
+EIP207_Global_Error_t
+EIP207_Global_Status_Get(
+ EIP207_Global_IOArea_t * const IOArea_p,
+ const unsigned int CE_Number,
+ EIP207_Global_Status_t * const Status_p,
+ bool * const fFatalError_p)
+{
+ unsigned int i;
+ Device_Handle_t Device;
+ EIP207_Global_Error_t rv;
+ bool fFatalError = false;
+ volatile EIP207_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP207_GLOBAL_CHECK_POINTER(IOArea_p);
+ EIP207_GLOBAL_CHECK_POINTER(Status_p);
+ EIP207_GLOBAL_CHECK_POINTER(fFatalError_p);
+
+ if(CE_Number >= EIP207_GLOBAL_MAX_NOF_CE_TO_USE)
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+ Device = TrueIOArea_p->Device;
+
+ rv = EIP207_ICE_Status_Get(Device, CE_Number, &Status_p->ICE);
+ if (rv != EIP207_GLOBAL_NO_ERROR)
+ return rv;
+
+ rv = EIP207_OCE_Status_Get(Device, CE_Number, &Status_p->OCE);
+ if (rv != EIP207_GLOBAL_NO_ERROR &&
+ rv != EIP207_GLOBAL_UNSUPPORTED_FEATURE_ERROR)
+ return rv;
+
+ EIP207_FLUE_Status_Get(Device, &Status_p->FLUE);
+
+ if (Status_p->ICE.fPUE_EccDerr ||
+ Status_p->ICE.fFPP_EccDerr ||
+ Status_p->OCE.fPUE_EccDerr ||
+ Status_p->OCE.fFPP_EccDerr ||
+ Status_p->ICE.fTimerOverflow ||
+ Status_p->OCE.fTimerOverflow ||
+ Status_p->FLUE.Error1 != 0 ||
+ Status_p->FLUE.Error2 != 0)
+ fFatalError = true;
+
+ for (i = 0; i < EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE; i++)
+ {
+ EIP207_RC_Internal_Status_Get(Device,
+ i,
+ &Status_p->FRC[i],
+ &Status_p->TRC[i],
+ &Status_p->ARC4RC[i]);
+ if (Status_p->FRC[i].fDMAReadError ||
+ Status_p->FRC[i].fDMAWriteError ||
+ Status_p->FRC[i].fAdminEccErr ||
+ Status_p->FRC[i].fDataEccOflo ||
+ Status_p->TRC[i].fDMAReadError ||
+ Status_p->TRC[i].fDMAWriteError ||
+ Status_p->TRC[i].fAdminEccErr ||
+ Status_p->TRC[i].fDataEccOflo ||
+ Status_p->ARC4RC[i].fDMAReadError ||
+ Status_p->ARC4RC[i].fDMAWriteError ||
+ Status_p->ARC4RC[i].fAdminEccErr ||
+ Status_p->ARC4RC[i].fDataEccOflo)
+ fFatalError = true;
+
+ EIP207_RC_Internal_DebugStatistics_Get(Device,
+ i,
+ &Status_p->FRCStats[i],
+ &Status_p->TRCStats[i]);
+ }
+
+ *fFatalError_p = fFatalError;
+
+#ifdef EIP207_GLOBAL_DEBUG_FSM
+ if (fFatalError)
+ {
+ uint32_t State = TrueIOArea_p->State;
+
+ // Transit to a new state
+ rv = EIP207Lib_Global_State_Set(
+ (EIP207_Global_State_t* const)&State,
+ EIP207_GLOBAL_STATE_FATAL_ERROR);
+
+ TrueIOArea_p->State = State;
+
+ if (rv != EIP207_GLOBAL_NO_ERROR)
+ return EIP207_GLOBAL_ILLEGAL_IN_STATE;
+ }
+#endif // EIP207_GLOBAL_DEBUG_FSM
+
+ return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/* end of file eip207_global_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_ice.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_ice.c
new file mode 100644
index 0000000..9f2e019
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_ice.c
@@ -0,0 +1,572 @@
+/* eip207_ice.c
+ *
+ * EIP-207c Input Classification Engine (ICE) interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207c Input Classification Engine (ICE) interface
+#include "eip207_ice.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // uint32_t, bool
+
+// EIP-207 Global Control Driver Library Internal interfaces
+#include "eip207_level0.h" // EIP-207 Level 0 macros
+
+// EIP-207 HW interface
+#include "eip207_hw_interface.h"
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+#include "device_rw.h" // Read32, Write32
+
+// EIP-207 Firmware Classification API
+#include "firmware_eip207_api_cs.h" // Classification API: General
+
+// EIP-207 Firmware Download API
+#include "firmware_eip207_api_dwld.h" // Classification API: FW download
+
+// EIP-207 Support API
+#include "eip207_support.h"
+
+// EIP97_Interfaces_Get()
+#include "eip97_global_internal.h"
+
+#include "clib.h" // memcmp
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Allow legacy firmware to be used, which does not have these constants.
+#ifndef FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT
+#define FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT FIRMWARE_EIP207_DWLD_ADMIN_RAM_LAST_BYTE_COUNT
+#endif
+#ifndef FIRMWARE_EIP207_CS_ADMIN_RAM_INPUT_LAST_BYTE_COUNT
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_INPUT_LAST_BYTE_COUNT FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT
+#endif
+
+// Number fo words to check when reading firmware back.
+#define EIP207_FW_CHECK_WORD_COUNT 16
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_ICE_Firmware_Load
+ */
+EIP207_Global_Error_t
+EIP207_ICE_Firmware_Load(
+ const Device_Handle_t Device,
+ const unsigned int TimerPrescaler,
+ EIP207_Firmware_t * const PUE_Firmware_p,
+ EIP207_Firmware_t * const FPP_Firmware_p)
+{
+ unsigned int NofCEs;
+ EIP97_Interfaces_Get(&NofCEs,NULL,NULL,NULL);
+ // Check if the Adapter provides the IPUE firmware image with correct size.
+ if (!PUE_Firmware_p->Image_p ||
+ PUE_Firmware_p->ImageWordCount > EIP207_IPUE_PROG_RAM_WORD_COUNT)
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+ // Check if the Adapter provides the IFPP firmware image with correct size.
+ if (!FPP_Firmware_p->Image_p ||
+ FPP_Firmware_p->ImageWordCount > EIP207_IPUE_PROG_RAM_WORD_COUNT)
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+
+ // Clear EIP-207c ICE Scratchpad RAM where the the firmware
+ // administration data will be located
+ {
+ unsigned int i, CECount, BlockCount, RequiredRAMByteCount;
+
+ RequiredRAMByteCount =
+ MAX(FIRMWARE_EIP207_CS_ADMIN_RAM_INPUT_LAST_BYTE_COUNT,
+ FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT);
+
+ // Check if the administration RAM required by the EIP-207 firmware
+ // fits into physically available scratchpad RAM
+ if ((EIP207_ICE_SCRATCH_RAM_128B_BLOCK_COUNT * 128) <
+ RequiredRAMByteCount)
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+ // Calculate how many 128-byte blocks are required for the firmware
+ // administration data
+ BlockCount = (RequiredRAMByteCount + 127) / 128;
+
+ for (CECount = 0; CECount < NofCEs; CECount++)
+ {
+ // Make ICE Scratchpad RAM accessible and set the timer
+ EIP207_ICE_SCRATCH_CTRL_WR(
+ Device,
+ CECount,
+ true, // Change timer
+ true, // Enable timer
+ (uint16_t)TimerPrescaler,
+ EIP207_ICE_SCRATCH_TIMER_OFLO_BIT, // Timer overflow bit
+ true, // Change access
+ (uint8_t)BlockCount);
+
+#ifdef DEBUG
+ // Check if the timer runs
+ {
+ uint32_t Value32;
+ unsigned int i;
+
+ for (i = 0; i < 10; i++)
+ {
+ Value32 = Device_Read32(Device,
+ EIP207_ICE_REG_TIMER_LO(CECount));
+
+ if (Value32 == 0)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+ }
+ }
+#endif
+
+ // Write the ICE Scratchpad RAM with 0
+ for(i = 0; i < (BlockCount * 32); i++)
+ {
+ Device_Write32(Device,
+ EIP207_ICE_REG_SCRATCH_RAM(CECount) +
+ i * sizeof(uint32_t),
+ 0);
+#ifdef DEBUG
+ // Perform read-back check
+ {
+ uint32_t Value32 =
+ Device_Read32(
+ Device,
+ EIP207_ICE_REG_SCRATCH_RAM(CECount) +
+ i * sizeof(uint32_t));
+
+ if (Value32 != 0)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+ }
+#endif
+ }
+ }
+
+ // Leave the scratchpad RAM accessible for the Host
+ }
+
+ // Download the firmware
+ {
+ unsigned int CECount;
+#ifdef DEBUG
+ unsigned int i;
+#endif
+ for (CECount = 0; CECount < NofCEs; CECount++)
+ {
+ // Reset the Input Flow Post-Processor micro-engine (IFPP) to make its
+ // Program RAM accessible
+ EIP207_ICE_FPP_CTRL_WR(Device,
+ CECount,
+ 0, // No start address for debug mode
+ 1, // Clear ECC correctable error
+ 1, // Clear ECC non-correctable error
+ false, // Debug mode OFF
+ true); // SW Reset ON
+
+ // Enable access to IFPP Program RAM
+ EIP207_ICE_RAM_CTRL_WR(Device, CECount, false, true);
+ }
+
+#ifdef DEBUG
+ // Write the Input Flow post-Processor micro-Engine firmware
+ for(i = 0; i < FPP_Firmware_p->ImageWordCount; i++)
+ {
+ Device_Write32(Device,
+ EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t),
+ FPP_Firmware_p->Image_p[i]);
+ // Perform read-back check
+ {
+ uint32_t Value32 =
+ Device_Read32(
+ Device,
+ EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t));
+
+ if (Value32 != FPP_Firmware_p->Image_p[i])
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+ }
+ }
+#else
+ Device_Write32Array(Device,
+ EIP207_CS_RAM_XS_SPACE_BASE,
+ FPP_Firmware_p->Image_p,
+ FPP_Firmware_p->ImageWordCount);
+ // Perform read-back check of small subset
+ {
+ static uint32_t ReadBuf[EIP207_FW_CHECK_WORD_COUNT];
+ Device_Read32Array(Device,
+ EIP207_CS_RAM_XS_SPACE_BASE,
+ ReadBuf,
+ EIP207_FW_CHECK_WORD_COUNT);
+ if (memcmp(ReadBuf,
+ FPP_Firmware_p->Image_p,
+ EIP207_FW_CHECK_WORD_COUNT * sizeof(uint32_t)) != 0)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+
+ }
+#endif
+
+ for (CECount = 0; CECount < NofCEs; CECount++)
+ {
+ // Disable access to IFPP Program RAM
+ // Enable access to IPUE Program RAM
+ EIP207_ICE_RAM_CTRL_WR(Device, CECount, true, false);
+
+ // Reset the Input Pull-Up micro-Engine (IPUE) to make its
+ // Program RAM accessible
+ EIP207_ICE_PUE_CTRL_WR(Device,
+ CECount,
+ 0, // No start address for debug mode
+ 1, // Clear ECC correctable error
+ 1, // Clear ECC non-correctable error
+ false, // Debug mode OFF
+ true); // SW Reset ON
+ }
+
+#ifdef DEBUG
+ // Write the Input Pull-Up micro-Engine firmware
+ for(i = 0; i < PUE_Firmware_p->ImageWordCount; i++)
+ {
+ Device_Write32(Device,
+ EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t),
+ PUE_Firmware_p->Image_p[i]);
+ // Perform read-back check
+ {
+ uint32_t Value32 =
+ Device_Read32(
+ Device,
+ EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t));
+
+ if (Value32 != PUE_Firmware_p->Image_p[i])
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+ }
+ }
+#else
+ Device_Write32Array(Device,
+ EIP207_CS_RAM_XS_SPACE_BASE,
+ PUE_Firmware_p->Image_p,
+ PUE_Firmware_p->ImageWordCount);
+ // Perform read-back check of small subset
+ {
+ static uint32_t ReadBuf[EIP207_FW_CHECK_WORD_COUNT];
+ Device_Read32Array(Device,
+ EIP207_CS_RAM_XS_SPACE_BASE,
+ ReadBuf,
+ EIP207_FW_CHECK_WORD_COUNT);
+ if (memcmp(ReadBuf,
+ PUE_Firmware_p->Image_p,
+ EIP207_FW_CHECK_WORD_COUNT * sizeof(uint32_t)) != 0)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+
+ }
+#endif
+
+ // Disable access to IPUE Program RAM
+ for (CECount = 0; CECount < NofCEs; CECount++)
+ EIP207_ICE_RAM_CTRL_WR(Device, CECount, false, false);
+
+#ifdef EIP207_GLOBAL_FIRMWARE_DOWNLOAD_VERSION_CHECK
+ // Check the firmware version and start all the engines
+ for (CECount = 0; CECount < NofCEs; CECount++)
+ {
+ uint32_t Value32;
+ unsigned int Ma, Mi, Pl, i;
+ bool fUpdated;
+
+ // Start the IFPP in Debug mode for the firmware version check
+ EIP207_ICE_FPP_CTRL_WR(
+ Device,
+ CECount,
+ FIRMWARE_EIP207_DWLD_IFPP_VERSION_CHECK_DBG_PROG_CNTR,
+ 1, // Clear ECC correctable error
+ 1, // Clear ECC non-correctable error
+ true, // Debug mode ON
+ false); // SW Reset OFF
+
+ // Wait for the IFPP version update
+ for (i = 0; i < EIP207_FW_VER_CHECK_MAX_NOF_READ_ATTEMPTS; i++)
+ {
+ Value32 = Device_Read32(
+ Device,
+ EIP207_ICE_REG_SCRATCH_RAM(CECount) +
+ FIRMWARE_EIP207_DWLD_ADMIN_RAM_IFPP_CTRL_BYTE_OFFSET);
+
+ FIRMWARE_EIP207_DWLD_IFPP_VersionUpdated_Read(Value32,
+ &fUpdated);
+
+ if (fUpdated)
+ break;
+ }
+
+ if (!fUpdated)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+
+ Value32 = Device_Read32(
+ Device,
+ EIP207_ICE_REG_SCRATCH_RAM(CECount) +
+ FIRMWARE_EIP207_DWLD_ADMIN_RAM_IFPP_VERSION_BYTE_OFFSET);
+
+ FIRMWARE_EIP207_DWLD_Version_Read(Value32, &Ma, &Mi, &Pl);
+
+ if (FPP_Firmware_p->Major == 0 &&
+ FPP_Firmware_p->Minor == 0 &&
+ FPP_Firmware_p->PatchLevel == 0)
+ { // Adapter did not provide expected version, return it.
+ FPP_Firmware_p->Major = Ma;
+ FPP_Firmware_p->Minor = Mi;
+ FPP_Firmware_p->PatchLevel = Pl;
+ }
+ else
+ {
+ // Adapter provided expected version, check it.
+ if (FPP_Firmware_p->Major != Ma ||
+ FPP_Firmware_p->Minor != Mi ||
+ FPP_Firmware_p->PatchLevel != Pl)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+ }
+
+ // Start the IPUE in Debug mode for the firmware version check
+ EIP207_ICE_PUE_CTRL_WR(
+ Device,
+ CECount,
+ FIRMWARE_EIP207_DWLD_IPUE_VERSION_CHECK_DBG_PROG_CNTR,
+ 1, // Clear ECC correctable error
+ 1, // Clear ECC non-correctable error
+ true, // Debug mode ON
+ false); // SW Reset OFF
+
+ // Wait for the IPUE version update
+ for (i = 0; i < EIP207_FW_VER_CHECK_MAX_NOF_READ_ATTEMPTS; i++)
+ {
+ Value32 = Device_Read32(
+ Device,
+ EIP207_ICE_REG_SCRATCH_RAM(CECount) +
+ FIRMWARE_EIP207_DWLD_ADMIN_RAM_IPUE_CTRL_BYTE_OFFSET);
+
+ FIRMWARE_EIP207_DWLD_IPUE_VersionUpdated_Read(Value32,
+ &fUpdated);
+
+ if (fUpdated)
+ break;
+ }
+
+ if (!fUpdated)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+
+ Value32 = Device_Read32(
+ Device,
+ EIP207_ICE_REG_SCRATCH_RAM(CECount) +
+ FIRMWARE_EIP207_DWLD_ADMIN_RAM_IPUE_VERSION_BYTE_OFFSET);
+
+ FIRMWARE_EIP207_DWLD_Version_Read(Value32, &Ma, &Mi, &Pl);
+
+ if (PUE_Firmware_p->Major == 0 &&
+ PUE_Firmware_p->Minor == 0 &&
+ PUE_Firmware_p->PatchLevel == 0)
+ { // Adapter did not provide expected version, return it.
+ PUE_Firmware_p->Major = Ma;
+ PUE_Firmware_p->Minor = Mi;
+ PUE_Firmware_p->PatchLevel = Pl;
+ }
+ else
+ {
+ // Adapter provided expected version, check it.
+ if (PUE_Firmware_p->Major != Ma ||
+ PUE_Firmware_p->Minor != Mi ||
+ PUE_Firmware_p->PatchLevel != Pl)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+ }
+ } // for
+#else
+ for (CECount = 0; CECount < NofCEs; CECount++)
+ {
+ // Start the IFPP in Debug mode
+ EIP207_ICE_FPP_CTRL_WR(
+ Device,
+ CECount,
+ FIRMWARE_EIP207_DWLD_IFPP_VERSION_CHECK_DBG_PROG_CNTR,
+ 1, // Clear ECC correctable error
+ 1, // Clear ECC non-correctable error
+ true, // Debug mode ON
+ false); // SW Reset OFF
+
+ // Start the IPUE in Debug mode
+ EIP207_ICE_PUE_CTRL_WR(
+ Device,
+ CECount,
+ FIRMWARE_EIP207_DWLD_IPUE_VERSION_CHECK_DBG_PROG_CNTR,
+ 1, // Clear ECC correctable error
+ 1, // Clear ECC non-correctable error
+ true, // Debug mode ON
+ false); // SW Reset OFF
+ } // for
+#endif // EIP207_GLOBAL_FIRMWARE_DOWNLOAD_VERSION_CHECK
+ for (CECount = 0; CECount < NofCEs; CECount++)
+ {
+ uint32_t InputBufferSize = Device_Read32(
+ Device,
+ EIP207_ICE_REG_SCRATCH_RAM(CECount) +
+ 4*33) & MASK_16_BITS;
+ if (InputBufferSize != 0)
+ {
+ if (PUE_Firmware_p->Major > 3 ||
+ (PUE_Firmware_p->Major ==3 &&
+ PUE_Firmware_p->Minor >=1))
+ {
+ InputBufferSize -= 2048;
+ }
+ else
+ {
+ InputBufferSize = (InputBufferSize * 3) / 4;
+ }
+ EIP207_ICE_ADAPT_CTRL_WR(Device, CECount, InputBufferSize);
+ }
+ EIP207_ICE_PUTF_CTRL_WR(Device, CECount, 3, false);
+ EIP207_ICE_PPTF_CTRL_WR(Device, CECount, 0, false);
+ }
+ }
+
+
+ return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_ICE_GlobalStats_Get
+ */
+EIP207_Global_Error_t
+EIP207_ICE_GlobalStats_Get(
+ const Device_Handle_t Device,
+ const unsigned int CE_Number,
+ EIP207_Global_ICE_GlobalStats_t * const ICE_GlobalStats_p)
+{
+ EIP207_Global_Error_t rv;
+
+ rv = EIP207_Global_Read64(
+ Device,
+ EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+ FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_DROP_LO_BYTE_OFFSET,
+ EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+ FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_DROP_HI_BYTE_OFFSET,
+ &ICE_GlobalStats_p->DroppedPacketsCounter);
+ if (rv != EIP207_GLOBAL_NO_ERROR)
+ return rv;
+
+ rv = EIP207_Global_Read64(
+ Device,
+ EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+ FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_IN_OCT_LO_BYTE_OFFSET,
+ EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+ FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_IN_OCT_HI_BYTE_OFFSET,
+ &ICE_GlobalStats_p->InboundOctetsCounter);
+ if (rv != EIP207_GLOBAL_NO_ERROR)
+ return rv;
+
+ rv = EIP207_Global_Read64(
+ Device,
+ EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+ FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_OUT_OCT_LO_BYTE_OFFSET,
+ EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+ FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_OUT_OCT_HI_BYTE_OFFSET,
+ &ICE_GlobalStats_p->OutboundOctetsCounter);
+ if (rv != EIP207_GLOBAL_NO_ERROR)
+ return rv;
+
+ ICE_GlobalStats_p->InboundPacketsCounter =
+ Device_Read32(Device,
+ EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+ FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_IN_PKT_BYTE_OFFSET);
+
+ ICE_GlobalStats_p->OutboundPacketCounter =
+ Device_Read32(Device,
+ EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+ FIRMWARE_EIP207_CS_ADMIN_RAM_STAT_OUT_PKT_BYTE_OFFSET);
+
+ return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_ICE_ClockCount_Get
+ */
+EIP207_Global_Error_t
+EIP207_ICE_ClockCount_Get(
+ const Device_Handle_t Device,
+ const unsigned int CE_Number,
+ EIP207_Global_Value64_t * const ICE_Clock_p)
+{
+ return EIP207_Global_Read64(
+ Device,
+ EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+ FIRMWARE_EIP207_CS_ADMIN_RAM_TIME_LO_BYTE_OFFSET,
+ EIP207_ICE_REG_SCRATCH_RAM(CE_Number) +
+ FIRMWARE_EIP207_CS_ADMIN_RAM_TIME_HI_BYTE_OFFSET,
+ ICE_Clock_p);
+}
+
+
+/*-----------------------------------------------------------------------------
+ * EIP207_ICE_Status_Get
+ */
+EIP207_Global_Error_t
+EIP207_ICE_Status_Get(
+ const Device_Handle_t Device,
+ const unsigned int CE_Number,
+ EIP207_Global_CE_Status_t * const ICE_Status_p)
+{
+ EIP207_ICE_PUE_CTRL_RD_CLEAR(Device,
+ CE_Number,
+ &ICE_Status_p->fPUE_EccCorr,
+ &ICE_Status_p->fPUE_EccDerr);
+
+ EIP207_ICE_FPP_CTRL_RD_CLEAR(Device,
+ CE_Number,
+ &ICE_Status_p->fFPP_EccCorr,
+ &ICE_Status_p->fFPP_EccDerr);
+
+ EIP207_ICE_SCRATCH_CTRL_RD(Device,
+ CE_Number,
+ &ICE_Status_p->fTimerOverflow);
+
+ return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/* end of file eip207_ice.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_oce.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_oce.c
new file mode 100644
index 0000000..7d29ed2
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_oce.c
@@ -0,0 +1,514 @@
+/* eip207_oce.c
+ *
+ * EIP-207c Output Classification Engine (OCE) interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207c Output Classification Engine (OCE) interface
+#include "eip207_oce.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // uint32_t, bool
+
+// Driver Framework C Run-Time Library Abstraction API
+#include "clib.h" // ZEROINIT
+
+// EIP-207 Global Control Driver Library Internal interfaces
+#include "eip207_level0.h" // EIP-207 Level 0 macros
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+#include "device_rw.h" // Read32, Write32
+
+// EIP-207 Firmware Classification API
+#include "firmware_eip207_api_cs.h" // Classification API: General
+
+// EIP-207 Firmware Download API
+#include "firmware_eip207_api_dwld.h" // Classification API: FW download
+
+// EIP97_Interfaces_Get()
+#include "eip97_global_internal.h"
+
+// EIP97 Global init API
+#include "eip97_global_init.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Allow legacy firmware to be used, which does not have these constants.
+#ifndef FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT
+#define FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT FIRMWARE_EIP207_DWLD_ADMIN_RAM_LAST_BYTE_COUNT
+#endif
+#ifndef FIRMWARE_EIP207_CS_ADMIN_RAM_INPUT_LAST_BYTE_COUNT
+#define FIRMWARE_EIP207_CS_ADMIN_RAM_INPUT_LAST_BYTE_COUNT FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT
+#endif
+
+// Number fo words to check when reading firmware back.
+#define EIP207_FW_CHECK_WORD_COUNT 16
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_OCE_Firmware_Load
+ */
+EIP207_Global_Error_t
+EIP207_OCE_Firmware_Load(
+ const Device_Handle_t Device,
+ const unsigned int TimerPrescaler,
+ EIP207_Firmware_t * const PUE_Firmware_p,
+ EIP207_Firmware_t * const FPP_Firmware_p)
+{
+ unsigned int NofCEs;
+
+ if ((EIP97_SupportedFuncs_Get() & BIT_1) != 0)
+ {
+ EIP97_Interfaces_Get(&NofCEs,NULL,NULL,NULL);
+ // Check if the Adapter provides the OPUE firmware image with correct size.
+ if (!PUE_Firmware_p->Image_p ||
+ PUE_Firmware_p->ImageWordCount > EIP207_OPUE_PROG_RAM_WORD_COUNT)
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+ // Check if the Adapter provides the OFPP firmware image with correct size.
+ if (!FPP_Firmware_p->Image_p ||
+ FPP_Firmware_p->ImageWordCount > EIP207_OPUE_PROG_RAM_WORD_COUNT)
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+
+ // Clear EIP-207c OCE Scratchpad RAM where the the firmware
+ // administration data will be located
+ {
+ unsigned int i, CECount, BlockCount, RequiredRAMByteCount;
+
+ RequiredRAMByteCount =
+ MAX(FIRMWARE_EIP207_CS_ADMIN_RAM_INPUT_LAST_BYTE_COUNT,
+ FIRMWARE_EIP207_DWLD_ADMIN_RAM_INPUT_LAST_BYTE_COUNT);
+
+ // Check if the administration RAM required by the EIP-207 firmware
+ // fits into physically available scratchpad RAM
+ if ((EIP207_OCE_SCRATCH_RAM_128B_BLOCK_COUNT * 128) <
+ RequiredRAMByteCount)
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+ // Calculate how many 128-byte blocks are required for the firmware
+ // administration data
+ BlockCount = (RequiredRAMByteCount + 127) / 128;
+
+ for (CECount = 0; CECount < NofCEs; CECount++)
+ {
+ // Make OCE Scratchpad RAM accessible and set the timer
+ EIP207_OCE_SCRATCH_CTRL_WR(
+ Device,
+ CECount,
+ true, // Change timer
+ true, // Enable timer
+ (uint16_t)TimerPrescaler,
+ EIP207_OCE_SCRATCH_TIMER_OFLO_BIT, // Timer overflow bit
+ true, // Change access
+ (uint8_t)BlockCount);
+
+#ifdef DEBUG
+ // Check if the timer runs
+ {
+ uint32_t Value32;
+ unsigned int i;
+
+ for (i = 0; i < 10; i++)
+ {
+ Value32 = Device_Read32(Device,
+ EIP207_OCE_REG_TIMER_LO(CECount));
+
+ if (Value32 == 0)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+ }
+ }
+#endif
+
+ // Write the OCE Scratchpad RAM with 0
+ for(i = 0; i < (BlockCount * 32); i++)
+ {
+ Device_Write32(Device,
+ EIP207_OCE_REG_SCRATCH_RAM(CECount) +
+ i * sizeof(uint32_t),
+ 0);
+#ifdef DEBUG
+ // Perform read-back check
+ {
+ uint32_t Value32 =
+ Device_Read32(
+ Device,
+ EIP207_OCE_REG_SCRATCH_RAM(CECount) +
+ i * sizeof(uint32_t));
+
+ if (Value32 != 0)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+ }
+#endif
+ }
+ }
+
+ // Leave the scratchpad RAM accessible for the Host
+ }
+
+ // Download the firmware
+ {
+ unsigned int CECount;
+#ifdef DEBUG
+ unsigned int i;
+#endif
+ for (CECount = 0; CECount < NofCEs; CECount++)
+ {
+ // Reset the Input Flow Post-Processor micro-engine (OFPP) to make its
+ // Program RAM accessible
+ EIP207_OCE_FPP_CTRL_WR(Device,
+ CECount,
+ 0, // No start address for debug mode
+ 1, // Clear ECC correctable error
+ 1, // Clear ECC non-correctable error
+ false, // Debug mode OFF
+ true); // SW Reset ON
+
+ // Enable access to OFPP Program RAM
+ EIP207_OCE_RAM_CTRL_WR(Device, CECount, false, true);
+ }
+
+#ifdef DEBUG
+ // Write the Input Flow post-Processor micro-Engine firmware
+ for(i = 0; i < FPP_Firmware_p->ImageWordCount; i++)
+ {
+ Device_Write32(Device,
+ EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t),
+ FPP_Firmware_p->Image_p[i]);
+ // Perform read-back check
+ {
+ uint32_t Value32 =
+ Device_Read32(
+ Device,
+ EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t));
+
+ if (Value32 != FPP_Firmware_p->Image_p[i])
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+ }
+ }
+#else
+ Device_Write32Array(Device,
+ EIP207_CS_RAM_XS_SPACE_BASE,
+ FPP_Firmware_p->Image_p,
+ FPP_Firmware_p->ImageWordCount);
+ // Perform read-back check of small subset
+ {
+ static uint32_t ReadBuf[EIP207_FW_CHECK_WORD_COUNT];
+ Device_Read32Array(Device,
+ EIP207_CS_RAM_XS_SPACE_BASE,
+ ReadBuf,
+ EIP207_FW_CHECK_WORD_COUNT);
+ if (memcmp(ReadBuf,
+ FPP_Firmware_p->Image_p,
+ EIP207_FW_CHECK_WORD_COUNT * sizeof(uint32_t)) != 0)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+
+ }
+#endif
+
+ for (CECount = 0; CECount < NofCEs; CECount++)
+ {
+ // Disable access to OFPP Program RAM
+ // Enable access to OPUE Program RAM
+ EIP207_OCE_RAM_CTRL_WR(Device, CECount, true, false);
+
+ // Reset the Input Pull-Up micro-Engine (OPUE) to make its
+ // Program RAM accessible
+ EIP207_OCE_PUE_CTRL_WR(Device,
+ CECount,
+ 0, // No start address for debug mode
+ 1, // Clear ECC correctable error
+ 1, // Clear ECC non-correctable error
+ false, // Debug mode OFF
+ true); // SW Reset ON
+ }
+
+#ifdef DEBUG
+ // Write the Input Pull-Up micro-Engine firmware
+ for(i = 0; i < PUE_Firmware_p->ImageWordCount; i++)
+ {
+ Device_Write32(Device,
+ EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t),
+ PUE_Firmware_p->Image_p[i]);
+ // Perform read-back check
+ {
+ uint32_t Value32 =
+ Device_Read32(
+ Device,
+ EIP207_CS_RAM_XS_SPACE_BASE + i * sizeof(uint32_t));
+
+ if (Value32 != PUE_Firmware_p->Image_p[i])
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+ }
+ }
+#else
+ Device_Write32Array(Device,
+ EIP207_CS_RAM_XS_SPACE_BASE,
+ PUE_Firmware_p->Image_p,
+ PUE_Firmware_p->ImageWordCount);
+ // Perform read-back check of small subset
+ {
+ static uint32_t ReadBuf[EIP207_FW_CHECK_WORD_COUNT];
+ Device_Read32Array(Device,
+ EIP207_CS_RAM_XS_SPACE_BASE,
+ ReadBuf,
+ EIP207_FW_CHECK_WORD_COUNT);
+ if (memcmp(ReadBuf,
+ PUE_Firmware_p->Image_p,
+ EIP207_FW_CHECK_WORD_COUNT * sizeof(uint32_t)) != 0)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+
+ }
+#endif
+
+ // Disable access to OPUE Program RAM
+ for (CECount = 0; CECount < EIP207_GLOBAL_MAX_NOF_CE_TO_USE; CECount++)
+ EIP207_OCE_RAM_CTRL_WR(Device, CECount, false, false);
+
+#ifdef EIP207_GLOBAL_FIRMWARE_DOWNLOAD_VERSION_CHECK
+ // Check the firmware version and start all the engines
+ for (CECount = 0; CECount < NofCEs; CECount++)
+ {
+ uint32_t Value32;
+ unsigned int Ma, Mi, Pl, i;
+ bool fUpdated;
+
+ // Start the OFPP in Debug mode for the firmware version check
+ EIP207_OCE_FPP_CTRL_WR(
+ Device,
+ CECount,
+ FIRMWARE_EIP207_DWLD_OFPP_VERSION_CHECK_DBG_PROG_CNTR,
+ 1, // Clear ECC correctable error
+ 1, // Clear ECC non-correctable error
+ true, // Debug mode ON
+ false); // SW Reset OFF
+
+ // Wait for the OFPP version update
+ for (i = 0; i < EIP207_FW_VER_CHECK_MAX_NOF_READ_ATTEMPTS; i++)
+ {
+ Value32 = Device_Read32(
+ Device,
+ EIP207_OCE_REG_SCRATCH_RAM(CECount) +
+ FIRMWARE_EIP207_DWLD_ADMIN_RAM_OFPP_CTRL_BYTE_OFFSET);
+
+ FIRMWARE_EIP207_DWLD_OFPP_VersionUpdated_Read(Value32,
+ &fUpdated);
+
+ if (fUpdated)
+ break;
+ }
+
+ if (!fUpdated)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+
+ Value32 = Device_Read32(
+ Device,
+ EIP207_OCE_REG_SCRATCH_RAM(CECount) +
+ FIRMWARE_EIP207_DWLD_ADMIN_RAM_OFPP_VERSION_BYTE_OFFSET);
+
+ FIRMWARE_EIP207_DWLD_Version_Read(Value32, &Ma, &Mi, &Pl);
+
+ if (FPP_Firmware_p->Major == 0 &&
+ FPP_Firmware_p->Minor == 0 &&
+ FPP_Firmware_p->PatchLevel == 0)
+ { // Adapter did not provide expected version, return it.
+ FPP_Firmware_p->Major = Ma;
+ FPP_Firmware_p->Minor = Mi;
+ FPP_Firmware_p->PatchLevel = Pl;
+ }
+ else
+ {
+ // Adapter provided expected version, check it.
+ if (FPP_Firmware_p->Major != Ma ||
+ FPP_Firmware_p->Minor != Mi ||
+ FPP_Firmware_p->PatchLevel != Pl)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+ }
+
+ // Start the OPUE in Debug mode for the firmware version check
+ EIP207_OCE_PUE_CTRL_WR(
+ Device,
+ CECount,
+ FIRMWARE_EIP207_DWLD_OPUE_VERSION_CHECK_DBG_PROG_CNTR,
+ 1, // Clear ECC correctable error
+ 1, // Clear ECC non-correctable error
+ true, // Debug mode ON
+ false); // SW Reset OFF
+
+ // Wait for the OPUE version update
+ for (i = 0; i < EIP207_FW_VER_CHECK_MAX_NOF_READ_ATTEMPTS; i++)
+ {
+ Value32 = Device_Read32(
+ Device,
+ EIP207_OCE_REG_SCRATCH_RAM(CECount) +
+ FIRMWARE_EIP207_DWLD_ADMIN_RAM_OPUE_CTRL_BYTE_OFFSET);
+
+ FIRMWARE_EIP207_DWLD_OPUE_VersionUpdated_Read(Value32,
+ &fUpdated);
+
+ if (fUpdated)
+ break;
+ }
+
+ if (!fUpdated)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+
+ Value32 = Device_Read32(
+ Device,
+ EIP207_OCE_REG_SCRATCH_RAM(CECount) +
+ FIRMWARE_EIP207_DWLD_ADMIN_RAM_OPUE_VERSION_BYTE_OFFSET);
+
+ FIRMWARE_EIP207_DWLD_Version_Read(Value32, &Ma, &Mi, &Pl);
+
+ if (PUE_Firmware_p->Major == 0 &&
+ PUE_Firmware_p->Minor == 0 &&
+ PUE_Firmware_p->PatchLevel == 0)
+ { // Adapter did not provide expected version, return it.
+ PUE_Firmware_p->Major = Ma;
+ PUE_Firmware_p->Minor = Mi;
+ PUE_Firmware_p->PatchLevel = Pl;
+ }
+ else
+ {
+ // Adapter provided expected version, check it.
+ if (PUE_Firmware_p->Major != Ma ||
+ PUE_Firmware_p->Minor != Mi ||
+ PUE_Firmware_p->PatchLevel != Pl)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+ }
+ } // for
+#else
+ for (CECount = 0; CECount < EIP207_GLOBAL_MAX_NOF_CE_TO_USE; CECount++)
+ {
+ // Start the OFPP in Debug mode
+ EIP207_OCE_FPP_CTRL_WR(
+ Device,
+ CECount,
+ FIRMWARE_EIP207_DWLD_OFPP_VERSION_CHECK_DBG_PROG_CNTR,
+ 1, // Clear ECC correctable error
+ 1, // Clear ECC non-correctable error
+ true, // Debug mode ON
+ false); // SW Reset OFF
+
+ // Start the OPUE in Debug mode
+ EIP207_OCE_PUE_CTRL_WR(
+ Device,
+ CECount,
+ FIRMWARE_EIP207_DWLD_OPUE_VERSION_CHECK_DBG_PROG_CNTR,
+ 1, // Clear ECC correctable error
+ 1, // Clear ECC non-correctable error
+ true, // Debug mode ON
+ false); // SW Reset OFF
+ } // for
+#endif // EIP207_GLOBAL_FIRMWARE_DOWNLOAD_VERSION_CHECK
+ }
+ }
+ return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_OCE_GlobalStats_Get
+ */
+EIP207_Global_Error_t
+EIP207_OCE_GlobalStats_Get(
+ const Device_Handle_t Device,
+ const unsigned int CE_Number,
+ EIP207_Global_OCE_GlobalStats_t * const OCE_GlobalStats_p)
+{
+ IDENTIFIER_NOT_USED(Device);
+ IDENTIFIER_NOT_USED(CE_Number);
+
+ // Not used / implemented yet
+ ZEROINIT(*OCE_GlobalStats_p);
+
+ return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_OCE_ClockCount_Get
+ */
+EIP207_Global_Error_t
+EIP207_OCE_ClockCount_Get(
+ const Device_Handle_t Device,
+ const unsigned int CE_Number,
+ EIP207_Global_Value64_t * const OCE_Clock_p)
+{
+ IDENTIFIER_NOT_USED(Device);
+ IDENTIFIER_NOT_USED(CE_Number);
+
+ // Not used / implemented yet
+ ZEROINIT(*OCE_Clock_p);
+
+ return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/*-----------------------------------------------------------------------------
+ * EIP207_OCE_Status_Get
+ */
+EIP207_Global_Error_t
+EIP207_OCE_Status_Get(
+ const Device_Handle_t Device,
+ const unsigned int CE_Number,
+ EIP207_Global_CE_Status_t * const OCE_Status_p)
+{
+ if ((EIP97_SupportedFuncs_Get() & BIT_1) != 0)
+ {
+ EIP207_OCE_PUE_CTRL_RD_CLEAR(Device,
+ CE_Number,
+ &OCE_Status_p->fPUE_EccCorr,
+ &OCE_Status_p->fPUE_EccDerr);
+
+ EIP207_OCE_FPP_CTRL_RD_CLEAR(Device,
+ CE_Number,
+ &OCE_Status_p->fFPP_EccCorr,
+ &OCE_Status_p->fFPP_EccDerr);
+
+ EIP207_OCE_SCRATCH_CTRL_RD(Device,
+ CE_Number,
+ &OCE_Status_p->fTimerOverflow);
+ }
+ return EIP207_GLOBAL_NO_ERROR;
+}
+
+
+/* end of file eip207_oce.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_rc.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_rc.c
new file mode 100644
index 0000000..42ea46c
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_rc.c
@@ -0,0 +1,107 @@
+/* eip207_rc.c
+ *
+ * EIP-207 Record Cache (RC) interface High-Performance (HP) implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207 Record Cache (RC) interface
+#include "eip207_rc.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // uint32_t
+
+// EIP-207 Global Control Driver Library Internal interfaces
+#include "eip207_level0.h" // EIP-207 Level 0 macros
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_BaseAddr_Set
+ */
+void
+EIP207_RC_BaseAddr_Set(
+ const Device_Handle_t Device,
+ const uint32_t CacheBase,
+ const unsigned int CacheNr,
+ const uint32_t Address,
+ const uint32_t UpperAddress)
+{
+ // Not implemented
+ IDENTIFIER_NOT_USED(Device);
+ IDENTIFIER_NOT_USED(CacheBase);
+ IDENTIFIER_NOT_USED(CacheNr);
+ IDENTIFIER_NOT_USED(Address);
+ IDENTIFIER_NOT_USED(UpperAddress);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_Record_Update
+ */
+void
+EIP207_RC_Record_Update(
+ const Device_Handle_t Device,
+ const uint32_t CacheBase,
+ const unsigned int CacheNr,
+ const uint32_t Rec_DMA_Addr,
+ const uint8_t Command,
+ const unsigned int ByteOffset,
+ const uint32_t Value32)
+{
+ // Not implemented
+ IDENTIFIER_NOT_USED(Command);
+ IDENTIFIER_NOT_USED(Device);
+ IDENTIFIER_NOT_USED(CacheBase);
+ IDENTIFIER_NOT_USED(Device);
+ IDENTIFIER_NOT_USED(CacheNr);
+ IDENTIFIER_NOT_USED(Rec_DMA_Addr);
+ IDENTIFIER_NOT_USED(ByteOffset);
+ IDENTIFIER_NOT_USED(Value32);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_Record_Dummy_Addr_Get
+ */
+unsigned int
+EIP207_RC_Record_Dummy_Addr_Get(void)
+{
+ return EIP207_RC_RECORD_DUMMY_ADDRESS;
+}
+
+
+/* end of file eip207_rc.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_rc_internal.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_rc_internal.c
new file mode 100644
index 0000000..4ca5d25
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_rc_internal.c
@@ -0,0 +1,808 @@
+/* eip207_rc_internal.c
+ *
+ * EIP-207 Record Cache (RC) interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// EIP-207 Record Cache (RC) internal interface
+#include "eip207_rc_internal.h"
+
+// EIP97_Interfaces_Get()
+#include "eip97_global_internal.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // uint32_t, bool
+
+// EIP-207 Global Control Driver Library Internal interfaces
+#include "eip207_level0.h" // EIP-207 Level 0 macros
+
+// EIP-206 Global Control Driver Library Internal interfaces
+#include "eip206_level0.h" // EIP-206 Level 0 macros
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+
+// EIP-207 Firmware Classification API
+#include "firmware_eip207_api_cs.h" // Classification API: General
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#if FIRMWARE_EIP207_CS_ARC4RC_RECORD_WORD_COUNT <= \
+ FIRMWARE_EIP207_CS_TRC_RECORD_WORD_COUNT
+#define EIP207_RC_ARC4_SIZE 0
+#elif FIRMWARE_EIP207_CS_ARC4RC_RECORD_WORD_COUNT <= \
+ FIRMWARE_EIP207_CS_TRC_RECORD_WORD_COUNT_LARGE
+#define EIP207_RC_ARC4_SIZE 1
+#else
+#error "Error: ARC4 State Record size too big"
+#endif
+
+// Minimum number of entries in the Record Cache
+#define EIP207_RC_MIN_ENTRY_COUNT 32
+
+// Maximum number of entries in the Record Cache
+#define EIP207_RC_MAX_ENTRY_COUNT 4096
+
+// Maximum number of records in cachs
+#define EIP207_RC_MAX_RECORD_COUNT 1023
+
+// Number of header words (32-bits) in a cache record
+#define EIP207_RC_HEADER_WORD_COUNT 4
+
+// Number of 32-bit words in one administration memory word
+#define EIP207_RC_ADMIN_MEMWORD_WORD_COUNT 4
+
+// Number of hash table entries in one administration memory word
+#define EIP207_RC_ADMIN_MEMWORD_ENTRY_COUNT 8
+
+// Null value used in Record Caches
+#define EIP207_RC_NULL_VALUE 0x3FF
+
+// Checks for the required configuration parameters
+#ifndef EIP207_FRC_ADMIN_RAM_WORD_COUNT
+#error "EIP207_FRC_ADMIN_RAM_WORD_COUNT not defined"
+#endif // EIP207_FRC_ADMIN_RAM_WORD_COUNT
+
+#ifndef EIP207_TRC_ADMIN_RAM_WORD_COUNT
+#error "EIP207_TRC_ADMIN_RAM_WORD_COUNT not defined"
+#endif // EIP207_TRC_ADMIN_RAM_WORD_COUNT
+
+#ifndef EIP207_ARC4RC_ADMIN_RAM_WORD_COUNT
+#error "EIP207_ARC4RC_ADMIN_RAM_WORD_COUNT not defined"
+#endif // EIP207_ARC4RC_ADMIN_RAM_WORD_COUNT
+
+// Minimum required Record Cache Admin RAM size
+#define EIP207_RC_MIN_ADMIN_RAM_WORD_COUNT \
+ (((EIP207_RC_MIN_ENTRY_COUNT / EIP207_RC_ADMIN_MEMWORD_ENTRY_COUNT) * \
+ EIP207_RC_ADMIN_MEMWORD_WORD_COUNT) + \
+ EIP207_RC_HEADER_WORD_COUNT * EIP207_RC_MIN_ENTRY_COUNT)
+
+// Check if the configured FRC Admin RAM size is large enough to contain
+// the minimum required number of record headers with their hash table
+#if EIP207_FRC_ADMIN_RAM_WORD_COUNT > 0 && \
+ EIP207_FRC_ADMIN_RAM_WORD_COUNT < EIP207_RC_MIN_ADMIN_RAM_WORD_COUNT
+#error "Configured FRC Admin RAM size is too small"
+#endif
+
+// Check if the configured TRC Admin RAM size is large enough to contain
+// the minimum required number of record headers with their hash table
+#if EIP207_TRC_ADMIN_RAM_WORD_COUNT > 0 && \
+ EIP207_TRC_ADMIN_RAM_WORD_COUNT < EIP207_RC_MIN_ADMIN_RAM_WORD_COUNT
+#error "Configured TRC Admin RAM size is too small"
+#endif
+
+// Check if the (optional) configured ARC4RC Admin RAM size is large enough
+// to contain the minimum required number of record headers
+// with their hash table
+#if EIP207_ARC4RC_ADMIN_RAM_WORD_COUNT > 0 && \
+ EIP207_ARC4RC_ADMIN_RAM_WORD_COUNT < EIP207_RC_MIN_ADMIN_RAM_WORD_COUNT
+#error "Configured ARC4RC Admin RAM size is too small"
+#endif
+
+// Hash Table Size calculation for *RC_p_PARAMS registers
+// Hash Table entry count =
+// 2 ^ (Hash Table Size + EIP207_RC_HASH_TABLE_SIZE_POWER_FACTOR)
+#define EIP207_RC_HASH_TABLE_SIZE_POWER_FACTOR 5
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_RC_Internal_LowerPowerOfTwo
+ *
+ * Rounds down a value to the lower or equal power of two value.
+ */
+static unsigned int
+EIP207Lib_RC_Internal_LowerPowerOfTwo(const unsigned int Value,
+ unsigned int * const Power)
+{
+ unsigned int v = Value;
+ unsigned int i = 0;
+
+ if (v == 0)
+ return v;
+
+ while (v)
+ {
+ v = v >> 1;
+ i++;
+ }
+
+ v = 1 << (i - 1);
+
+ *Power = i - 1;
+
+ return v;
+}
+
+
+#define EIP207_RC_DATA_WORDCOUNT_MAX 131072
+#define EIP207_RC_DATA_WORDCOUNT_MIN 256
+#define EIP207_RC_ADMIN_WORDCOUNT_MAX 16384
+#define EIP207_RC_ADMIN_WORDCOUNT_MIN 64
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_Bank_Set
+ *
+ * Set the bank for the CS RAM to the given address.
+ *
+ * Device (input)
+ * Device to use.
+ *
+ * BankNr (input)
+ * Bank number from 0 to 7.
+ *
+ */
+static void
+EIP207Lib_Bank_Set(
+ const Device_Handle_t Device,
+ uint32_t BankNr)
+{
+ uint32_t OldValue = Device_Read32(Device, EIP207_CS_REG_RAM_CTRL);
+
+ uint32_t NewValue = (OldValue & 0xffff8fff) | ((BankNr&0x7) << 12);
+
+ Device_Write32(Device, EIP207_CS_REG_RAM_CTRL, NewValue);
+}
+
+
+static void
+EIP207Lib_RAM_Write32(
+ const Device_Handle_t Device,
+ uint32_t Address,
+ uint32_t Value)
+{
+ Device_Write32(Device,
+ EIP207_CS_RAM_XS_SPACE_BASE + Address,
+ Value);
+}
+
+static uint32_t
+EIP207Lib_RAM_Read32(
+ const Device_Handle_t Device,
+ uint32_t Address)
+{
+ return Device_Read32(Device,
+ EIP207_CS_RAM_XS_SPACE_BASE + Address);
+}
+
+
+
+/*----------------------------------------------------------------------------
+ * EIP207Lib_RAMSize_Probe
+ *
+ * Probe the size of the accessible RAM, do not access more memory than
+ * indicated by MaxSize.
+ *
+ * Device (input)
+ * Device to use.
+ *
+ * MaxSize (input)
+ * Maximum size of RAM
+ */
+static unsigned int
+EIP207Lib_RAMSize_Probe(
+ const Device_Handle_t Device,
+ const unsigned int MaxSize)
+{
+ unsigned int MaxBank, MaxPage, MaxOffs, i, RAMSize;
+
+ if (MaxSize <= 16384)
+ {
+ // All RAM is in a single bank.
+ MaxBank = 0;
+ }
+ else
+ {
+ // Probe the maximum bank number that has (distinct) RAM.
+ for (i=0; i<8; i++)
+ {
+ EIP207Lib_Bank_Set(Device, 7 - i);
+ EIP207Lib_RAM_Write32(Device, 0, 7 - i);
+ EIP207Lib_RAM_Write32(Device, 4, 0);
+ EIP207Lib_RAM_Write32(Device, 8, 0);
+ EIP207Lib_RAM_Write32(Device, 12, 0);
+ }
+ MaxBank=0;
+ for (i=0; i<7; i++)
+ {
+ EIP207Lib_Bank_Set(Device, i);
+ if (EIP207Lib_RAM_Read32(Device, 0) != i)
+ {
+ break;
+ }
+ MaxBank = i;
+ }
+ }
+
+ EIP207Lib_Bank_Set(Device, MaxBank);
+
+ for (i=0; i<0x10000; i+=0x100)
+ {
+ EIP207Lib_RAM_Write32(Device, 0xff00-i, 0xff00-i);
+ EIP207Lib_RAM_Write32(Device, 0xff00-i+4, 0);
+ EIP207Lib_RAM_Write32(Device, 0xff00-i+8, 0);
+ EIP207Lib_RAM_Write32(Device, 0xff00-i+12, 0);
+ }
+
+ MaxPage = 0;
+ for (i=0; i<0x10000; i+=0x100)
+ {
+ if (EIP207Lib_RAM_Read32(Device, i) != i)
+ {
+ break;
+ }
+ MaxPage = i;
+ }
+
+ for (i=0; i<0x100; i+= 4)
+ {
+ EIP207Lib_RAM_Write32(Device, MaxPage + 0xfc - i, MaxPage + 0xfc - i);
+ }
+
+ MaxOffs = 0;
+
+ for (i=0; i<0x100; i+=4)
+ {
+ if (EIP207Lib_RAM_Read32(Device, MaxPage + i) != MaxPage + i)
+ {
+ break;
+ }
+ MaxOffs = i;
+ }
+
+ EIP207Lib_Bank_Set(Device, 0);
+ RAMSize = ((MaxBank<<16) + MaxPage + MaxOffs + 4) >> 2;
+
+ if (RAMSize > MaxSize)
+ RAMSize = MaxSize;
+
+ return RAMSize;
+}
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_Internal_Init
+ */
+EIP207_Global_Error_t
+EIP207_RC_Internal_Init(
+ const Device_Handle_t Device,
+ const EIP207_RC_Internal_Combination_Type_t CombinationType,
+ const uint32_t CacheBase,
+ EIP207_Global_CacheParams_t * RC_Params_p,
+ const unsigned int RecordWordCount)
+{
+ unsigned int i;
+ uint16_t RC_Record2_WordCount = 0;
+ uint8_t ClocksPerTick;
+ bool fFrc = false, fTrc = false, fArc4 = false;
+ EIP207_Global_CacheParams_t * RC_p = RC_Params_p;
+ unsigned int NullVal = EIP207_RC_NULL_VALUE;
+
+ switch (CacheBase)
+ {
+ case EIP207_FRC_REG_BASE:
+ fFrc = true;
+ RC_Record2_WordCount = 0;
+ break;
+
+ case EIP207_TRC_REG_BASE:
+ fTrc = true;
+ RC_Record2_WordCount =
+ FIRMWARE_EIP207_CS_TRC_RECORD_WORD_COUNT_LARGE;
+ break;
+
+ case EIP207_ARC4RC_REG_BASE:
+ fArc4 = true;
+ RC_Record2_WordCount =
+ FIRMWARE_EIP207_CS_ARC4RC_RECORD_WORD_COUNT_LARGE;
+ break;
+
+ default:
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+ }
+
+ if (CombinationType != EIP207_RC_INTERNAL_NOT_COMBINED)
+ {
+ if( fFrc ) // FRC cannot be combined
+ return EIP207_GLOBAL_ARGUMENT_ERROR;
+
+ // Initialize all the configured for use Record Cache sets
+ for (i = 0; i < EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE; i++)
+ EIP207_RC_PARAMS_WR(Device,
+ CacheBase,
+ i, // Cache Set number
+ false, // Disable cache RAM access
+ false, // Block Next Command is reserved
+ false, // Enable access cache administration RAM
+ 0,
+ 0, // Block Time Base is reserved
+ false, // Not used for this HW
+ RC_Record2_WordCount); // Large record size
+
+ return EIP207_GLOBAL_NO_ERROR;
+ }
+ // Indicate if ARC4 state records are considered 'large' transform records.
+ // Only relevent inin case the TRC is used to store ARC4 state records, but
+ // without a combined cache.
+ if (fTrc)
+ {
+ unsigned int NofCEs;
+ EIP97_Interfaces_Get(&NofCEs,NULL,NULL,NULL);
+ for (i = 0; i < NofCEs; i++)
+ EIP206_ARC4_SIZE_WR(Device, i, EIP207_RC_ARC4_SIZE);
+ }
+
+ // Initialize all the configured for use Record Cache sets
+ for (i = 0; i < EIP207_GLOBAL_MAX_NOF_CACHE_SETS_TO_USE; i++)
+ {
+ unsigned int RC_RAM_WordCount = RC_p->DataWordCount;
+ uint8_t RC_HashTableSize;
+ unsigned int j, Power,
+ RC_RecordCount,
+ RC_Record_WordCount,
+ RC_HashTable_EntryCount,
+ RC_HashTable_WordCount,
+ RC_AdminRAM_WordCount,
+ RC_AdminRAM_EntryCount,
+ RC_HashTable_ByteOffset;
+
+ if (RC_p->fEnable == false)
+ continue; // Cache is not enabled
+
+ // Enable Record Cache RAM access
+ EIP207_CS_RAM_CTRL_WR(
+ Device,
+ fFrc && i==0,
+ fFrc && i==1,
+ fFrc && i==2,
+ fTrc && i==0,
+ fTrc && i==1,
+ fTrc && i==2,
+ fArc4 && i==0,
+ fArc4 && i==1,
+ fArc4 && i==2,
+ false); // No FLUEC cache RAM access
+
+ // Take Record Cache into reset
+ // Make cache data RAM accessible
+ EIP207_RC_PARAMS_WR(Device,
+ CacheBase,
+ i, // Cache Set number
+ true, // Enable cache RAM access
+ false,
+ true, // Enable access cache data RAM
+ 0,
+ 0,
+ false, // Not used here for this HW
+ 0);
+
+ if (RC_RAM_WordCount == 0 ||
+ RC_RAM_WordCount > EIP207_RC_DATA_WORDCOUNT_MAX)
+ RC_RAM_WordCount = EIP207_RC_DATA_WORDCOUNT_MAX;
+ // Check the size of the data RAM.
+ RC_RAM_WordCount = EIP207Lib_RAMSize_Probe(
+ Device,
+ RC_RAM_WordCount);
+
+ // Data RAM may be inaccessible on some hardware configurations,
+ // so RAM size probing may not work. Assume that provided word count
+ // input actually reflects RAM size.
+ if (RC_RAM_WordCount < EIP207_RC_DATA_WORDCOUNT_MIN)
+ RC_RAM_WordCount = MIN(RC_p->DataWordCount, EIP207_RC_DATA_WORDCOUNT_MAX);
+ if (RC_RAM_WordCount < EIP207_RC_DATA_WORDCOUNT_MIN)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+
+ RC_p->DataWordCount = RC_RAM_WordCount;
+
+ // Take Record Cache into reset
+ // Make cache administration RAM accessible
+ EIP207_RC_PARAMS_WR(Device,
+ CacheBase,
+ i, // Cache Set number
+ true, // Enable cache RAM access
+ false,
+ false, // Enable access cache administration RAM
+ 0,
+ 0,
+ false, // Not used here for this HW
+ 0);
+
+ // Get the configured RC Admin RAM size
+ RC_AdminRAM_WordCount = RC_p->AdminWordCount;
+ if (RC_AdminRAM_WordCount == 0 ||
+ RC_AdminRAM_WordCount > EIP207_RC_ADMIN_WORDCOUNT_MAX)
+ RC_AdminRAM_WordCount = EIP207_RC_ADMIN_WORDCOUNT_MAX;
+
+ RC_AdminRAM_WordCount = EIP207Lib_RAMSize_Probe(
+ Device,
+ RC_AdminRAM_WordCount);
+
+ RC_p->AdminWordCount = RC_AdminRAM_WordCount;
+
+ if (RC_AdminRAM_WordCount < EIP207_RC_ADMIN_WORDCOUNT_MIN)
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+
+ // Check the size of the Admin RAM
+
+ // Determine the RC record size to use
+ if (RC_Record2_WordCount > RecordWordCount)
+ RC_Record_WordCount = RC_Record2_WordCount;
+ else
+ RC_Record_WordCount = RecordWordCount;
+
+ // Calculate the maximum possible record count that
+ // the Record Cache Data RAM can contain
+ RC_RecordCount = RC_RAM_WordCount / RC_Record_WordCount;
+ if (RC_RecordCount > EIP207_RC_MAX_RECORD_COUNT)
+ RC_RecordCount = EIP207_RC_MAX_RECORD_COUNT;
+
+ // RC_RecordCount is calculated using the configured RC Data RAM size.
+
+ // RC_AdminRAM_EntryCount is calculated using
+ // the configured RC Admin RAM size.
+
+ // Calculate the maximum possible record count that
+ // the RC Hash Table (in Record Cache Administration RAM) can contain
+ RC_AdminRAM_EntryCount = EIP207_RC_ADMIN_MEMWORD_ENTRY_COUNT *
+ RC_AdminRAM_WordCount /
+ (EIP207_RC_ADMIN_MEMWORD_WORD_COUNT +
+ EIP207_RC_ADMIN_MEMWORD_ENTRY_COUNT *
+ EIP207_RC_HEADER_WORD_COUNT);
+
+ // Try to extend the Hash Table in the RC Admin RAM
+ if (RC_RecordCount < RC_AdminRAM_EntryCount)
+ {
+ unsigned int HTSpace_WordCount;
+
+ // Calculate the size of space available for the Hash Table
+ HTSpace_WordCount = RC_AdminRAM_WordCount -
+ RC_RecordCount * EIP207_RC_HEADER_WORD_COUNT;
+
+ // Calculate maximum possible Hash Table entry count
+ RC_HashTable_EntryCount = (HTSpace_WordCount /
+ EIP207_RC_ADMIN_MEMWORD_WORD_COUNT) *
+ EIP207_RC_ADMIN_MEMWORD_ENTRY_COUNT;
+ }
+ else // Extension impossible
+ RC_HashTable_EntryCount = RC_AdminRAM_EntryCount;
+
+ // Check minimum number of entries in the record cache
+ RC_HashTable_EntryCount = MAX(EIP207_RC_MIN_ENTRY_COUNT,
+ RC_HashTable_EntryCount);
+
+ // Check maximum number of entries in the record cache
+ RC_HashTable_EntryCount = MIN(EIP207_RC_MAX_ENTRY_COUNT,
+ RC_HashTable_EntryCount);
+
+ // Round down to power of two
+ Power = 0;
+ RC_HashTable_EntryCount =
+ EIP207Lib_RC_Internal_LowerPowerOfTwo(RC_HashTable_EntryCount,
+ &Power);
+
+ // Hash Table Mask that determines the hash table size
+ if (Power >= EIP207_RC_HASH_TABLE_SIZE_POWER_FACTOR)
+ RC_HashTableSize =
+ (uint8_t)(Power - EIP207_RC_HASH_TABLE_SIZE_POWER_FACTOR);
+ else
+ // Insufficient memory for Hash Table in the RC Admin RAM
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+
+ // Calculate the Hash Table size in 32-bit words
+ RC_HashTable_WordCount = RC_HashTable_EntryCount /
+ EIP207_RC_ADMIN_MEMWORD_ENTRY_COUNT *
+ EIP207_RC_ADMIN_MEMWORD_WORD_COUNT;
+
+ // Recalculate the record count that fits the RC Admin RAM space
+ // without the Hash Table, restricting for the maximum records
+ // which fit the RC Data RAM
+ {
+ // Adjusted record count which fits the RC Admin RAM
+ unsigned int RC_AdminRAM_AdjustedEntryCount =
+ (RC_AdminRAM_WordCount -
+ RC_HashTable_WordCount) /
+ EIP207_RC_HEADER_WORD_COUNT;
+
+ // Maximum record count which fits the RC Data RAM - RC_RecordCount
+ // use the minimum of the two
+ RC_RecordCount = MIN(RC_RecordCount,
+ RC_AdminRAM_AdjustedEntryCount);
+ }
+
+ // Clear all ECC errors
+ EIP207_RC_ECCCTRL_WR(Device, CacheBase, i, false, false, false);
+
+ // Clear all record administration words
+ // in Record Cache administration RAM
+ for (j = 0; j < RC_RecordCount; j++)
+ {
+ // Calculate byte offset for the current record
+ unsigned int ByteOffset = EIP207_CS_RAM_XS_SPACE_BASE +
+ j *
+ EIP207_RC_HEADER_WORD_COUNT *
+ sizeof(uint32_t);
+
+ // Write word 0
+ Device_Write32(Device,
+ ByteOffset,
+ (NullVal << 20) | // Hash_Collision_Prev
+ (NullVal << 10)); // Hash_Collision_Next
+
+ // Write word 1
+ ByteOffset += sizeof(uint32_t);
+
+ if (j == RC_RecordCount - 1)
+ {
+ // Last record
+ Device_Write32(Device,
+ ByteOffset,
+ ((j - 1) << 10) | // Free_List_Prev
+ NullVal); // Free_List_Next
+ }
+ else if (j == 0)
+ {
+ // First record
+ Device_Write32(Device,
+ ByteOffset,
+ (NullVal << 10) | // Free_List_Prev
+ (j + 1)); // Free_List_Next
+ }
+ else
+ {
+ // All other records
+ Device_Write32(Device,
+ ByteOffset,
+ ((j - 1) << 10) | // Free_List_Prev
+ (j + 1)); // Free_List_Next
+ }
+
+ // Write word 2
+ ByteOffset += sizeof(uint32_t);
+
+ Device_Write32(Device,
+ ByteOffset,
+ 0); // Address_Key, low bits
+
+ // Write word 3
+ ByteOffset += sizeof(uint32_t);
+
+ Device_Write32(Device,
+ ByteOffset,
+ 0); // Address_Key, high bits
+ } // for (records)
+
+ // Calculate byte offset for the Hash Table
+ RC_HashTable_ByteOffset = EIP207_CS_RAM_XS_SPACE_BASE +
+ RC_RecordCount *
+ EIP207_RC_HEADER_WORD_COUNT *
+ sizeof(uint32_t);
+
+ // Clear all hash table words
+ for (j = 0; j < RC_HashTable_WordCount; j++)
+ Device_Write32(Device,
+ RC_HashTable_ByteOffset + j * sizeof(uint32_t),
+ 0x3FFFFFFF);
+
+ // Disable Record Cache RAM access
+ EIP207_CS_RAM_CTRL_DEFAULT_WR(Device);
+
+ // Write head and tail pointers to the RC Free Chain
+ EIP207_RC_FREECHAIN_WR(
+ Device,
+ CacheBase,
+ i, // Cache Set number
+ 0, // head pointer
+ (uint16_t)(RC_RecordCount - 1)); // tail pointer
+
+ // Set Hash Table start
+ // This is an offset from EIP207_CS_RAM_XS_SPACE_BASE
+ // in record administration memory words
+ EIP207_RC_PARAMS2_WR(Device,
+ CacheBase,
+ i,
+ (uint16_t)RC_RecordCount,
+ /* Small Record size */ fArc4 ? 0 : (uint16_t)RecordWordCount,
+ FIRMWARE_EIP207_RC_DMA_WR_COMB_DLY);
+
+ // Select the highest clock count as specified by
+ // the Host and the Firmware for the FRC
+#ifdef FIRMWARE_EIP207_CS_BLOCK_NEXT_COMMAND_LOGIC_DISABLE
+ ClocksPerTick = RC_p->BlockClockCount;
+#else
+ {
+ uint8_t tmp;
+
+ tmp = (uint8_t)FIRMWARE_EIP207_CS_FRC_BLOCK_TIMEBASE;
+ ClocksPerTick = RC_p->BlockClockCount >= tmp ?
+ CacheConf_p->FRC.BlockClockCount : tmp;
+ }
+#endif
+
+ // Take Record Cache out of reset
+ EIP207_RC_PARAMS_WR(Device,
+ CacheBase,
+ i, // Cache Set number
+ false, // Disable cache RAM access
+ RC_p->fNonBlock,
+ false, // Disable access cache administration RAM
+ RC_HashTableSize,
+ ClocksPerTick,
+ false, // Not used here for this HW
+ RC_Record2_WordCount); // Large record size
+
+ RC_p++;
+ } // for, i cache sets
+
+ return EIP207_GLOBAL_NO_ERROR;
+}
+
+static void
+EIP207_RC_Internal_DebugStatistics_Single_Get(
+ const Device_Handle_t Device,
+ const unsigned int CacheSetId,
+ uint32_t RegBase,
+ EIP207_Global_CacheDebugStatistics_t * const Stats_p)
+{
+ EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_PREFEXEC(RegBase, CacheSetId),
+ &Stats_p->PrefetchExec);
+ EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_PREFBLCK(RegBase, CacheSetId),
+ &Stats_p->PrefetchBlock);
+ EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_PREFDMA(RegBase, CacheSetId),
+ &Stats_p->PrefetchDMA);
+ EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_SELOPS(RegBase, CacheSetId),
+ &Stats_p->SelectOps);
+ EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_SELDMA(RegBase, CacheSetId),
+ &Stats_p->SelectDMA);
+ EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_IDMAWR(RegBase, CacheSetId),
+ &Stats_p->IntDMAWrite);
+ EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_XDMAWR(RegBase, CacheSetId),
+ &Stats_p->ExtDMAWrite);
+ EIP207_RC_LONGCTR_RD(Device, EIP207_RC_REG_INVCMD(RegBase, CacheSetId),
+ &Stats_p->InvalidateOps);
+ EIP207_RC_RDMAERRFLGS_RD(Device, RegBase, CacheSetId,
+ &Stats_p->ReadDMAErrFlags);
+ EIP207_RC_SHORTCTR_RD(Device, EIP207_RC_REG_RDMAERR(RegBase, CacheSetId),
+ &Stats_p->ReadDMAErrors);
+ EIP207_RC_SHORTCTR_RD(Device, EIP207_RC_REG_WDMAERR(RegBase, CacheSetId),
+ &Stats_p->WriteDMAErrors);
+ EIP207_RC_SHORTCTR_RD(Device, EIP207_RC_REG_INVECC(RegBase, CacheSetId),
+ &Stats_p->InvalidateECC);
+ EIP207_RC_SHORTCTR_RD(Device, EIP207_RC_REG_DATECC_CORR(RegBase, CacheSetId),
+ &Stats_p->DataECCCorr);
+ EIP207_RC_SHORTCTR_RD(Device, EIP207_RC_REG_ADMECC_CORR(RegBase, CacheSetId),
+ &Stats_p->AdminECCCorr);
+
+}
+
+
+void
+EIP207_RC_Internal_DebugStatistics_Get(
+ const Device_Handle_t Device,
+ const unsigned int CacheSetId,
+ EIP207_Global_CacheDebugStatistics_t * const FRC_Stats_p,
+ EIP207_Global_CacheDebugStatistics_t * const TRC_Stats_p)
+{
+ EIP207_RC_Internal_DebugStatistics_Single_Get(
+ Device,
+ CacheSetId,
+ EIP207_FRC_REG_BASE,
+ FRC_Stats_p);
+ EIP207_RC_Internal_DebugStatistics_Single_Get(
+ Device,
+ CacheSetId,
+ EIP207_TRC_REG_BASE,
+ TRC_Stats_p);
+}
+
+/*----------------------------------------------------------------------------
+ * EIP207_RC_Internal_Status_Get
+ */
+void
+EIP207_RC_Internal_Status_Get(
+ const Device_Handle_t Device,
+ const unsigned int CacheSetId,
+ EIP207_Global_CacheStatus_t * const FRC_Status_p,
+ EIP207_Global_CacheStatus_t * const TRC_Status_p,
+ EIP207_Global_CacheStatus_t * const ARC4RC_Status_p)
+{
+ // Read FRC status
+ EIP207_RC_PARAMS_RD(Device,
+ EIP207_FRC_REG_BASE,
+ CacheSetId,
+ &FRC_Status_p->fDMAReadError,
+ &FRC_Status_p->fDMAWriteError);
+
+ EIP207_RC_ECCCTRL_RD_CLEAR(Device,
+ EIP207_FRC_REG_BASE,
+ CacheSetId,
+ &FRC_Status_p->fDataEccOflo,
+ &FRC_Status_p->fDataEccErr,
+ &FRC_Status_p->fAdminEccErr);
+
+ // Read TRC status
+ EIP207_RC_PARAMS_RD(Device,
+ EIP207_TRC_REG_BASE,
+ CacheSetId,
+ &TRC_Status_p->fDMAReadError,
+ &TRC_Status_p->fDMAWriteError);
+
+ EIP207_RC_ECCCTRL_RD_CLEAR(Device,
+ EIP207_TRC_REG_BASE,
+ CacheSetId,
+ &TRC_Status_p->fDataEccOflo,
+ &TRC_Status_p->fDataEccErr,
+ &TRC_Status_p->fAdminEccErr);
+
+ // Read ARC4RC status
+ EIP207_RC_PARAMS_RD(Device,
+ EIP207_ARC4RC_REG_BASE,
+ CacheSetId,
+ &ARC4RC_Status_p->fDMAReadError,
+ &ARC4RC_Status_p->fDMAWriteError);
+
+ EIP207_RC_ECCCTRL_RD_CLEAR(Device,
+ EIP207_ARC4RC_REG_BASE,
+ CacheSetId,
+ &ARC4RC_Status_p->fDataEccOflo,
+ &ARC4RC_Status_p->fDataEccErr,
+ &ARC4RC_Status_p->fAdminEccErr);
+}
+
+
+/* end of file eip207_rc_internal.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_support.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_support.c
new file mode 100644
index 0000000..b5982c6
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip207_support.c
@@ -0,0 +1,86 @@
+/* eip207_support.c
+ *
+ * EIP-207 Support interface implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP-207 Support interface
+#include "eip207_support.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip207_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // uint32_t, bool
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+#include "device_rw.h" // Read32, Write32
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP207_Global_Read64
+ */
+EIP207_Global_Error_t
+EIP207_Global_Read64(
+ const Device_Handle_t Device,
+ const unsigned int Value64_OffsetLo,
+ const unsigned int Value64_OffsetHi,
+ EIP207_Global_Value64_t * const Value64_p)
+{
+ uint32_t Value32;
+ unsigned int i;
+
+ for (i = 0; i < EIP207_VALUE_64BIT_MAX_NOF_READ_ATTEMPTS; i++)
+ {
+ Value32 = Device_Read32(Device, Value64_OffsetHi);
+
+ Value64_p->Value64_Lo = Device_Read32(Device, Value64_OffsetLo);
+ Value64_p->Value64_Hi = Device_Read32(Device, Value64_OffsetHi);
+
+ if (Value32 == Value64_p->Value64_Hi)
+ return EIP207_GLOBAL_NO_ERROR;
+ }
+
+ return EIP207_GLOBAL_INTERNAL_ERROR;
+}
+
+
+/* end of file eip207_support.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip74.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip74.c
new file mode 100644
index 0000000..a9ef9ff
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip74.c
@@ -0,0 +1,388 @@
+/* eip74.c
+ *
+ * Implementation of the EIP-74 Driver Library.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// EIP76 initialization API
+#include "eip74.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip74.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // uint32_t
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+
+// EIP-76 Driver Library Internal interfaces
+#include "eip74_level0.h" // Level 0 macros
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// I/O Area, used internally
+typedef struct
+{
+ Device_Handle_t Device;
+} EIP74_True_IOArea_t;
+
+#define TEST_SIZEOF(type, size) \
+ extern int size##_must_bigger[1 - 2*((int)(sizeof(type) > size))]
+
+
+#ifdef EIP74_STRICT_ARGS
+#define EIP74_CHECK_POINTER(_p) \
+ if (NULL == (_p)) \
+ return EIP74_ARGUMENT_ERROR;
+#define EIP74_CHECK_INT_INRANGE(_i, _min, _max) \
+ if ((_i) < (_min) || (_i) > (_max)) \
+ return EIP74_ARGUMENT_ERROR;
+#define EIP74_CHECK_INT_ATLEAST(_i, _min) \
+ if ((_i) < (_min)) \
+ return EIP74_ARGUMENT_ERROR;
+#define EIP74_CHECK_INT_ATMOST(_i, _max) \
+ if ((_i) > (_max)) \
+ return EIP74_ARGUMENT_ERROR;
+#else
+/* EIP74_STRICT_ARGS undefined */
+#define EIP74_CHECK_POINTER(_p)
+#define EIP74_CHECK_INT_INRANGE(_i, _min, _max)
+#define EIP74_CHECK_INT_ATLEAST(_i, _min)
+#define EIP74_CHECK_INT_ATMOST(_i, _max)
+#endif /*end of EIP74_STRICT_ARGS */
+
+
+// validate the size of the fake and real IOArea structures
+TEST_SIZEOF(EIP74_True_IOArea_t, EIP74_IOAREA_REQUIRED_SIZE);
+
+
+/*----------------------------------------------------------------------------
+ * EIP74Lib_Detect
+ *
+ * Checks the presence of EIP-74 device. Returns true when found.
+ */
+static bool
+EIP74Lib_Detect(
+ const Device_Handle_t Device)
+{
+ uint32_t Value;
+
+ Value = EIP74_Read32(Device, EIP74_REG_VERSION);
+ if (!EIP74_REV_SIGNATURE_MATCH( Value ))
+ return false;
+
+ return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74Lib_Reset_IsDone
+ */
+static bool
+EIP74Lib_Reset_IsDone(
+ const Device_Handle_t Device)
+{
+ bool fReady, fPSAIWriteOK, fStuckOut, fEarlyReseed;
+ bool fTestReady,fGenPktError, fInstantiated, fTestStuckOut, fNeedClock;
+ uint8_t BlocksAvailable;
+
+ EIP74_STATUS_RD(Device,
+ &fReady,
+ &fPSAIWriteOK,
+ &fStuckOut,
+ &fEarlyReseed,
+ &fTestReady,
+ &fGenPktError,
+ &fInstantiated,
+ &fTestStuckOut,
+ &BlocksAvailable,
+ &fNeedClock);
+
+ return fPSAIWriteOK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Init
+ */
+EIP74_Error_t
+EIP74_Init(
+ EIP74_IOArea_t * const IOArea_p,
+ const Device_Handle_t Device)
+{
+ volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+ (EIP74_True_IOArea_t *)IOArea_p;
+ EIP74_CHECK_POINTER(IOArea_p);
+
+ TrueIOArea_p->Device = Device;
+
+ if (!EIP74Lib_Detect(Device))
+ {
+ return EIP74_UNSUPPORTED_FEATURE_ERROR;
+ }
+
+ return EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Reset
+ */
+EIP74_Error_t
+EIP74_Reset(
+ EIP74_IOArea_t * const IOArea_p)
+{
+ Device_Handle_t Device;
+ volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+ (EIP74_True_IOArea_t *)IOArea_p;
+ EIP74_CHECK_POINTER(IOArea_p);
+
+ Device = TrueIOArea_p->Device;
+
+ EIP74_CONTROL_WR(Device,
+ false, /* fReadyMask */
+ false, /* fStuckOut */
+ false, /* fTestMode */
+ false, /* fHostMode */
+ false, /* fEnableDRBG */
+ false, /* fForceStuckOut */
+ false, /* fRequestdata */
+ 0); /* DataBlocks */
+
+ if (EIP74Lib_Reset_IsDone(Device))
+ {
+ return EIP74_NO_ERROR;
+ }
+ else
+ {
+ return EIP74_BUSY_RETRY_LATER;
+ }
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Reset_IsDone
+ */
+EIP74_Error_t
+EIP74_Reset_IsDone(
+ EIP74_IOArea_t * const IOArea_p)
+{
+ Device_Handle_t Device;
+ volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+ (EIP74_True_IOArea_t *)IOArea_p;
+ EIP74_CHECK_POINTER(IOArea_p);
+
+ Device = TrueIOArea_p->Device;
+
+ if (EIP74Lib_Reset_IsDone(Device))
+ {
+ return EIP74_NO_ERROR;
+ }
+ else
+ {
+ return EIP74_BUSY_RETRY_LATER;
+ }
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_HWRevision_Get
+ */
+EIP74_Error_t
+EIP74_HWRevision_Get(
+ const Device_Handle_t Device,
+ EIP74_Capabilities_t * const Capabilities_p)
+{
+ EIP74_CHECK_POINTER(Capabilities_p);
+
+ EIP74_VERSION_RD(Device,
+ &Capabilities_p->HW_Revision.EipNumber,
+ &Capabilities_p->HW_Revision.ComplmtEipNumber,
+ &Capabilities_p->HW_Revision.HWPatchLevel,
+ &Capabilities_p->HW_Revision.MinHWRevision,
+ &Capabilities_p->HW_Revision.MajHWRevision);
+ EIP74_OPTIONS_RD(Device,
+ &Capabilities_p->HW_Options.ClientCount,
+ &Capabilities_p->HW_Options.AESCoreCount,
+ &Capabilities_p->HW_Options.AESSpeed,
+ &Capabilities_p->HW_Options.FIFODepth);
+
+ return EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Configure
+ */
+EIP74_Error_t
+EIP74_Configure(
+ EIP74_IOArea_t * const IOArea_p,
+ const EIP74_Configuration_t * const Configuration_p)
+{
+ Device_Handle_t Device;
+ volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+ (EIP74_True_IOArea_t *)IOArea_p;
+ EIP74_CHECK_POINTER(IOArea_p);
+ EIP74_CHECK_POINTER(Configuration_p);
+ EIP74_CHECK_INT_INRANGE(Configuration_p->GenerateBlockSize, 1, 4095);
+
+ Device = TrueIOArea_p->Device;
+
+ EIP74_GEN_BLK_SIZE_WR(Device, Configuration_p->GenerateBlockSize);
+ EIP74_RESEED_THR_WR(Device, Configuration_p->ReseedThr);
+ EIP74_RESEED_THR_EARLY_WR(Device, Configuration_p->ReseedThrEarly);
+
+ return EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Instantiate
+ */
+EIP74_Error_t
+EIP74_Instantiate(
+ EIP74_IOArea_t * const IOArea_p,
+ const uint32_t * const Entropy_p,
+ bool fStuckOut)
+{
+ Device_Handle_t Device;
+ volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+ (EIP74_True_IOArea_t *)IOArea_p;
+ EIP74_CHECK_POINTER(IOArea_p);
+ EIP74_CHECK_POINTER(Entropy_p);
+
+ Device = TrueIOArea_p->Device;
+
+ EIP74_PS_AI_WR(Device, Entropy_p, 12);
+
+ EIP74_CONTROL_WR(Device,
+ false, /* fReadyMask */
+ fStuckOut,
+ false, /* fTestMode */
+ false, /* fHostMode */
+ true, /* fEnableDRBG */
+ false, /* fForceStuckOut */
+ false, /* fRequestdata */
+ 0); /* DataBlocks */
+
+ return EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Reseed
+ */
+EIP74_Error_t
+EIP74_Reseed(
+ EIP74_IOArea_t * const IOArea_p,
+ const uint32_t * const Entropy_p)
+{
+ Device_Handle_t Device;
+ volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+ (EIP74_True_IOArea_t *)IOArea_p;
+ EIP74_CHECK_POINTER(IOArea_p);
+ EIP74_CHECK_POINTER(Entropy_p);
+
+ Device = TrueIOArea_p->Device;
+
+ EIP74_PS_AI_WR(Device, Entropy_p, 12);
+
+ return EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Status_Get
+ */
+EIP74_Error_t
+EIP74_Status_Get(
+ EIP74_IOArea_t * const IOArea_p,
+ EIP74_Status_t * const Status_p)
+{
+ Device_Handle_t Device;
+ volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+ (EIP74_True_IOArea_t *)IOArea_p;
+ bool fReady, fPSAIWriteOK, fStuckOut, fEarlyReseed;
+ bool fTestReady,fGenPktError, fInstantiated, fTestStuckOut, fNeedClock;
+ uint8_t BlocksAvailable;
+ uint32_t GenBlockCount, ReseedThr;
+ EIP74_CHECK_POINTER(IOArea_p);
+ EIP74_CHECK_POINTER(Status_p);
+
+ Device = TrueIOArea_p->Device;
+
+ EIP74_STATUS_RD(Device,
+ &fReady,
+ &fPSAIWriteOK,
+ &fStuckOut,
+ &fEarlyReseed,
+ &fTestReady,
+ &fGenPktError,
+ &fInstantiated,
+ &fTestStuckOut,
+ &BlocksAvailable,
+ &fNeedClock);
+
+ EIP74_GENERATE_CNT_RD(Device, &GenBlockCount);
+ EIP74_RESEED_THR_RD(Device, &ReseedThr);
+
+ Status_p->GenerateBlockCount = GenBlockCount;
+ Status_p->fStuckOut = fStuckOut;
+ Status_p->fNotInitialized = fGenPktError;
+ Status_p->fReseedError = GenBlockCount == ReseedThr;
+ Status_p->fReseedWarning = fEarlyReseed;
+ Status_p->fInstantiated = fInstantiated;
+ Status_p->AvailableCount = BlocksAvailable;
+
+ return EIP74_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP74_Clear
+ */
+EIP74_Error_t
+EIP74_Clear(
+ EIP74_IOArea_t * const IOArea_p)
+{
+ Device_Handle_t Device;
+ volatile EIP74_True_IOArea_t * const TrueIOArea_p =
+ (EIP74_True_IOArea_t *)IOArea_p;
+ EIP74_CHECK_POINTER(IOArea_p);
+
+ Device = TrueIOArea_p->Device;
+
+ EIP74_INTACK_WR(Device, false, true, false);
+
+ return EIP74_NO_ERROR;
+}
+
+
+/* end of file eip74.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_event.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_event.c
new file mode 100644
index 0000000..cf47963
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_event.c
@@ -0,0 +1,409 @@
+/* eip97_global_event.c
+ *
+ * EIP-97 Global Control Driver Library
+ * Event Management Module
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip97_global_event.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_eip97_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // uint32_t
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+
+// EIP-97 Global Control Driver Library Internal interfaces
+#include "eip97_global_internal.h"
+#include "eip202_global_level0.h" // EIP-202 Level 0 macros
+#include "eip96_level0.h" // EIP-96 Level 0 macros
+#include "eip97_global_fsm.h" // State machine
+#include "eip97_global_level0.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+#ifdef EIP97_REG_DBG_BASE
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Debug_Statistics_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_Debug_Statistics_Get(
+ EIP97_Global_IOArea_t * const IOArea_p,
+ EIP97_Global_Debug_Statistics_t * const Debug_Statistics_p)
+{
+ Device_Handle_t Device;
+ unsigned int i;
+ volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+ EIP97_GLOBAL_CHECK_POINTER(Debug_Statistics_p);
+
+ Device = TrueIOArea_p->Device;
+
+ for (i = 0; i < 16; i++)
+ {
+ EIP97_DBG_RING_IN_COUNT_RD(Device,
+ i,
+ &Debug_Statistics_p->Ifc_Packets_In[i]);
+ EIP97_DBG_RING_OUT_COUNT_RD(Device,
+ i,
+ &Debug_Statistics_p->Ifc_Packets_Out[i]);
+
+ }
+ for (i = 0; i < EIP97_GLOBAL_MAX_NOF_PE_TO_USE; i++)
+ {
+ EIP97_DBG_PIPE_COUNT_RD(Device,
+ i,
+ &Debug_Statistics_p->Pipe_Total_Packets[i],
+ &Debug_Statistics_p->Pipe_Current_Packets[i],
+ &Debug_Statistics_p->Pipe_Max_Packets[i]);
+ EIP97_DBG_PIPE_DCOUNT_RD(Device,
+ i,
+ &Debug_Statistics_p->Pipe_Data_Count[i]);
+ }
+ for (i = EIP97_GLOBAL_MAX_NOF_PE_TO_USE; i < 16; i++)
+ {
+ Debug_Statistics_p->Pipe_Total_Packets[i] = 0;
+ Debug_Statistics_p->Pipe_Current_Packets[i] = 0;
+ Debug_Statistics_p->Pipe_Max_Packets[i] = 0;
+ Debug_Statistics_p->Pipe_Data_Count[i] = 0;
+ }
+ return 0;
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_DFE_Status_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_DFE_Status_Get(
+ EIP97_Global_IOArea_t * const IOArea_p,
+ const unsigned int PE_Number,
+ EIP97_Global_DFE_Status_t * const DFE_Status_p)
+{
+ Device_Handle_t Device;
+ volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+ unsigned int DFEDSEOffset;
+ DFEDSEOffset = EIP97_DFEDSE_Offset_Get();
+
+ EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+ EIP97_GLOBAL_CHECK_POINTER(DFE_Status_p);
+
+ if(PE_Number >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+ return EIP97_GLOBAL_ARGUMENT_ERROR;
+
+ Device = TrueIOArea_p->Device;
+
+ EIP202_DFE_TRD_STAT_RD(Device,
+ DFEDSEOffset,
+ PE_Number,
+ &DFE_Status_p->CDFifoWord32Count,
+ &DFE_Status_p->CDR_ID,
+ &DFE_Status_p->DMASize,
+ &DFE_Status_p->fAtDMABusy,
+ &DFE_Status_p->fDataDMABusy,
+ &DFE_Status_p->fDMAError);
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+ {
+ EIP97_Global_Error_t rv;
+
+ if(DFE_Status_p->fDMAError)
+ rv = EIP97_Global_State_Set(
+ (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+ EIP97_GLOBAL_STATE_FATAL_ERROR);
+ else
+ // Remain in the current state
+ rv = EIP97_Global_State_Set(
+ (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+ (EIP97_Global_State_t)TrueIOArea_p->State);
+ if(rv != EIP97_GLOBAL_NO_ERROR)
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_DSE_Status_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_DSE_Status_Get(
+ EIP97_Global_IOArea_t * const IOArea_p,
+ const unsigned int PE_Number,
+ EIP97_Global_DSE_Status_t * const DSE_Status_p)
+{
+ Device_Handle_t Device;
+ volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+ unsigned int DFEDSEOffset;
+ DFEDSEOffset = EIP97_DFEDSE_Offset_Get();
+
+ EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+ EIP97_GLOBAL_CHECK_POINTER(DSE_Status_p);
+
+ if(PE_Number >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+ return EIP97_GLOBAL_ARGUMENT_ERROR;
+
+ Device = TrueIOArea_p->Device;
+
+ EIP202_DSE_TRD_STAT_RD(Device,
+ DFEDSEOffset,
+ PE_Number,
+ &DSE_Status_p->RDFifoWord32Count,
+ &DSE_Status_p->RDR_ID,
+ &DSE_Status_p->DMASize,
+ &DSE_Status_p->fDataFlushBusy,
+ &DSE_Status_p->fDataDMABusy,
+ &DSE_Status_p->fDMAError);
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+ {
+ EIP97_Global_Error_t rv;
+
+ if(DSE_Status_p->fDMAError)
+ rv = EIP97_Global_State_Set(
+ (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+ EIP97_GLOBAL_STATE_FATAL_ERROR);
+ else
+ // Remain in the current state
+ rv = EIP97_Global_State_Set(
+ (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+ (EIP97_Global_State_t)TrueIOArea_p->State);
+ if(rv != EIP97_GLOBAL_NO_ERROR)
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_EIP96_Token_Status_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_EIP96_Token_Status_Get(
+ EIP97_Global_IOArea_t * const IOArea_p,
+ const unsigned int PE_Number,
+ EIP96_Token_Status_t * const Token_Status_p)
+{
+ Device_Handle_t Device;
+ volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+ EIP97_GLOBAL_CHECK_POINTER(Token_Status_p);
+
+ if(PE_Number >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+ return EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR;
+
+ Device = TrueIOArea_p->Device;
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+ {
+ EIP97_Global_Error_t rv;
+
+ // Remain in the current state
+ rv = EIP97_Global_State_Set(
+ (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+ (EIP97_Global_State_t)TrueIOArea_p->State);
+ if(rv != EIP97_GLOBAL_NO_ERROR)
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+ EIP96_TOKEN_CTRL_STAT_RD(Device,
+ PE_Number,
+ &Token_Status_p->ActiveTokenCount,
+ &Token_Status_p->fTokenLocationAvailable,
+ &Token_Status_p->fResultTokenAvailable,
+ &Token_Status_p->fTokenReadActive,
+ &Token_Status_p->fContextCacheActive,
+ &Token_Status_p->fContextFetch,
+ &Token_Status_p->fResultContext,
+ &Token_Status_p->fProcessingHeld,
+ &Token_Status_p->fBusy);
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_EIP96_Context_Status_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_EIP96_Context_Status_Get(
+ EIP97_Global_IOArea_t * const IOArea_p,
+ const unsigned int PE_Number,
+ EIP96_Context_Status_t * const Context_Status_p)
+{
+ Device_Handle_t Device;
+ volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+ EIP97_GLOBAL_CHECK_POINTER(Context_Status_p);
+
+ if(PE_Number >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+ return EIP97_GLOBAL_ARGUMENT_ERROR;
+
+ Device = TrueIOArea_p->Device;
+
+ EIP96_CONTEXT_STAT_RD(Device,
+ PE_Number,
+ &Context_Status_p->Error,
+ &Context_Status_p->AvailableTokenCount,
+ &Context_Status_p->fActiveContext,
+ &Context_Status_p->fNextContext,
+ &Context_Status_p->fResultContext,
+ &Context_Status_p->fErrorRecovery);
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+ {
+ EIP97_Global_Error_t rv;
+
+ if((Context_Status_p->Error & EIP96_TIMEOUT_FATAL_ERROR_MASK) != 0)
+ rv = EIP97_Global_State_Set(
+ (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+ EIP97_GLOBAL_STATE_FATAL_ERROR);
+ else
+ // Remain in the current state
+ rv = EIP97_Global_State_Set(
+ (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+ (EIP97_Global_State_t)TrueIOArea_p->State);
+ if(rv != EIP97_GLOBAL_NO_ERROR)
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_EIP96_OutXfer_Status_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_EIP96_OutXfer_Status_Get(
+ EIP97_Global_IOArea_t * const IOArea_p,
+ const unsigned int PE_Number,
+ EIP96_Output_Transfer_Status_t * const OutXfer_Status_p)
+{
+ Device_Handle_t Device;
+ volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+ EIP97_GLOBAL_CHECK_POINTER(OutXfer_Status_p);
+
+ if(PE_Number >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+ return EIP97_GLOBAL_ARGUMENT_ERROR;
+
+ Device = TrueIOArea_p->Device;
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+ {
+ EIP97_Global_Error_t rv;
+
+ // Remain in the current state
+ rv = EIP97_Global_State_Set((volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+ (EIP97_Global_State_t)TrueIOArea_p->State);
+ if(rv != EIP97_GLOBAL_NO_ERROR)
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+ EIP96_OUT_TRANS_CTRL_STAT_RD(Device,
+ PE_Number,
+ &OutXfer_Status_p->AvailableWord32Count,
+ &OutXfer_Status_p->MinTransferWordCount,
+ &OutXfer_Status_p->MaxTransferWordCount,
+ &OutXfer_Status_p->TransferSizeMask);
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_EIP96_PRNG_Status_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_EIP96_PRNG_Status_Get(
+ EIP97_Global_IOArea_t * const IOArea_p,
+ const unsigned int PE_Number,
+ EIP96_PRNG_Status_t * const PRNG_Status_p)
+{
+ Device_Handle_t Device;
+ volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+ EIP97_GLOBAL_CHECK_POINTER(PRNG_Status_p);
+
+ if(PE_Number >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+ return EIP97_GLOBAL_ARGUMENT_ERROR;
+
+ Device = TrueIOArea_p->Device;
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+ {
+ EIP97_Global_Error_t rv;
+
+ // Remain in the current state
+ rv = EIP97_Global_State_Set((volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+ (EIP97_Global_State_t)TrueIOArea_p->State);
+ if(rv != EIP97_GLOBAL_NO_ERROR)
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+ EIP96_PRNG_STAT_RD(Device,
+ PE_Number,
+ &PRNG_Status_p->fBusy,
+ &PRNG_Status_p->fResultReady);
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/* end of file eip97_global_event.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_fsm.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_fsm.c
new file mode 100644
index 0000000..e3f5ffb
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_fsm.c
@@ -0,0 +1,164 @@
+/* eip97_global_fsm.c
+ *
+ * EIP-97 Global Control Driver Library API State Machine Internal Interface
+ * implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip97_global_fsm.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// EIP-97 Driver Library Types API
+#include "eip97_global_types.h" // EIP97_Global_* types
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_State_Set
+ *
+ */
+EIP97_Global_Error_t
+EIP97_Global_State_Set(
+ volatile EIP97_Global_State_t * const CurrentState,
+ const EIP97_Global_State_t NewState)
+{
+ switch(*CurrentState)
+ {
+ case EIP97_GLOBAL_STATE_UNKNOWN:
+ switch(NewState)
+ {
+ case EIP97_GLOBAL_STATE_SW_RESET_START:
+ *CurrentState = NewState;
+ break;
+ case EIP97_GLOBAL_STATE_SW_RESET_DONE:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP97_GLOBAL_STATE_HW_RESET_DONE:
+ switch(NewState)
+ {
+ case EIP97_GLOBAL_STATE_INITIALIZED:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP97_GLOBAL_STATE_SW_RESET_START:
+ switch(NewState)
+ {
+ case EIP97_GLOBAL_STATE_SW_RESET_DONE:
+ *CurrentState = NewState;
+ break;
+ case EIP97_GLOBAL_STATE_SW_RESET_START:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP97_GLOBAL_STATE_SW_RESET_DONE:
+ switch(NewState)
+ {
+ case EIP97_GLOBAL_STATE_SW_RESET_DONE:
+ case EIP97_GLOBAL_STATE_INITIALIZED:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP97_GLOBAL_STATE_INITIALIZED:
+ switch(NewState)
+ {
+ case EIP97_GLOBAL_STATE_ENABLED:
+ *CurrentState = NewState;
+ break;
+ case EIP97_GLOBAL_STATE_SW_RESET_DONE:
+ *CurrentState = NewState;
+ break;
+ case EIP97_GLOBAL_STATE_INITIALIZED:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP97_GLOBAL_STATE_ENABLED:
+ switch(NewState)
+ {
+ case EIP97_GLOBAL_STATE_SW_RESET_START:
+ *CurrentState = NewState;
+ break;
+ case EIP97_GLOBAL_STATE_SW_RESET_DONE:
+ *CurrentState = NewState;
+ break;
+ case EIP97_GLOBAL_STATE_FATAL_ERROR:
+ break;
+ case EIP97_GLOBAL_STATE_ENABLED:
+ break;
+ default:
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ case EIP97_GLOBAL_STATE_FATAL_ERROR:
+ switch(NewState)
+ {
+ case EIP97_GLOBAL_STATE_SW_RESET_START:
+ *CurrentState = NewState;
+ break;
+ case EIP97_GLOBAL_STATE_SW_RESET_DONE:
+ *CurrentState = NewState;
+ break;
+ default:
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+ break;
+
+ default:
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/* end of file eip97_global_fsm.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_fsm_stub.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_fsm_stub.c
new file mode 100644
index 0000000..4289875
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_fsm_stub.c
@@ -0,0 +1,68 @@
+/* eip97_global_fsm_stub.c
+ *
+ * EIP-97 Global Control Driver Library API State Machine Internal Interface
+ * stub implementation
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip97_global_fsm.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // IDENTIFIER_NOT_USED
+
+// EIP-97 Driver Library Types API
+#include "eip97_global_types.h" // EIP97_Global_* types
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_State_Set
+ *
+ */
+EIP97_Global_Error_t
+EIP97_Global_State_Set(
+ EIP97_Global_State_t * const CurrentState,
+ const EIP97_Global_State_t NewState)
+{
+ IDENTIFIER_NOT_USED(CurrentState);
+ IDENTIFIER_NOT_USED((bool)NewState);
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/* end of file eip97_global_fsm_stub.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_init.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_init.c
new file mode 100644
index 0000000..5f060cb
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_init.c
@@ -0,0 +1,827 @@
+/* eip97_global_init.c
+ *
+ * EIP-97 Global Control Driver Library
+ * Initialization Module
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip97_global_init.h"
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+
+// Default configuration
+#include "c_eip97_global.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // uint32_t
+
+// Driver Framework C Run-time Library API
+#include "clib.h" // ZEROINIT
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+
+// EIP-97 Global Control Driver Library Internal interfaces
+#include "eip97_global_internal.h"
+#include "eip97_global_level0.h" // EIP-97 Level 0 macros
+#include "eip202_global_init.h" // EIP-202 Initialization code
+#include "eip206_level0.h" // EIP-206 Level 0 macros
+#include "eip96_level0.h" // EIP-96 Level 0 macros
+#include "eip97_global_fsm.h" // State machine
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+// Maximum number of Packet Engines that should be used
+// Driver Library will check the maximum number supported run-time
+#ifndef EIP97_GLOBAL_MAX_NOF_PE_TO_USE
+#error "EIP97_GLOBAL_MAX_NOF_PE_TO_USE is not defined"
+#endif
+
+// Number of Ring interfaces
+// Maximum number of Ring interfaces that should be used
+// Driver Library will check the maximum number supported run-time
+#ifndef EIP97_GLOBAL_MAX_NOF_RING_TO_USE
+#error "EIP97_GLOBAL_MAX_NOF_RING_TO_USE is not defined"
+#endif
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+static unsigned int Global97_NofPEs;
+static unsigned int Global97_NofRings;
+static unsigned int Global97_NofLA;
+static unsigned int Global97_NofIN;
+static unsigned int Global97_DFEDSEOffset;
+static unsigned int Global97_SupportedFuncs;
+
+/*----------------------------------------------------------------------------
+ * EIP206Lib_Detect
+ *
+ * Checks the presence of EIP-206 PE hardware. Returns true when found.
+ */
+static bool
+EIP206Lib_Detect(
+ const Device_Handle_t Device,
+ const unsigned int PEnr)
+{
+ uint32_t Value;
+
+ // No revision register for this HW version
+
+ // read-write test one of the registers
+
+ // Set MASK_8_BITS bits of the EIP206_OUT_REG_DBUF_TRESH register
+ EIP206_Write32(Device,
+ EIP206_OUT_REG_DBUF_TRESH(PEnr),
+ MASK_8_BITS);
+ Value = EIP206_Read32(Device,
+ EIP206_OUT_REG_DBUF_TRESH(PEnr));
+ if ((Value & MASK_8_BITS) != MASK_8_BITS)
+ return false;
+
+ // Clear MASK_8_BITS bits of the EIP206_OUT_REG_DBUF_TRESH(PEnr) register
+ EIP206_Write32(Device, EIP206_OUT_REG_DBUF_TRESH(PEnr), 0);
+ Value = EIP206_Read32(Device, EIP206_OUT_REG_DBUF_TRESH(PEnr));
+ if ((Value & MASK_8_BITS) != 0)
+ return false;
+
+ return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP96Lib_Detect
+ *
+ * Checks the presence of EIP-96 Engine hardware. Returns true when found.
+ */
+static bool
+EIP96Lib_Detect(
+ const Device_Handle_t Device,
+ const unsigned int PEnr)
+{
+ uint32_t Value, DefaultValue;
+ bool fSuccess = true;
+
+ // No revision register for this HW version
+
+ // Save the default register value
+ DefaultValue = EIP96_Read32(Device,
+ EIP96_REG_CONTEXT_CTRL(PEnr));
+
+ // read-write test one of the registers
+
+ // Set MASK_6_BITS bits of the EIP96_REG_CONTEXT_CTRL register
+ EIP96_Write32(Device,
+ EIP96_REG_CONTEXT_CTRL(PEnr),
+ MASK_6_BITS );
+ Value = EIP96_Read32(Device, EIP96_REG_CONTEXT_CTRL(PEnr));
+ if ((Value & MASK_6_BITS) != MASK_6_BITS)
+ fSuccess = false;
+
+ if( fSuccess )
+ {
+ // Clear MASK_6_BITS bits of the EIP96_REG_CONTEXT_CTRL register
+ EIP96_Write32(Device, EIP96_REG_CONTEXT_CTRL(PEnr), 0);
+ Value = EIP96_Read32(Device, EIP96_REG_CONTEXT_CTRL(PEnr));
+ if ((Value & MASK_6_BITS) != 0)
+ fSuccess = false;
+ }
+
+ // Restore the default register value
+ EIP96_Write32(Device,
+ EIP96_REG_CONTEXT_CTRL(PEnr),
+ DefaultValue );
+ return fSuccess;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97Lib_Detect
+ *
+ * Checks the presence of EIP-97 Engine hardware. Returns true when found.
+ */
+static bool
+EIP97Lib_Detect(
+ const Device_Handle_t Device)
+{
+#ifdef EIP97_GLOBAL_VERSION_CHECK_ENABLE
+ uint32_t Value;
+
+ // read and check the revision register
+ Value = EIP97_Read32(Device, EIP97_REG_VERSION);
+ if (!EIP97_REV_SIGNATURE_MATCH( Value ))
+ return false;
+#else
+ IDENTIFIER_NOT_USED(Device);
+#endif // EIP97_GLOBAL_VERSION_CHECK_ENABLE
+
+ return true;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP202Lib_HWRevision_Get
+ */
+static void
+EIP202Lib_HWRevision_Get(
+ const Device_Handle_t Device,
+ EIP202_Options_t * const Options_p,
+ EIP202_Options2_t * const Options2_p,
+ EIP_Version_t * const Version_p)
+{
+ EIP202_Capabilities_t EIP202_Capabilities;
+ EIP202_Global_HWRevision_Get(Device, &EIP202_Capabilities);
+
+ Version_p->EipNumber = EIP202_Capabilities.EipNumber;
+ Version_p->ComplmtEipNumber = EIP202_Capabilities.ComplmtEipNumber;
+ Version_p->HWPatchLevel = EIP202_Capabilities.HWPatchLevel;
+ Version_p->MinHWRevision = EIP202_Capabilities.MinHWRevision;
+ Version_p->MajHWRevision = EIP202_Capabilities.MajHWRevision;
+
+ Options_p->NofRings = EIP202_Capabilities.NofRings;
+ Options_p->NofPes = EIP202_Capabilities.NofPes;
+ Options_p->fExpPlf = EIP202_Capabilities.fExpPlf;
+ Options_p->CF_Size = EIP202_Capabilities.CF_Size;
+ Options_p->RF_Size = EIP202_Capabilities.RF_Size;
+ Options_p->HostIfc = EIP202_Capabilities.HostIfc;
+ Options_p->DMA_Len = EIP202_Capabilities.DMA_Len;
+ Options_p->HDW = EIP202_Capabilities.HDW;
+ Options_p->TgtAlign = EIP202_Capabilities.TgtAlign;
+ Options_p->fAddr64 = EIP202_Capabilities.fAddr64;
+
+ Options2_p->NofLA_Ifs = EIP202_Capabilities.NofLA_Ifs;
+ Options2_p->NofIN_Ifs = EIP202_Capabilities.NofIN_Ifs;
+ Options2_p->NofAXI_WrChs = EIP202_Capabilities.NofAXI_WrChs;
+ Options2_p->NofAXI_RdClusters = EIP202_Capabilities.NofAXI_RdClusters;
+ Options2_p->NofAXI_RdCPC = EIP202_Capabilities.NofAXI_RdCPC;
+
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP96Lib_HWRevision_Get
+ */
+static void
+EIP96Lib_HWRevision_Get(
+ const Device_Handle_t Device,
+ const unsigned int PEnr,
+ EIP96_Options_t * const Options_p,
+ EIP_Version_t * const Version_p)
+{
+ uint32_t OptionsVal;
+ EIP96_EIP_REV_RD(Device,
+ PEnr,
+ &Version_p->EipNumber,
+ &Version_p->ComplmtEipNumber,
+ &Version_p->HWPatchLevel,
+ &Version_p->MinHWRevision,
+ &Version_p->MajHWRevision);
+
+ EIP96_OPTIONS_RD(Device,
+ PEnr,
+ &Options_p->fAES,
+ &Options_p->fAESfb,
+ &Options_p->fAESspeed,
+ &Options_p->fDES,
+ &Options_p->fDESfb,
+ &Options_p->fDESspeed,
+ &Options_p->ARC4,
+ &Options_p->fAES_XTS,
+ &Options_p->fWireless,
+ &Options_p->fMD5,
+ &Options_p->fSHA1,
+ &Options_p->fSHA1speed,
+ &Options_p->fSHA224_256,
+ &Options_p->fSHA384_512,
+ &Options_p->fXCBC_MAC,
+ &Options_p->fCBC_MACspeed,
+ &Options_p->fCBC_MACkeylens,
+ &Options_p->fGHASH);
+ Global97_SupportedFuncs = Device_Read32(Device, EIP96_REG_OPTIONS(0)) & 0xfffffff0;
+ OptionsVal = Device_Read32(Device, EIP97_REG_OPTIONS);
+ if ((OptionsVal & BIT_30) != 0)
+ {
+ Global97_SupportedFuncs |= BIT_3;
+ }
+ if ((OptionsVal & BIT_25) != 0)
+ {
+ Global97_SupportedFuncs |= BIT_2;
+ }
+ if ((OptionsVal & BIT_24) != 0)
+ {
+ Global97_SupportedFuncs |= BIT_1;
+ }
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97Lib_HWRevision_Get
+ */
+static void
+EIP97Lib_HWRevision_Get(
+ const Device_Handle_t Device,
+ EIP97_Options_t * const Options_p,
+ EIP_Version_t * const Version_p)
+{
+ EIP97_EIP_REV_RD(Device,
+ &Version_p->EipNumber,
+ &Version_p->ComplmtEipNumber,
+ &Version_p->HWPatchLevel,
+ &Version_p->MinHWRevision,
+ &Version_p->MajHWRevision);
+
+ EIP97_OPTIONS_RD(Device,
+ &Options_p->NofPes,
+ &Options_p->in_tbuf_size,
+ &Options_p->in_dbuf_size,
+ &Options_p->out_tbuf_size,
+ &Options_p->out_dbuf_size,
+ &Options_p->central_prng,
+ &Options_p->tg,
+ &Options_p->trc);
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97Lib_Reset_IsDone
+ */
+static EIP97_Global_Error_t
+EIP97Lib_Reset_IsDone(
+ const Device_Handle_t Device,
+ volatile uint32_t * State_p,
+ const unsigned int PEnr)
+{
+ bool fResetDone = EIP202_Global_Reset_IsDone(Device, PEnr);
+
+ if(fResetDone)
+ {
+ // Transit to a new state
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+ {
+ EIP97_Global_Error_t rv;
+
+ rv = EIP97_Global_State_Set((volatile EIP97_Global_State_t*)State_p,
+ EIP97_GLOBAL_STATE_SW_RESET_DONE);
+ if(rv != EIP97_GLOBAL_NO_ERROR)
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+ }
+ else
+ {
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+ {
+ EIP97_Global_Error_t rv;
+
+ // SW Reset is ongoing, retry later
+ rv = EIP97_Global_State_Set((volatile EIP97_Global_State_t*)State_p,
+ EIP97_GLOBAL_STATE_SW_RESET_START);
+ if(rv != EIP97_GLOBAL_NO_ERROR)
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+ return EIP97_GLOBAL_BUSY_RETRY_LATER;
+ }
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Init
+ */
+EIP97_Global_Error_t
+EIP97_Global_Init(
+ EIP97_Global_IOArea_t * const IOArea_p,
+ const Device_Handle_t Device)
+{
+ unsigned int i;
+ EIP97_Global_Capabilities_t Capabilities;
+ volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ ZEROINIT(Capabilities);
+
+ EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+
+ // Attempt to initialize slave byte swapping.
+ if (!EIP202_Global_Endianness_Slave_Configure(Device))
+ return EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR;
+
+ // Detect presence of the EIP-97 HW hardware
+ if (!EIP202_Global_Detect(Device) ||
+ !EIP206Lib_Detect(Device, PE_DEFAULT_NR) ||
+ !EIP96Lib_Detect(Device, PE_DEFAULT_NR) ||
+ !EIP97Lib_Detect(Device))
+ return EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR;
+
+ // Initialize the IO Area
+ TrueIOArea_p->Device = Device;
+ // Can also be EIP97_GLOBAL_STATE_HW_RESET_DONE
+ TrueIOArea_p->State = (uint32_t)EIP97_GLOBAL_STATE_SW_RESET_DONE;
+
+ EIP97Lib_HWRevision_Get(Device,
+ &Capabilities.EIP97_Options,
+ &Capabilities.EIP97_Version);
+
+ EIP202Lib_HWRevision_Get(Device,
+ &Capabilities.EIP202_Options,
+ &Capabilities.EIP202_Options2,
+ &Capabilities.EIP202_Version);
+
+ EIP96Lib_HWRevision_Get(Device,
+ PE_DEFAULT_NR,
+ &Capabilities.EIP96_Options,
+ &Capabilities.EIP96_Version);
+
+ // Check actual configuration HW against capabilities
+ // Number of configured PE's
+ Global97_NofPEs = MIN(Capabilities.EIP202_Options.NofPes,
+ EIP97_GLOBAL_MAX_NOF_PE_TO_USE);
+
+ // Number of configure ring interfaces
+ Global97_NofRings = MIN(Capabilities.EIP202_Options.NofRings,
+ EIP97_GLOBAL_MAX_NOF_RING_TO_USE);
+
+ // Number of configured Look-aside FIFO interfaces
+#if EIP97_GLOBAL_MAX_NOF_LAFIFO_TO_USE==0
+ Global97_NofLA = 0;
+#else
+ Global97_NofLA = MIN(Capabilities.EIP202_Options2.NofLA_Ifs,
+ EIP97_GLOBAL_MAX_NOF_LAFIFO_TO_USE);
+#endif
+#if EIP97_GLOBAL_MAX_NOF_INFIFO_TO_USE==0
+ Global97_NofIN = 0;
+#else
+ // Number of configured Inline FIFO interfaces
+ Global97_NofIN = MIN(Capabilities.EIP202_Options2.NofIN_Ifs,
+ EIP97_GLOBAL_MAX_NOF_INFIFO_TO_USE);
+#endif
+
+ // EIP197 devices with more than 12 rings move the
+ // DFE and DSE register addresses up by 2*4kB to make room for 2 extra
+ // sets of ring control registers.
+ if (Capabilities.EIP202_Options.NofRings > 12)
+ {
+ Global97_DFEDSEOffset = 0x2000;
+ }
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+ {
+ EIP97_Global_Error_t rv;
+
+ // Transit to a new state
+ rv = EIP97_Global_State_Set(
+ (volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+ EIP97_GLOBAL_STATE_INITIALIZED);
+ if(rv != EIP97_GLOBAL_NO_ERROR)
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+ // Configure Endianness Conversion method for master (DMA) interface
+ for (i = 0; i < Global97_NofPEs; i++)
+ EIP97_MST_CTRL_WR(Device,
+ i,
+ EIP97_GLOBAL_RD_CACHE_VALUE,
+ EIP97_GLOBAL_WR_CACHE_VALUE,
+ EIP97_GLOBAL_BYTE_SWAP_METHOD,
+ EIP97_GLOBAL_SUPPORT_PROTECT_VALUE,
+ 0, // Disable cache-aligned context writes.
+ false);
+ {
+ uint8_t ipbuf_max, ipbuf_min,
+ itbuf_max, itbuf_min,
+ opbuf_max, opbuf_min;
+
+#ifdef EIP97_GLOBAL_THRESH_CONFIG_AUTO
+ // Calculate the EIP-202 and EIP-206 Global Control thresholds
+ uint8_t dmalen;
+
+ // Convert to powers of byte counts from powers of 32-bit word counts
+ ipbuf_max = Capabilities.EIP97_Options.in_dbuf_size + 2;
+ itbuf_max = Capabilities.EIP97_Options.in_tbuf_size + 2;
+ opbuf_max = Capabilities.EIP97_Options.out_dbuf_size + 2;
+
+ // EIP-96 token cannot be larger than 2^7 bytes
+ if( itbuf_max > EIP97_GLOBAL_MAX_TOKEN_SIZE )
+ itbuf_max = EIP97_GLOBAL_MAX_TOKEN_SIZE;
+
+ // DMA_Len is power of byte count
+ if (Capabilities.EIP202_Options.DMA_Len >= 1)
+ dmalen = Capabilities.EIP202_Options.DMA_Len - 1;
+ else
+ dmalen = Capabilities.EIP202_Options.DMA_Len;
+
+ ipbuf_max = MIN(ipbuf_max, dmalen);
+ itbuf_max = MIN(itbuf_max, dmalen);
+ opbuf_max = MIN(opbuf_max, dmalen);
+
+ ipbuf_min = ipbuf_max - 1;
+ itbuf_min = itbuf_max - 1;
+ opbuf_min = opbuf_max - 1;
+#else
+ // Use configured statically
+ // the EIP-202 and EIP-206 Global Control thresholds
+ ipbuf_min = EIP97_GLOBAL_DFE_MIN_DATA_XFER_SIZE;
+ ipbuf_max = EIP97_GLOBAL_DFE_MAX_DATA_XFER_SIZE;
+
+ itbuf_min = EIP97_GLOBAL_DFE_MIN_TOKEN_XFER_SIZE;
+ itbuf_max = EIP97_GLOBAL_DFE_MAX_TOKEN_XFER_SIZE;
+
+ opbuf_min = EIP97_GLOBAL_DSE_MIN_DATA_XFER_SIZE;
+ opbuf_max = EIP97_GLOBAL_DSE_MAX_DATA_XFER_SIZE;
+#endif
+
+ EIP202_Global_Init(Device,
+ Global97_NofPEs,
+ Capabilities.EIP202_Options2.NofLA_Ifs,
+ ipbuf_min,
+ ipbuf_max,
+ itbuf_min,
+ itbuf_max,
+ opbuf_min,
+ opbuf_max);
+ for (i = 0; i < Global97_NofPEs; i++)
+ {
+
+ // Configure EIP-206 Processing Engine
+ EIP206_IN_DBUF_THRESH_WR(
+ Device,
+ i,
+ 0,
+ ipbuf_min,
+ ipbuf_max); // ... or use 0xF for maximum, autoconf
+
+ EIP206_IN_TBUF_THRESH_WR(
+ Device,
+ i,
+ EIP97_GLOBAL_IN_TBUF_PKT_THR,
+ itbuf_min,
+ itbuf_max); // ... or use 0xF for maximum, autoconf
+
+ EIP206_OUT_DBUF_THRESH_WR(
+ Device,
+ i,
+ opbuf_min,
+ opbuf_max); // ... or use 0xF for maximum, autoconf
+
+ // Configure EIP-96 Packet Engine
+ EIP96_TOKEN_CTRL_STAT_WR(
+ Device,
+ i,
+ true, /* optimal context update */
+ EIP97_GLOBAL_EIP96_NO_TOKEN_WAIT, /* CT No token wait */
+ false, /* Absulute ARC4 pointer */
+ false, /* Allow reuse cached context */
+ false, /* Allow postponed reuse */
+ false, /* Zero length result */
+ (EIP97_GLOBAL_EIP96_TIMEOUT_CNTR_FLAG == 0) ? false : true,
+ (EIP97_GLOBAL_EIP96_EXTENDED_ERRORS_ENABLE == 0) ? false : true
+ );
+ EIP96_TOKEN_CTRL2_WR(
+ Device,
+ i,
+ true,
+ true,
+ false,
+ EIP97_GLOBAL_EIP96_CTX_DONE_PULSE);
+ EIP96_OUT_BUF_CTRL_WR(
+ Device,
+ i,
+ EIP97_GLOBAL_EIP96_PE_HOLD_OUTPUT_DATA,
+ (EIP97_GLOBAL_EIP96_BLOCK_UPDATE_APPEND == 0) ? false : true,
+ (EIP97_GLOBAL_EIP96_LEN_DELTA_ENABLE == 0) ? false : true);
+ EIP96_CONTEXT_CTRL_WR(
+ Device,
+ i,
+ EIP97_EIP96_CTX_SIZE,
+ false,
+ true);
+ EIP96_CTX_NUM32_THR_WR(
+ Device,
+ i,
+ EIP97_GLOBAL_EIP96_NUM32_THR);
+ EIP96_CTX_NUM64_THR_L_WR(
+ Device,
+ i,
+ EIP97_GLOBAL_EIP96_NUM64_THR_L);
+ EIP96_CTX_NUM64_THR_H_WR(
+ Device,
+ i,
+ EIP97_GLOBAL_EIP96_NUM64_THR_H);
+#ifdef EIP97_GLOBAL_HAVE_ECN_FIXUP
+ EIP96_ECN_TABLE_WR(Device, i, 0,
+ 0, 0,
+ 1, 0,
+ 2, 0,
+ 3, 0);
+ EIP96_ECN_TABLE_WR(Device, i, 1,
+ 0, EIP96_ECN_CLE0,
+ 1, 0,
+ 1, 0,
+ 3, EIP96_ECN_CLE1);
+ EIP96_ECN_TABLE_WR(Device, i, 2,
+ 0, EIP96_ECN_CLE2,
+ 1, EIP96_ECN_CLE3,
+ 2, 0,
+ 3, 0);
+ EIP96_ECN_TABLE_WR(Device, i, 3,
+ 0, EIP96_ECN_CLE4,
+ 3, 0,
+ 3, 0,
+ 3, 0);
+#endif
+ } // for
+
+ } // EIP-202 HIA Global is configured
+
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Reset
+ */
+EIP97_Global_Error_t
+EIP97_Global_Reset(
+ EIP97_Global_IOArea_t * const IOArea_p,
+ const Device_Handle_t Device)
+{
+ volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+ unsigned int i;
+
+ EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+
+ // Attempt to initialize slave byte swapping.
+ if (!EIP202_Global_Endianness_Slave_Configure(Device))
+ return EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR;
+
+ // Initialize the IO Area
+ TrueIOArea_p->Device = Device;
+ // Assume this function is called in the Unknown state but
+ // this may not always be true
+ TrueIOArea_p->State = (uint32_t)EIP97_GLOBAL_STATE_UNKNOWN;
+
+ if (!EIP202_Global_Reset(Device, Global97_NofPEs))
+ return EIP97_GLOBAL_UNSUPPORTED_FEATURE_ERROR;
+
+ for (i = 0; i < Global97_NofPEs; i++)
+ {
+ // Restore the EIP-206 default configuration
+ EIP206_IN_DBUF_THRESH_DEFAULT_WR(Device, i);
+ EIP206_IN_TBUF_THRESH_DEFAULT_WR(Device, i);
+ EIP206_OUT_DBUF_THRESH_DEFAULT_WR(Device, i);
+ EIP206_OUT_TBUF_THRESH_DEFAULT_WR(Device, i);
+
+ // Restore the EIP-96 default configuration
+ EIP96_TOKEN_CTRL_STAT_DEFAULT_WR(Device, i);
+ }
+
+ // Check if Global SW Reset is done
+ for (i = 0; i < Global97_NofPEs; i++)
+ {
+ EIP97_Global_Error_t EIP97_Rc;
+
+ EIP97_Rc =
+ EIP97Lib_Reset_IsDone(Device, &TrueIOArea_p->State, i);
+
+ if (EIP97_Rc != EIP97_GLOBAL_NO_ERROR)
+ return EIP97_Rc;
+ }
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Reset_IsDone
+ */
+EIP97_Global_Error_t
+EIP97_Global_Reset_IsDone(
+ EIP97_Global_IOArea_t * const IOArea_p)
+{
+ Device_Handle_t Device;
+ volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+ unsigned int i;
+
+ EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+
+ Device = TrueIOArea_p->Device;
+
+ // Check if Global SW Reset is done
+ for (i = 0; i < Global97_NofPEs; i++)
+ {
+ EIP97_Global_Error_t EIP97_Rc;
+
+ EIP97_Rc =
+ EIP97Lib_Reset_IsDone(Device, &TrueIOArea_p->State, i);
+
+ if (EIP97_Rc != EIP97_GLOBAL_NO_ERROR)
+ return EIP97_Rc;
+ }
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_HWRevision_Get
+ */
+EIP97_Global_Error_t
+EIP97_Global_HWRevision_Get(
+ EIP97_Global_IOArea_t * const IOArea_p,
+ EIP97_Global_Capabilities_t * const Capabilities_p)
+{
+ Device_Handle_t Device;
+ volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+ EIP97_GLOBAL_CHECK_POINTER(Capabilities_p);
+
+ Device = TrueIOArea_p->Device;
+
+ EIP202Lib_HWRevision_Get(Device,
+ &Capabilities_p->EIP202_Options,
+ &Capabilities_p->EIP202_Options2,
+ &Capabilities_p->EIP202_Version);
+
+ EIP96Lib_HWRevision_Get(Device,
+ PE_DEFAULT_NR,
+ &Capabilities_p->EIP96_Options,
+ &Capabilities_p->EIP96_Version);
+
+ EIP97Lib_HWRevision_Get(Device,
+ &Capabilities_p->EIP97_Options,
+ &Capabilities_p->EIP97_Version);
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_Configure
+ */
+EIP97_Global_Error_t
+EIP97_Global_Configure(
+ EIP97_Global_IOArea_t * const IOArea_p,
+ const unsigned int PE_Number,
+ const EIP97_Global_Ring_PE_Map_t * const RingPEMap_p)
+{
+ Device_Handle_t Device;
+ volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+ EIP202_Global_Ring_PE_Map_t EIP202RingPEMap;
+
+ EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+ EIP97_GLOBAL_CHECK_POINTER(RingPEMap_p);
+
+ if(PE_Number >= Global97_NofPEs)
+ return EIP97_GLOBAL_ARGUMENT_ERROR;
+
+ Device = TrueIOArea_p->Device;
+
+ // Figure out which rings must be assigned to
+ // DFE and DSE threads for PE_Number
+ EIP202RingPEMap.RingPE_Mask = (uint16_t)(RingPEMap_p->RingPE_Mask &
+ ((1 << (Global97_NofRings + Global97_NofLA + Global97_NofIN))-1));
+ EIP202RingPEMap.RingPrio_Mask = RingPEMap_p->RingPrio_Mask;
+ EIP202RingPEMap.RingSlots0 = RingPEMap_p->RingSlots0;
+ EIP202RingPEMap.RingSlots1 = RingPEMap_p->RingSlots1;
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+ {
+ EIP97_Global_Error_t rv;
+ EIP97_Global_State_t NewState;
+
+ // Transit to a new state
+ if(EIP202RingPEMap.RingPE_Mask != 0)
+ NewState = EIP97_GLOBAL_STATE_ENABLED;
+ else
+ // Engines without rings not allowed!
+ NewState = EIP97_GLOBAL_STATE_INITIALIZED;
+
+ rv = EIP97_Global_State_Set(
+ (volatile EIP97_Global_State_t*)&TrueIOArea_p->State, NewState);
+ if(rv != EIP97_GLOBAL_NO_ERROR)
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+ EIP202_Global_Configure(Device, PE_Number, &EIP202RingPEMap);
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Interfaces_Get
+ */
+void
+EIP97_Interfaces_Get(
+ unsigned int * const NofPEs_p,
+ unsigned int * const NofRings_p,
+ unsigned int * const NofLA_p,
+ unsigned int * const NofIN_p)
+{
+ if (NofPEs_p)
+ *NofPEs_p = Global97_NofPEs;
+ if (NofRings_p)
+ *NofRings_p = Global97_NofRings;
+ if (NofLA_p)
+ *NofLA_p = Global97_NofLA;
+ if (NofIN_p)
+ *NofIN_p = Global97_NofIN;
+}
+
+/*----------------------------------------------------------------------------
+ * EIP97_DFEDSE_Offset_Get
+ */
+unsigned int
+EIP97_DFEDSE_Offset_Get(void)
+{
+ return Global97_DFEDSEOffset;
+}
+
+
+unsigned int
+EIP97_SupportedFuncs_Get(void)
+{
+ return Global97_SupportedFuncs;
+}
+
+
+/* end of file eip97_global_init.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_prng.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_prng.c
new file mode 100644
index 0000000..eb41088
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/eip197/eip97_global_prng.c
@@ -0,0 +1,120 @@
+/* eip97_global_prng.c
+ *
+ * EIP-97 GLobal Control Driver Library
+ * PRNG Module
+ */
+
+/* -------------------------------------------------------------------------- */
+/* */
+/* Module : ddk197 */
+/* Version : 5.6.1 */
+/* Configuration : DDK-197-GPL */
+/* */
+/* Date : 2022-Dec-16 */
+/* */
+/* Copyright (c) 2008-2022 by Rambus, Inc. and/or its subsidiaries. */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation, either version 2 of the License, or */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* -------------------------------------------------------------------------- */
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+#include "eip97_global_prng.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Driver Framework Device API
+#include "device_types.h" // Device_Handle_t
+
+// EIP-97 Global Control Driver Library Internal interfaces
+#include "eip97_global_internal.h"
+#include "eip96_level0.h" // EIP-96 Level 0 macros
+#include "eip97_global_fsm.h" // State machine
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * EIP97_Global_PRNG_Reseed
+ */
+EIP97_Global_Error_t
+EIP97_Global_PRNG_Reseed(
+ EIP97_Global_IOArea_t * const IOArea_p,
+ const unsigned int PE_Number,
+ const EIP96_PRNG_Reseed_t * const ReseedData_p)
+{
+ Device_Handle_t Device;
+ volatile EIP97_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
+
+ EIP97_GLOBAL_CHECK_POINTER(IOArea_p);
+
+ if(PE_Number >= EIP97_GLOBAL_MAX_NOF_PE_TO_USE)
+ return EIP97_GLOBAL_ARGUMENT_ERROR;
+
+ Device = TrueIOArea_p->Device;
+
+#ifdef EIP97_GLOBAL_DEBUG_FSM
+ {
+ EIP97_Global_Error_t rv;
+
+ // Remain in the current state
+ rv = EIP97_Global_State_Set((volatile EIP97_Global_State_t*)&TrueIOArea_p->State,
+ (EIP97_Global_State_t)TrueIOArea_p->State);
+ if(rv != EIP97_GLOBAL_NO_ERROR)
+ return EIP97_GLOBAL_ILLEGAL_IN_STATE;
+ }
+#endif // EIP97_GLOBAL_DEBUG_FSM
+
+ EIP96_PRNG_CTRL_WR(Device,
+ PE_Number, // EIP-96 PE number
+ false, // Disable PRNG
+ false); // Set PRNG Manual mode
+
+ // Write new seed data
+ EIP96_PRNG_SEED_L_WR(Device, PE_Number, ReseedData_p->SeedLo);
+ EIP96_PRNG_SEED_H_WR(Device, PE_Number, ReseedData_p->SeedHi);
+
+ // Write new key data
+ EIP96_PRNG_KEY_0_L_WR(Device, PE_Number, ReseedData_p->Key0Lo);
+ EIP96_PRNG_KEY_0_H_WR(Device, PE_Number, ReseedData_p->Key0Hi);
+ EIP96_PRNG_KEY_1_L_WR(Device, PE_Number, ReseedData_p->Key1Lo);
+ EIP96_PRNG_KEY_1_H_WR(Device, PE_Number, ReseedData_p->Key1Hi);
+
+ // Write new LFSR data
+ EIP96_PRNG_LFSR_L_WR(Device, PE_Number, ReseedData_p->LFSRLo);
+ EIP96_PRNG_LFSR_H_WR(Device, PE_Number, ReseedData_p->LFSRHi);
+
+ EIP96_PRNG_CTRL_WR(Device,
+ PE_Number, // EIP-96 PE number
+ true, // Enable PRNG
+ true); // Set PRNG Auto mode
+
+ return EIP97_GLOBAL_NO_ERROR;
+}
+
+
+/* end of file eip97_global_prng.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/iotoken/iotoken.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/iotoken/iotoken.c
new file mode 100644
index 0000000..a9a3498
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/iotoken/iotoken.c
@@ -0,0 +1,633 @@
+/* iotoken.c
+ *
+ * IOToken API implementation for the EIP-197 Server with ICE only
+ *
+ */
+
+/*****************************************************************************
+* Copyright (c) 2016-2022 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// Extended IOToken API
+#include "iotoken_ext.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_iotoken.h" // IOTOKEN_STRICT_ARGS
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h" // IDENTIFIER_NOT_USED, bool, uint32_t
+
+// Firmware packet flow codes
+#include "firmware_eip207_api_cmd.h"
+
+// ZEROINIT
+#include "clib.h"
+
+#include "log.h"
+
+// Packet buffer access
+#include "adapter_pec_pktbuf.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+#define IOTOKEN_ARGUMENT_ERROR -1
+#define IOTOKEN_INTERNAL_ERROR -2
+
+#ifdef IOTOKEN_STRICT_ARGS
+#define IOTOKEN_CHECK_POINTER(_p) \
+ if (NULL == (_p)) \
+ return IOTOKEN_ARGUMENT_ERROR;
+#define IOTOKEN_CHECK_INT_INRANGE(_i, _min, _max) \
+ if ((_i) < (_min) || (_i) > (_max)) \
+ return IOTOKEN_ARGUMENT_ERROR;
+#define IOTOKEN_CHECK_INT_ATLEAST(_i, _min) \
+ if ((_i) < (_min)) \
+ return IOTOKEN_ARGUMENT_ERROR;
+#define IOTOKEN_CHECK_INT_ATMOST(_i, _max) \
+ if ((_i) > (_max)) \
+ return IOTOKEN_ARGUMENT_ERROR;
+#else
+/* IOTOKEN_STRICT_ARGS undefined */
+#define IOTOKEN_CHECK_POINTER(_p)
+#define IOTOKEN_CHECK_INT_INRANGE(_i, _min, _max)
+#define IOTOKEN_CHECK_INT_ATLEAST(_i, _min)
+#define IOTOKEN_CHECK_INT_ATMOST(_i, _max)
+#endif /*end of IOTOKEN_STRICT_ARGS */
+
+// Input Token words offsets
+#define IOTOKEN_HDR_IN_WORD_OFFS 0
+#define IOTOKEN_APP_ID_IN_WORD_OFFS 1
+#define IOTOKEN_SA_ADDR_LO_IN_WORD_OFFS 2
+#define IOTOKEN_SA_ADDR_HI_IN_WORD_OFFS 3
+#define IOTOKEN_HW_SERVICES_IN_WORD_OFFS 4
+#define IOTOKEN_NH_OFFSET_IN_WORD_OFFS 5
+#define IOTOKEN_BP_DATA_IN_WORD_OFFS 6
+
+// Output Token words offsets
+#define IOTOKEN_HDR_OUT_WORD_OFFS 0
+#define IOTOKEN_BP_LEN_OUT_WORD_OFFS 1
+#define IOTOKEN_APP_ID_OUT_WORD_OFFS 2
+#define IOTOKEN_PAD_NH_OUT_WORD_OFFS 3
+#define IOTOKEN_SA_ADDR_LO_OUT_WORD_OFFS 4
+#define IOTOKEN_SA_ADDR_HI_OUT_WORD_OFFS 5
+#define IOTOKEN_NPH_CTX_OUT_WORD_OFFS 6
+#define IOTOKEN_PREV_NH_OFFS_OUT_WORD_OFFS 7
+#define IOTOKEN_BP_DATA_OUT_WORD_OFFS 8
+
+#define IOTOKEN_MARK 0xEC00
+
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_InWordCount_Get
+ */
+unsigned int
+IOToken_InWordCount_Get(void)
+{
+ return IOTOKEN_IN_WORD_COUNT - 4 + IOTOKEN_BYPASS_WORD_COUNT;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_OutWordCount_Get
+ */
+unsigned int
+IOToken_OutWordCount_Get(void)
+{
+ return IOTOKEN_OUT_WORD_COUNT - 4 + IOTOKEN_BYPASS_WORD_COUNT;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Create
+ */
+int
+IOToken_Create(
+ const IOToken_Input_Dscr_t * const Dscr_p,
+ uint32_t * Data_p)
+{
+ IOToken_Input_Dscr_Ext_t * DscrExt_p;
+#if IOTOKEN_BYPASS_WORD_COUNT > 0
+ unsigned int bypass_gap = 0;
+#endif
+ unsigned int i;
+
+ IOTOKEN_CHECK_POINTER(Dscr_p);
+ IOTOKEN_CHECK_POINTER(Dscr_p->Ext_p);
+ IOTOKEN_CHECK_POINTER(Data_p);
+
+ DscrExt_p = (IOToken_Input_Dscr_Ext_t *)Dscr_p->Ext_p;
+
+ // Input Token word: EIP-96 Token Header Word
+ {
+ i = IOTOKEN_HDR_IN_WORD_OFFS;
+
+ // Set initialization value in the Token Header Word excluding packet
+ // size field
+ Data_p[i] = Dscr_p->TknHdrWordInit & ~MASK_16_BITS;
+
+ // Input packet size
+ Data_p[i] |= Dscr_p->InPacket_ByteCount & MASK_16_BITS;
+
+ if (DscrExt_p->HW_Services == IOTOKEN_CMD_PKT_LAC)
+ {
+ // Options, ARC4 pre-fetch
+ if (DscrExt_p->fARC4Prefetch)
+ Data_p[i] |= BIT_16;
+
+ Data_p[i] |= BIT_17; // Set token header format to EIP-(1)97
+
+ Data_p[i] |= BIT_18; // Only 64-bit Context (SA) pointer is supported
+
+ // Enable Context Reuse auto detect if no new SA
+ if (Dscr_p->Options.fReuseSA)
+ Data_p[i] |= BIT_21;
+ }
+ // Mask size for inbound ESP
+ if (DscrExt_p->SequenceMaskBitCount != 0)
+ {
+ switch(DscrExt_p->SequenceMaskBitCount)
+ {
+ case 64:
+ Data_p[i] |= 0x00200000;
+ break;
+ case 128:
+ Data_p[i] |= 0x00400000;
+ break;
+ case 256:
+ Data_p[i] |= 0x00600000;
+ break;
+ case 512:
+ Data_p[i] |= 0x00800000;
+ break;
+ }
+ }
+ // Extended options for LIP
+ if (DscrExt_p->fEncLastDest)
+ Data_p[i] |= BIT_25;
+ // Extended options for in-line DTLS packet flow
+ {
+ if (DscrExt_p->Options.fCAPWAP)
+ Data_p[i] |= BIT_26;
+
+ if (DscrExt_p->Options.fInbound)
+ Data_p[i] |= BIT_27;
+
+ Data_p[i] |= DscrExt_p->Options.ContentType << 28;
+ }
+
+ Data_p[i] |= IOTOKEN_FLOW_TYPE << 30; // Implemented flow type
+ }
+
+ // Input Token word: Application ID
+ {
+ i = IOTOKEN_APP_ID_IN_WORD_OFFS;
+ Data_p[i] = (Dscr_p->AppID & MASK_7_BITS) << 9;
+ Data_p[i] |= (DscrExt_p->AAD_ByteCount & MASK_8_BITS);
+ if (DscrExt_p->fInline)
+ Data_p[i] |= (32 + IOTOKEN_BYPASS_WORD_COUNT*4) << 16;
+ }
+
+ // Input Token word: Context (SA) low 32 bits physical address
+ {
+ i = IOTOKEN_SA_ADDR_LO_IN_WORD_OFFS;
+ Data_p[i] = Dscr_p->SA_PhysAddr.Lo;
+ }
+
+ // Input Token word: Context (SA) high 32 bits physical address
+ {
+ i = IOTOKEN_SA_ADDR_HI_IN_WORD_OFFS;
+ //if (DscrExt_p->Options.f64bitSA) // Only 64-bit SA address supported
+ Data_p[i] = Dscr_p->SA_PhysAddr.Hi;
+ }
+
+ // Input Token word: HW services, e,g, packet flow selection
+ {
+ i = IOTOKEN_HW_SERVICES_IN_WORD_OFFS;
+ Data_p[i] = ((DscrExt_p->HW_Services & MASK_8_BITS) << 24) |
+ (DscrExt_p->UserDef & MASK_16_BITS);
+ if (DscrExt_p->fStripPadding != IOTOKEN_PADDING_DEFAULT_ON)
+ Data_p[i] |= BIT_22;
+ if (DscrExt_p->fAllowPadding != IOTOKEN_PADDING_DEFAULT_ON)
+ Data_p[i] |= BIT_23;
+ }
+
+ // Input Token word: Offset and Next Header
+ {
+ i = IOTOKEN_NH_OFFSET_IN_WORD_OFFS;
+ Data_p[i] = (DscrExt_p->Offset_ByteCount & MASK_8_BITS) << 8;
+ Data_p[i] |= (DscrExt_p->NextHeader & MASK_8_BITS) << 16;
+ if (DscrExt_p->fFL)
+ Data_p[i] |= BIT_24;
+ if (DscrExt_p->fIPv4Chksum)
+ Data_p[i] |= BIT_25;
+ if (DscrExt_p->fL4Chksum)
+ Data_p[i] |= BIT_26;
+ if (DscrExt_p->fParseEther)
+ Data_p[i] |= BIT_27;
+ if (DscrExt_p->fKeepOuter)
+ Data_p[i] |= BIT_28;
+
+ }
+
+ if (DscrExt_p->fInline)
+ {
+ Data_p[IOTOKEN_BP_DATA_IN_WORD_OFFS]=0;
+ Data_p[IOTOKEN_BP_DATA_IN_WORD_OFFS+1]=0;
+#if IOTOKEN_BYPASS_WORD_COUNT > 0
+ bypass_gap = 2;
+#endif
+ }
+
+#if IOTOKEN_BYPASS_WORD_COUNT > 0
+ // Input Token word: Bypass Data
+ {
+ unsigned int j;
+
+ if (DscrExt_p->BypassData_p)
+ {
+ for (j = 0; j < IOTOKEN_BYPASS_WORD_COUNT; j++)
+ Data_p[j+IOTOKEN_BP_DATA_IN_WORD_OFFS + bypass_gap] = DscrExt_p->BypassData_p[j];
+ }
+ else
+ {
+ for (j = 0; j < IOTOKEN_BYPASS_WORD_COUNT; j++)
+ Data_p[j+IOTOKEN_BP_DATA_IN_WORD_OFFS + bypass_gap] = 0xf0f0f0f0;
+ }
+ i += bypass_gap + j;
+ }
+#endif
+
+ if (i >= IOTOKEN_IN_WORD_COUNT_IL)
+ return IOTOKEN_INTERNAL_ERROR;
+ else
+ return i+1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Fixup
+ */
+int
+IOToken_Fixup(
+ uint32_t * const Data_p,
+ const DMABuf_Handle_t PacketHandle)
+{
+ uint32_t AppendFlags;
+ if (Data_p == NULL)
+ return 0;
+
+ AppendFlags = Data_p[IOTOKEN_BP_LEN_OUT_WORD_OFFS] & (BIT_31|BIT_30|BIT_29);
+ if (AppendFlags != 0)
+ {
+ uint8_t AppendData[12];
+ uint8_t *Append_p;
+ unsigned int Offset;
+ unsigned int PrevNH_Offset;
+ unsigned int UpdateOffset;
+ unsigned int AppendLen = 0;
+ if ((AppendFlags & BIT_31) != 0)
+ AppendLen+=4;
+ if ((AppendFlags & BIT_30) != 0)
+ AppendLen+=4;
+ if ((AppendFlags & BIT_29) != 0)
+ AppendLen+=4;
+ UpdateOffset = Data_p[IOTOKEN_HDR_OUT_WORD_OFFS] & MASK_17_BITS;
+ UpdateOffset = 4*((UpdateOffset + 3)/4); // Align to word boundary.
+ Offset = Data_p[IOTOKEN_PAD_NH_OUT_WORD_OFFS] >> 16 & MASK_8_BITS;
+ // Get first byte of header
+ Append_p = Adapter_PEC_PktData_Get(PacketHandle, AppendData, UpdateOffset, AppendLen);
+ if (AppendFlags == (BIT_31|BIT_30))
+ { // IPv6 header update, NH plus length
+ PrevNH_Offset = Data_p[IOTOKEN_PREV_NH_OFFS_OUT_WORD_OFFS] & MASK_16_BITS;
+ Adapter_PEC_PktByte_Put(PacketHandle, PrevNH_Offset, Append_p[4]);
+ Adapter_PEC_PktByte_Put(PacketHandle, Offset + 4, Append_p[0]);
+ Adapter_PEC_PktByte_Put(PacketHandle, Offset + 5, Append_p[1]);
+ LOG_INFO("IOToken_Fixup: IPv6 inbound transport\n");
+ }
+ else if (AppendFlags == BIT_29)
+ { // IPv4 checksum only update
+ Adapter_PEC_PktByte_Put(PacketHandle, Offset + 10, Append_p[0]);
+ Adapter_PEC_PktByte_Put(PacketHandle, Offset + 11, Append_p[1]);
+ LOG_INFO("IOToken_Fixup: IPv4 inbound tunnel\n");
+ }
+ else if (AppendFlags == (BIT_31|BIT_30|BIT_29))
+ { // IPv4 header update, proto + length + checksum.
+ Adapter_PEC_PktByte_Put(PacketHandle, Offset + 2, Append_p[0]);
+ Adapter_PEC_PktByte_Put(PacketHandle, Offset + 3, Append_p[1]);
+ Adapter_PEC_PktByte_Put(PacketHandle, Offset + 9, Append_p[5]);
+ Adapter_PEC_PktByte_Put(PacketHandle, Offset + 10, Append_p[8]);
+ Adapter_PEC_PktByte_Put(PacketHandle, Offset + 11, Append_p[9]);
+ LOG_INFO("IOToken_Fixup: IPv4 inbound transport\n");
+ }
+ else
+ {
+ LOG_CRIT("IOToken_Fixup: Unexpected flags combination 0x%08x\n",
+ AppendFlags);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*----------------------------------------------------------------------------
+ * IOToken_SAAddr_Update
+ */
+int
+IOToken_SAAddr_Update(
+ const IOToken_PhysAddr_t * const SA_PhysAddr_p,
+ uint32_t * InTokenData_p)
+{
+ IOTOKEN_CHECK_POINTER(SA_PhysAddr_p);
+ IOTOKEN_CHECK_POINTER(InTokenData_p);
+
+ // Input Token word: Context (SA) low 32 bits physical address
+ InTokenData_p[IOTOKEN_SA_ADDR_LO_IN_WORD_OFFS] = SA_PhysAddr_p->Lo;
+
+ // Input Token word: Context (SA) high 32 bits physical address
+ InTokenData_p[IOTOKEN_SA_ADDR_HI_IN_WORD_OFFS] = SA_PhysAddr_p->Hi;
+
+ return 2; // updated 32-bit token words
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_SAReuse_Update
+ */
+int
+IOToken_SAReuse_Update(
+ const bool fReuseSA,
+ uint32_t * InTokenData_p)
+{
+ IOTOKEN_CHECK_POINTER(InTokenData_p);
+
+ // Enable Context Reuse auto detect if no new SA
+ if (fReuseSA)
+ InTokenData_p[IOTOKEN_HDR_IN_WORD_OFFS] |= BIT_21;
+ else
+ InTokenData_p[IOTOKEN_HDR_IN_WORD_OFFS] &= ~BIT_21;
+
+ return 1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Mark_Set
+ */
+int
+IOToken_Mark_Set(
+ uint32_t * InTokenData_p)
+{
+ IOTOKEN_CHECK_POINTER(InTokenData_p);
+
+ InTokenData_p[IOTOKEN_APP_ID_IN_WORD_OFFS] &= ~(MASK_7_BITS << 9);
+ InTokenData_p[IOTOKEN_APP_ID_IN_WORD_OFFS] |= IOTOKEN_MARK;
+
+ return 1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Mark_Offset_Get
+ */
+int
+IOToken_OutMarkOffset_Get(void)
+{
+ return IOTOKEN_APP_ID_OUT_WORD_OFFS;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Mark_Check
+ */
+int
+IOToken_Mark_Check(
+ uint32_t * OutTokenData_p)
+{
+ uint32_t Mark;
+
+ IOTOKEN_CHECK_POINTER(OutTokenData_p);
+
+ Mark = OutTokenData_p[IOTOKEN_APP_ID_OUT_WORD_OFFS] & IOTOKEN_MARK;
+
+ if (Mark == IOTOKEN_MARK)
+ return 0;
+ else
+ return 1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_Parse
+ */
+int
+IOToken_Parse(
+ const uint32_t * Data_p,
+ IOToken_Output_Dscr_t * const Dscr_p)
+{
+ unsigned int i, j = 0;
+ IOToken_Output_Dscr_Ext_t * Ext_p;
+
+ IOTOKEN_CHECK_POINTER(Data_p);
+ IOTOKEN_CHECK_POINTER(Dscr_p);
+
+ Ext_p = (IOToken_Output_Dscr_Ext_t *)Dscr_p->Ext_p;
+
+ // Output Token word: EIP-96 Output Token Header Word
+ {
+ i = IOTOKEN_HDR_OUT_WORD_OFFS;
+ Dscr_p->OutPacket_ByteCount = Data_p[i] & MASK_17_BITS;
+ Dscr_p->ErrorCode = Data_p[i] >> 17 & MASK_15_BITS;
+ }
+
+ // Output Token word: EIP-96 Output Token Bypass Data Length Word
+ {
+ i = IOTOKEN_BP_LEN_OUT_WORD_OFFS;
+ Dscr_p->BypassData_ByteCount = Data_p[i] & MASK_4_BITS;
+ Dscr_p->fHashAppended = (Data_p[i] & BIT_21) != 0;
+
+ Dscr_p->Hash_ByteCount = Data_p[i] >> 22 & MASK_6_BITS;
+
+ Dscr_p->fBytesAppended = (Data_p[i] & BIT_28) != 0;
+ Dscr_p->fChecksumAppended = (Data_p[i] & BIT_29) != 0;
+ Dscr_p->fNextHeaderAppended = (Data_p[i] & BIT_30) != 0;
+ Dscr_p->fLengthAppended = (Data_p[i] & BIT_31) != 0;
+ }
+
+ // Output Token word: EIP-96 Output Token Application ID Word
+ {
+ i = IOTOKEN_APP_ID_OUT_WORD_OFFS;
+ Dscr_p->AppID = Data_p[i] >> 9 & MASK_7_BITS;
+ }
+
+ // Output Token word: Pad Length and Next Header
+ {
+ i = IOTOKEN_PAD_NH_OUT_WORD_OFFS;
+ Dscr_p->NextHeader = Data_p[i] & MASK_8_BITS;
+ Dscr_p->Pad_ByteCount = Data_p[i] >> 8 & MASK_8_BITS;
+ }
+
+ // Parse Output Token descriptor extension if requested
+ if (Ext_p)
+ {
+ // Output Token word: ToS/TC, DF, Firmware errors
+ {
+ j = IOTOKEN_BP_LEN_OUT_WORD_OFFS;
+ Ext_p->TOS_TC = Data_p[j] >> 5 & MASK_8_BITS;
+
+ Ext_p->fDF = (Data_p[j] & BIT_13) != 0;
+
+ Ext_p->CfyErrors = Data_p[j] >> 16 & MASK_5_BITS;
+ }
+
+#ifdef IOTOKEN_EXTENDED_ERRORS_ENABLE
+ if ((Data_p[IOTOKEN_HDR_OUT_WORD_OFFS] & BIT_31) != 0)
+ {
+ Ext_p->ExtErrors = (Data_p[IOTOKEN_HDR_OUT_WORD_OFFS] >> 17) & MASK_8_BITS;
+ }
+ else
+#endif
+ {
+ Ext_p->ExtErrors = 0;
+ }
+
+ // Output Token word: IP Length Delta and Offset
+ {
+ j = IOTOKEN_PAD_NH_OUT_WORD_OFFS;
+ Ext_p->Offset_ByteCount = Data_p[j] >> 16 & MASK_8_BITS;
+ Ext_p->IPDelta_ByteCount = Data_p[j] >> 24 & MASK_8_BITS;
+ }
+
+ // Output Token word: SA physical address low/high words
+ {
+ j = IOTOKEN_SA_ADDR_LO_OUT_WORD_OFFS;
+ Ext_p->SA_PhysAddr.Lo = Data_p[j];
+
+ j = IOTOKEN_SA_ADDR_HI_OUT_WORD_OFFS;
+ Ext_p->SA_PhysAddr.Hi = Data_p[j];
+ }
+
+ // Output Token word: Application header processing context
+ {
+ j = IOTOKEN_NPH_CTX_OUT_WORD_OFFS;
+ Ext_p->NPH_Context = Data_p[j];
+ }
+
+ // Output Token word: Previous Next Header Offset
+ {
+ j = IOTOKEN_PREV_NH_OFFS_OUT_WORD_OFFS;
+ Ext_p->NextHeaderOffset = Data_p[j] & MASK_16_BITS;
+ Ext_p->fInIPv6 = ((Data_p[j] & BIT_16) != 0);
+ Ext_p->fFromEther = ((Data_p[j] & BIT_17) != 0);
+ Ext_p->fOutIPv6 = ((Data_p[j] & BIT_22) != 0);
+ Ext_p->fInbTunnel = ((Data_p[j] & BIT_23) != 0);
+ }
+
+#if IOTOKEN_BYPASS_WORD_COUNT > 0
+ // Output Token word: Bypass Data
+ {
+ unsigned int k = 0;
+ if (Ext_p->BypassData_p)
+ {
+ for (k = 0; k < IOTOKEN_BYPASS_WORD_COUNT; k++)
+ Ext_p->BypassData_p[k] =
+ Data_p[k+IOTOKEN_BP_DATA_OUT_WORD_OFFS];
+ }
+ j += k;
+ }
+#endif
+ }
+
+ // Output Token word: Reserved word not used
+ // i = IOTOKEN_RSVD_OUT_WORD_OFFS;
+
+ return MAX(i, j);
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_PacketLegth_Get
+ */
+int
+IOToken_PacketLegth_Get(
+ const uint32_t * Data_p,
+ unsigned int * Pkt_ByteCount_p)
+{
+ IOTOKEN_CHECK_POINTER(Data_p);
+ IOTOKEN_CHECK_POINTER(Pkt_ByteCount_p);
+
+ *Pkt_ByteCount_p = Data_p[IOTOKEN_HDR_OUT_WORD_OFFS] & MASK_17_BITS;
+
+ return 1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_BypassLegth_Get
+ */
+int
+IOToken_BypassLegth_Get(
+ const uint32_t * Data_p,
+ unsigned int * BD_ByteCount_p)
+{
+ IOTOKEN_CHECK_POINTER(Data_p);
+ IOTOKEN_CHECK_POINTER(BD_ByteCount_p);
+
+ *BD_ByteCount_p = Data_p[IOTOKEN_BP_LEN_OUT_WORD_OFFS] & MASK_4_BITS;
+
+ return 1;
+}
+
+
+/*----------------------------------------------------------------------------
+ * IOToken_ErrorCode_Get
+ */
+int
+IOToken_ErrorCode_Get(
+ const uint32_t * Data_p,
+ unsigned int * ErrorCode_p)
+{
+ IOTOKEN_CHECK_POINTER(Data_p);
+ IOTOKEN_CHECK_POINTER(ErrorCode_p);
+
+ *ErrorCode_p = (Data_p[IOTOKEN_HDR_OUT_WORD_OFFS] >> 17) & MASK_15_BITS;
+#ifdef IOTOKEN_EXTENDED_ERRORS_ENABLE
+ if ((Data_p[IOTOKEN_HDR_OUT_WORD_OFFS] & BIT_31) != 0)
+ {
+ *ErrorCode_p &= ~0x40ff; // Remove the detailed error code and related bits.
+ }
+#endif
+
+ return 1;
+}
+
+
+/* end of file iotoken.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/list/list.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/list/list.c
new file mode 100644
index 0000000..86b0727
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/list/list.c
@@ -0,0 +1,459 @@
+/* list.c
+ *
+ * This Module implements the List API
+ */
+
+/*****************************************************************************
+* Copyright (c) 2012-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+/*----------------------------------------------------------------------------
+ * This module implements (provides) the following interface(s):
+ */
+
+// List API
+#include "list.h"
+
+
+/*----------------------------------------------------------------------------
+ * This module uses (requires) the following interface(s):
+ */
+
+// Default configuration
+#include "c_list.h"
+
+// Driver Framework Basic Definitions API
+#include "basic_defs.h"
+
+
+/*----------------------------------------------------------------------------
+ * Definitions and macros
+ */
+
+typedef struct
+{
+ // List head
+ List_Element_t * Head_p;
+
+ // List tail
+ List_Element_t * Tail_p;
+
+ // Number of elements in the list
+ unsigned int ElementCount;
+
+} List_t;
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ */
+
+// Statically allocated list instances. This will be deprecated in future.
+static List_t List [LIST_MAX_NOF_INSTANCES];
+
+
+/*----------------------------------------------------------------------------
+ * List_Init
+ *
+ */
+List_Status_t
+List_Init(
+ const unsigned int ListID,
+ void * const ListInstance_p)
+{
+#ifdef LIST_STRICT_ARGS
+ if (ListID >= LIST_MAX_NOF_INSTANCES)
+ return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+ // Initialize the list instance
+ {
+ List_t * List_p;
+
+ if (ListInstance_p)
+ List_p = (List_t*)ListInstance_p;
+ else
+ List_p = &List[ListID];
+
+ List_p->ElementCount = 0;
+ List_p->Head_p = NULL;
+ List_p->Tail_p = NULL;
+ }
+
+ return LIST_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * List_Uninit
+ *
+ */
+List_Status_t
+List_Uninit(
+ const unsigned int ListID,
+ void * const ListInstance_p)
+{
+#ifdef LIST_STRICT_ARGS
+ if (ListID >= LIST_MAX_NOF_INSTANCES)
+ return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+ // Un-initialize the list instance
+ {
+ List_t * List_p;
+
+ if (ListInstance_p)
+ List_p = (List_t*)ListInstance_p;
+ else
+ List_p = &List[ListID];
+
+ List_p->ElementCount = 0;
+ List_p->Head_p = NULL;
+ List_p->Tail_p = NULL;
+ }
+
+ return LIST_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * List_AddToHead
+ *
+ */
+List_Status_t
+List_AddToHead(
+ const unsigned int ListID,
+ void * const ListInstance_p,
+ List_Element_t * const Element_p)
+{
+#ifdef LIST_STRICT_ARGS
+ if (ListID >= LIST_MAX_NOF_INSTANCES)
+ return LIST_ERROR_BAD_ARGUMENT;
+
+ if (Element_p == NULL)
+ return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+ // Add the element at the list head
+ {
+ List_Element_t * TempElement_p;
+ List_t * List_p;
+
+ if (ListInstance_p)
+ List_p = (List_t*)ListInstance_p;
+ else
+ List_p = &List[ListID];
+
+ TempElement_p = List_p->Head_p;
+ List_p->Head_p = Element_p;
+
+ // Previous element in the list, this is a head
+ Element_p->Internal[0] = NULL;
+
+ // Next element in the list
+ Element_p->Internal[1] = TempElement_p;
+
+ // Check if this is the first element
+ if (List_p->ElementCount == 0)
+ List_p->Tail_p = List_p->Head_p;
+ else
+ // Link the old head to the new head
+ TempElement_p->Internal[0] = Element_p;
+
+ List_p->ElementCount++;
+ }
+
+ return LIST_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * List_RemoveFromTail
+ *
+ */
+List_Status_t
+List_RemoveFromTail(
+ const unsigned int ListID,
+ void * const ListInstance_p,
+ List_Element_t ** const Element_pp)
+{
+#ifdef LIST_STRICT_ARGS
+ if (ListID >= LIST_MAX_NOF_INSTANCES)
+ return LIST_ERROR_BAD_ARGUMENT;
+
+ if (Element_pp == NULL)
+ return LIST_ERROR_BAD_ARGUMENT;
+
+#endif // LIST_STRICT_ARGS
+
+ // Remove the element from the list tail
+ {
+ List_Element_t * TempElement_p;
+ List_t * List_p;
+
+ if (ListInstance_p)
+ List_p = (List_t*)ListInstance_p;
+ else
+ List_p = &List[ListID];
+
+#ifdef LIST_STRICT_ARGS
+ if (List_p->ElementCount == 0)
+ return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+ // Get the previous for the tail element in the list
+ TempElement_p = (List_Element_t*)List_p->Tail_p->Internal[0];
+
+ List_p->Tail_p->Internal[0] = NULL;
+ List_p->Tail_p->Internal[1] = NULL;
+ *Element_pp = List_p->Tail_p;
+
+ // Set the new tail
+ List_p->Tail_p = TempElement_p;
+
+ // Check if this is the last element
+ if (List_p->ElementCount == 1)
+ List_p->Head_p = NULL;
+ else
+ // New tail must have no next element
+ List_p->Tail_p->Internal[1] = NULL;
+
+ List_p->ElementCount--;
+ }
+
+ return LIST_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * List_RemoveAnywhere
+ */
+List_Status_t
+List_RemoveAnywhere(
+ const unsigned int ListID,
+ void * const ListInstance_p,
+ List_Element_t * const Element_p)
+{
+#ifdef LIST_STRICT_ARGS
+ if (ListID >= LIST_MAX_NOF_INSTANCES)
+ return LIST_ERROR_BAD_ARGUMENT;
+
+ if (Element_p == NULL)
+ return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+ // Remove the element from the list tail
+ {
+ List_Element_t * PrevElement_p, * NextElement_p;
+ List_t * List_p;
+
+ if (ListInstance_p)
+ List_p = (List_t*)ListInstance_p;
+ else
+ List_p = &List[ListID];
+
+#ifdef LIST_STRICT_ARGS
+ if (List_p->ElementCount == 0)
+ return LIST_ERROR_BAD_ARGUMENT;
+
+ // Check element belongs to this list
+ {
+ unsigned int i;
+ List_Element_t * TempElement_p = List_p->Head_p;
+
+ for (i = 0; i < List_p->ElementCount; i++)
+ {
+ List_Element_t * p;
+
+ if (TempElement_p == Element_p)
+ break; // Found
+
+ p = TempElement_p->Internal[1];
+ if (p)
+ TempElement_p = p; // not end of list yet
+ else
+ return LIST_ERROR_BAD_ARGUMENT; // Not found
+ }
+
+ if (TempElement_p != Element_p)
+ return LIST_ERROR_BAD_ARGUMENT; // Not found
+ }
+#endif // LIST_STRICT_ARGS
+
+ PrevElement_p = Element_p->Internal[0];
+ NextElement_p = Element_p->Internal[1];
+
+ Element_p->Internal[0] = NULL;
+ Element_p->Internal[1] = NULL;
+
+ if (PrevElement_p)
+ PrevElement_p->Internal[1] = NextElement_p;
+ else
+ List_p->Head_p = NextElement_p;
+
+ if (NextElement_p)
+ NextElement_p->Internal[0] = PrevElement_p;
+ else
+ List_p->Tail_p = PrevElement_p;
+
+ List_p->ElementCount--;
+ }
+
+ return LIST_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * List_GetListElementCount
+ *
+ */
+List_Status_t
+List_GetListElementCount(
+ const unsigned int ListID,
+ void * const ListInstance_p,
+ unsigned int * const Count_p)
+{
+#ifdef LIST_STRICT_ARGS
+ if (ListID >= LIST_MAX_NOF_INSTANCES)
+ return LIST_ERROR_BAD_ARGUMENT;
+
+ if (Count_p == NULL)
+ return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+ {
+ List_t * List_p;
+
+ if (ListInstance_p)
+ List_p = (List_t*)ListInstance_p;
+ else
+ List_p = &List[ListID];
+
+ *Count_p = List_p->ElementCount;
+ }
+
+ return LIST_STATUS_OK;
+}
+
+
+#ifdef LIST_FULL_API
+/*----------------------------------------------------------------------------
+ * List_RemoveFromHead
+ *
+ */
+List_Status_t
+List_RemoveFromHead(
+ const unsigned int ListID,
+ void * const ListInstance_p,
+ List_Element_t ** const Element_pp)
+{
+ List_t * List_p;
+
+ if (ListInstance_p)
+ List_p = (List_t*)ListInstance_p;
+ else
+ List_p = &List[ListID];
+
+#ifdef LIST_STRICT_ARGS
+ if (ListID >= LIST_MAX_NOF_INSTANCES)
+ return LIST_ERROR_BAD_ARGUMENT;
+
+ if (Element_pp == NULL)
+ return LIST_ERROR_BAD_ARGUMENT;
+
+ if (List_p->ElementCount == 0)
+ return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+ // Remove the element from the list head
+ {
+ List_Element_t * TempElement_p;
+
+ // Get the next for the head element in the list
+ TempElement_p = (List_Element_t*)List_p->Head_p->Internal[1];
+
+ List_p->Head_p->Internal[0] = NULL;
+ List_p->Head_p->Internal[1] = NULL;
+ *Element_pp = List_p->Head_p;
+
+ List_p->Head_p = TempElement_p;
+
+ // Check if this is the last element
+ if (List_p->ElementCount == 1)
+ List_p->Tail_p = NULL;
+ else
+ List_p->Head_p->Internal[0] = NULL;
+
+ List_p->ElementCount--;
+ }
+
+ return LIST_STATUS_OK;
+}
+
+
+/*----------------------------------------------------------------------------
+ * List_GetHead
+ */
+List_Status_t
+List_GetHead(
+ const unsigned int ListID,
+ void * const ListInstance_p,
+ const List_Element_t ** const Element_pp)
+{
+#ifdef LIST_STRICT_ARGS
+ if (ListID >= LIST_MAX_NOF_INSTANCES)
+ return LIST_ERROR_BAD_ARGUMENT;
+
+ if (Element_pp == NULL)
+ return LIST_ERROR_BAD_ARGUMENT;
+#endif // LIST_STRICT_ARGS
+
+ // Get the list head
+ {
+ List_t * List_p;
+
+ if (ListInstance_p)
+ List_p = (List_t*)ListInstance_p;
+ else
+ List_p = &List[ListID];
+
+ *Element_pp = List_p->Head_p;
+ }
+
+ return LIST_STATUS_OK;
+}
+#endif // LIST_FULL_API
+
+
+/*----------------------------------------------------------------------------
+ * List_GetInstanceByteCount
+ *
+ * Gets the memory size of the list instance (in bytes) excluding the list
+ * elements memory size. This list memory size can be used to allocate a list
+ * instance and pass a pointer to it subsequently to the List_*() functions.
+ *
+ * This function is re-entrant and can be called any time.
+ *
+ * Return Values
+ * Size of the list administration memory in bytes.
+ */
+unsigned int
+List_GetInstanceByteCount(void)
+{
+ return sizeof(List_t);
+}
+
+
+/* end of file list.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/log/log.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/log/log.c
new file mode 100644
index 0000000..84473f9
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/log/log.c
@@ -0,0 +1,128 @@
+/* log.c
+ *
+ * Log implementation for specific environment
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#define LOG_SEVERITY_MAX LOG_SEVERITY_NO_OUTPUT
+
+// Logging API
+#include "log.h" // the API to implement
+
+
+/*----------------------------------------------------------------------------
+ * Log_HexDump
+ *
+ * This function logs Hex Dump of a Buffer
+ *
+ * szPrefix
+ * Prefix to be printed on every row.
+ *
+ * PrintOffset
+ * Offset value that is printed at the start of every row. Can be used
+ * when the byte printed are located at some offset in another buffer.
+ *
+ * Buffer_p
+ * Pointer to the start of the array of bytes to hex dump.
+ *
+ * ByteCount
+ * Number of bytes to include in the hex dump from Buffer_p.
+ *
+ * Return Value
+ * None.
+ */
+void
+Log_HexDump(
+ const char * szPrefix_p,
+ const unsigned int PrintOffset,
+ const uint8_t * Buffer_p,
+ const unsigned int ByteCount)
+{
+ unsigned int i;
+
+ for(i = 0; i < ByteCount; i += 16)
+ {
+ unsigned int j, Limit;
+
+ // if we do not have enough data for a full line
+ if (i + 16 > ByteCount)
+ Limit = ByteCount - i;
+ else
+ Limit = 16;
+
+ Log_FormattedMessage("%s %08d:", szPrefix_p, PrintOffset + i);
+
+ for (j = 0; j < Limit; j++)
+ Log_FormattedMessage(" %02X", Buffer_p[i+j]);
+
+ Log_FormattedMessage("\n");
+ } // for
+}
+
+
+/*----------------------------------------------------------------------------
+ * Log_HexDump32
+ *
+ * This function logs Hex Dump of an array of 32-bit words
+ *
+ * szPrefix
+ * Prefix to be printed on every row.
+ *
+ * PrintOffset
+ * Offset value that is printed at the start of every row. Can be used
+ * when the byte printed are located at some offset in another buffer.
+ *
+ * Buffer_p
+ * Pointer to the start of the array of 32-bit words to hex dump.
+ *
+ * Word32Count
+ * Number of 32-bit words to include in the hex dump from Buffer_p.
+ *
+ * Return Value
+ * None.
+ */
+void
+Log_HexDump32(
+ const char * szPrefix_p,
+ const unsigned int PrintOffset,
+ const uint32_t * Buffer_p,
+ const unsigned int Word32Count)
+{
+ unsigned int i;
+
+ for(i = 0; i < Word32Count; i += 4)
+ {
+ unsigned int j, Limit;
+
+ // if we do not have enough data for a full line
+ if (i + 4 > Word32Count)
+ Limit = Word32Count - i;
+ else
+ Limit = 4;
+
+ Log_FormattedMessage("%s %08d:", szPrefix_p, PrintOffset + i*4);
+
+ for (j = 0; j < Limit; j++)
+ Log_FormattedMessage(" %08X", Buffer_p[i+j]);
+
+ Log_FormattedMessage("\n");
+ } // for
+}
+
+/* end of file log.c */
diff --git a/package-21.02/kernel/crypto-eip/src/ddk/kit/ring/ringhelper.c b/package-21.02/kernel/crypto-eip/src/ddk/kit/ring/ringhelper.c
new file mode 100644
index 0000000..fd04cd3
--- /dev/null
+++ b/package-21.02/kernel/crypto-eip/src/ddk/kit/ring/ringhelper.c
@@ -0,0 +1,484 @@
+/* ringhelper.c
+ *
+ * Ring Helper Library implementation.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2008-2020 by Rambus, Inc. and/or its subsidiaries.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 2 of the License, or
+* any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*****************************************************************************/
+
+#include "c_ringhelper.h" // configuration options
+
+#include "basic_defs.h" // bool, MIN
+#include "ringhelper.h" // API to implement
+#include "clib.h" // memset
+
+
+/*----------------------------------------------------------------------------
+ * RingHelper_Init
+ *
+ * This routine must be called once to initialize the administration block
+ * related to a ring.
+ *
+ * See header file for function specification.
+ */
+int
+RingHelper_Init(
+ volatile RingHelper_t * const Ring_p,
+ volatile const RingHelper_CallbackInterface_t * const CallbackIF_p,
+ const bool fSeparateRings,
+ const unsigned int CommandRing_MaxDescriptors,
+ const unsigned int ResultRing_MaxDescriptors)
+{
+#ifdef RINGHELPER_STRICT_ARGS
+ if (Ring_p == NULL ||
+ CallbackIF_p == NULL ||
+ CommandRing_MaxDescriptors < 1)
+ {
+ // invalid argument
+ return -1;
+ }
+
+ if (fSeparateRings)
+ {
+#ifdef RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT
+ // not supported
+ return -1;
+#else
+ if (ResultRing_MaxDescriptors < 1)
+ {
+ // invalid arguments
+ return -1;
+ }
+#endif
+ }
+
+ if (CallbackIF_p->ReadFunc_p == NULL ||
+ CallbackIF_p->WriteFunc_p == NULL)
+ {
+ return -1;
+ }
+
+#ifndef RINGHELPER_REMOVE_STATUSFUNC
+ if (CallbackIF_p->StatusFunc_p == NULL)
+ {
+ return -1;
+ }
+#endif
+
+#endif /* RINGHELPER_STRICT_ARGS */
+
+ Ring_p->CB = *CallbackIF_p;
+ Ring_p->fSupportsDeviceReadPos = true; // initial assumption
+ Ring_p->IN_Size = CommandRing_MaxDescriptors;
+ Ring_p->IN_Tail = 0;
+ Ring_p->OUT_Head = 0;
+
+#ifndef RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT
+ if (fSeparateRings)
+ {
+ // separate rings
+ Ring_p->fSeparate = true;
+ Ring_p->OUT_Size = ResultRing_MaxDescriptors;
+ }
+ else
+#endif /* !RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT */
+ {
+ // combined rings
+ Ring_p->fSeparate = false;
+ Ring_p->OUT_Size = CommandRing_MaxDescriptors;
+ }
+
+ return 0; // success
+}
+
+
+/*----------------------------------------------------------------------------
+ * RingHelper_Put
+ *
+ * This function tries to add a number of descriptors to the command ring
+ * specified.
+ *
+ * See header file for function specification.
+ */
+int
+RingHelper_Put(
+ volatile RingHelper_t * const Ring_p,
+ const void * Descriptors_p,
+ const int DescriptorCount)
+{
+ int A, N, W1, W2;
+
+#ifdef RINGHELPER_STRICT_ARGS
+ if (Ring_p == NULL ||
+ Descriptors_p == NULL ||
+ DescriptorCount < 0)
+ {
+ return -1;
+ }
+#endif /* RINGHELPER_STRICT_ARGS */
+
+ if (DescriptorCount == 0)
+ return 0;
+
+ W2 = 0;
+
+#ifndef RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT
+ // out of the descriptors provided, calculate the maximum number of
+ // descriptors that can be written sequentially before the ring is full.
+ if (Ring_p->fSeparate)
+ {
+ // separate rings
+
+ // ask how far the device has processed the ring
+ // we do this on every call and do not cache the result
+ int DeviceReadHead = -1; // not supported
+
+#ifndef RINGHELPER_REMOVE_STATUSFUNC
+ if (Ring_p->fSupportsDeviceReadPos)
+ {
+ int res;
+
+ res = Ring_p->CB.StatusFunc_p(
+ Ring_p->CB.CallbackParam1_p,
+ Ring_p->CB.CallbackParam2,
+ &DeviceReadHead);
+
+ if (res < 0)
+ return res; // ## RETURN ##
+
+ // suppress these calls if the device does not support it
+ if (DeviceReadHead < 0)
+ Ring_p->fSupportsDeviceReadPos = false;
+ }
+#endif /* !RINGHELPER_REMOVE_STATUSFUNC */
+
+ if (DeviceReadHead < 0)
+ {
+ // device does not expose its read position
+ // this means we cannot calculate how much space is available
+ // the WriteFunc will have to check, descriptor by descriptor
+ A = Ring_p->IN_Size;
+
+ // note: under this condition we rely on the implementation of
+ // the callback interface to handle ring-full condition and not
+ // overwrite existing descriptors. Because of this, we can
+ // fill the ring to the limit and do not have to keep 1 free
+ // position as done below.
+ }
+ else
+ {
+ unsigned int Device_IN_Head = (unsigned int)DeviceReadHead;
+
+ // based on the device read position we can calculate
+ // how many positions in the ring are free
+ if (Ring_p->IN_Tail < Device_IN_Head)
+ {
+ // we have wrapped around
+ // available space is between the two
+ A = Device_IN_Head - Ring_p->IN_Tail;
+ }
+ else
+ {
+ // used positions are between the two pointers
+ // rest is free
+ A = Ring_p->IN_Size - (Ring_p->IN_Tail - Device_IN_Head);
+ }
+
+ // avoid filling the entire ring
+ // so we can differentiate full from empty
+ if (A != 0)
+ A--;
+ }
+ }
+ else
+#endif /* !RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT */
+ {
+ // combined rings
+
+ // Critical: we have to be careful not to read the OUT_Head more
+ // than one, since it might change in between!
+ unsigned int OUT_Head_copy = Ring_p->OUT_Head;
+
+ // we can write descriptors up to the point where we expect the
+ // result descriptors
+ if (Ring_p->IN_Tail < OUT_Head_copy)
+ {
+ // used positions are around the wrap point
+ // free positions are between the pointers
+ A = OUT_Head_copy - Ring_p->IN_Tail;
+ }
+ else
+ {
+ // used positions are between the two pointers
+ // rest is free
+ A = Ring_p->IN_Size - (Ring_p->IN_Tail - OUT_Head_copy);
+ }
+
+ // avoid filling the entire ring
+ // so we can differentiate full from empty
+ // (when it contains all commands or all results)
+ if (A != 0)
+ A--;
+ }
+
+ // limit based on provided descriptors
+ A = MIN(A, DescriptorCount);
+
+ // limit for sequential writing
+ N = MIN(A, (int)(Ring_p->IN_Size - Ring_p->IN_Tail));
+
+ // bail out early if there is no space
+ if (N == 0)
+ {
+ return 0; // ## RETURN ##
+ }
+
+ W1 = Ring_p->CB.WriteFunc_p(
+ Ring_p->CB.CallbackParam1_p,
+ Ring_p->CB.CallbackParam2,
+ /*WriteIndex:*/Ring_p->IN_Tail,
+ /*WriteCount:*/N,
+ /*AvailableSpace*/A,
+ Descriptors_p,
+ DescriptorCount,
+ /*SkipCount:*/0);
+
+ if (W1 <= 0)
+ {
+ // 0: no descriptors could be added
+ // <0: failure
+ return W1; // ## RETURN ##
+ }
+
+ if (W1 == N &&
+ W1 < DescriptorCount &&
+ A > N)
+ {
+ // we have written all possible positions up to the end of the ring
+ // now write the rest
+ N = A - N;
+
+ W2 = Ring_p->CB.WriteFunc_p(
+ Ring_p->CB.CallbackParam1_p,
+ Ring_p->CB.CallbackParam2,
+ /*WriteIndex:*/0,
+ /*WriteCount:*/N,
+ /*AvailableSpace*/N,
+ Descriptors_p,
+ DescriptorCount,
+ /*SkipCount:*/W1);
+
+ if (W2 < 0)
+ {
+ // failure
+ return W2; // ## RETURN ##
+ }
+ }
+
+ // now update the position for the next write
+ {
+ unsigned int i = Ring_p->IN_Tail + W1 + W2;
+
+ // do not use % operator to avoid costly divisions
+ if (i >= Ring_p->IN_Size)
+ i -= Ring_p->IN_Size;
+
+ Ring_p->IN_Tail = i;
+ }
+
+ // return how many descriptors were added
+ return W1 + W2;
+}
+
+
+/*----------------------------------------------------------------------------
+ * RingHelper_Get
+ *
+ * This routine retrieves a number of descriptors from the result ring
+ * specified.
+ *
+ * See header file for function specification.
+ */
+int
+RingHelper_Get(
+ volatile RingHelper_t * const Ring_p,
+ const int ReadyCount,
+ void * Descriptors_p,
+ const int DescriptorsLimit)
+{
+ int A, N;
+ int R1, R2;
+
+ R2 = 0;
+
+#ifdef RINGHELPER_STRICT_ARGS
+ if (Ring_p == NULL ||
+ Descriptors_p == NULL ||
+ DescriptorsLimit < 0)
+ {
+ return -1;
+ }
+#endif /* RINGHELPER_STRICT_ARGS */
+
+ if (DescriptorsLimit == 0 ||
+ ReadyCount == 0)
+ {
+ // no space in output buffer
+ // or no descriptors ready
+ return 0;
+ }
+
+ // calculate the maximum number of descriptors that can be retrieved
+ // sequentially from this read position, taking into account the
+ // DescriptorsLimit and the ReadyCount (if available)
+
+ // A = entries in result ring from read position till end
+ A = Ring_p->OUT_Size - Ring_p->OUT_Head;
+
+ N = MIN(A, DescriptorsLimit);
+
+ if (ReadyCount > 0)
+ N = MIN(N, ReadyCount);
+
+ // now retrieve this number of descriptors
+ R1 = Ring_p->CB.ReadFunc_p(
+ Ring_p->CB.CallbackParam1_p,
+ Ring_p->CB.CallbackParam2,
+ /*ReadIndex:*/Ring_p->OUT_Head,
+ /*ReadLimit:*/N,
+ Descriptors_p,
+ /*SkipCount:*/0);
+
+ if (R1 <= 0)
+ {
+ // 0: if we got nothing on the first call, we can stop here
+ // <0: error while reading
+ // this means we cannot maintain read synchronization
+
+ return R1; // ## RETURN ##
+ }
+
+ // if we got the maximum, we can try to read more
+ // after wrapping to the start of the buffer
+ if (R1 == N &&
+ R1 < DescriptorsLimit &&
+ R1 != ReadyCount)
+ {
+ // A = number of entries in ring up to previous read-start position
+ A = Ring_p->OUT_Head;
+
+ N = MIN(A, DescriptorsLimit - R1);
+
+ if (ReadyCount > 0)
+ N = MIN(N, ReadyCount - R1);
+
+ R2 = Ring_p->CB.ReadFunc_p(
+ Ring_p->CB.CallbackParam1_p,
+ Ring_p->CB.CallbackParam2,
+ /*ReadIndex:*/0, // start of buffer
+ /*ReadLimit:*/N,
+ Descriptors_p,
+ /*SkipCount:*/R1);
+
+ if (R2 < 0)
+ {
+ // failure
+ return R2; // ## RETURN ##
+ }
+ }
+
+ // now update the position for the next read
+ {
+ unsigned int i = Ring_p->OUT_Head + R1 + R2;
+
+ // do not use % operator to avoid costly divisions
+ if (i >= Ring_p->OUT_Size)
+ i -= Ring_p->OUT_Size;
+
+ Ring_p->OUT_Head = i;
+ }
+
+ // return the number of descriptors read
+ return R1 + R2;
+}
+
+
+/*----------------------------------------------------------------------------
+ * RingHelper_FillLevel_Get
+ *
+ * This function return a number of filled (used) descriptors in the ring
+ * specified.
+ *
+ * See header file for function specification.
+ */
+int
+RingHelper_FillLevel_Get(
+ volatile RingHelper_t * const Ring_p)
+{
+#ifdef RINGHELPER_STRICT_ARGS
+ if (Ring_p == NULL)
+ {
+ return -1;
+ }
+#endif /* RINGHELPER_STRICT_ARGS */
+
+#ifndef RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT
+ // out of the descriptors provided, calculate the maximum number of
+ // descriptors that can be written sequentially before the ring is full.
+ if (Ring_p->fSeparate)
+ {
+ // separate rings
+
+ return -1; // not implemented
+ }
+ else
+#endif /* !RINGHELPER_REMOVE_SEPARATE_RING_SUPPORT */
+ {
+ // combined rings
+
+ unsigned int FillLevel;
+ unsigned int OUT_Head_copy;
+
+ // Critical: we have to be careful not to read the OUT_Head more
+ // than one, since it might change in between!
+ OUT_Head_copy = Ring_p->OUT_Head;
+
+ if (Ring_p->IN_Tail < OUT_Head_copy)
+ {
+ // used positions are around the wrap point
+ // free positions are between the pointers
+ FillLevel = Ring_p->IN_Size - (OUT_Head_copy - Ring_p->IN_Tail);
+ }
+ else
+ {
+ // used positions are between the two pointers
+ // rest is free
+ FillLevel = Ring_p->IN_Tail - OUT_Head_copy;
+ }
+
+ // avoid filling the entire ring
+ // so we can differentiate full from empty
+ // (when it contains all commands or all results)
+ if (FillLevel < Ring_p->IN_Size)
+ FillLevel++;
+
+ return (int)FillLevel;
+ }
+}
+
+
+/* end of file ringhelper.c */