[][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 */